Google Apps 脚本 - 尝试在 Gmail 上按名称查找 Google Sheet
Google Apps Script - Trying to find a Google Sheet by name on Gmail
我正在尝试创建一个 sheet,它将像数据库一样工作,用于存储来自 Gmail 的某些数据(我的边栏仅适用于 Gmail)。
但是,在为此创建新的 google sheet 之前,我必须查看 sheet 是否已经存在。如果是,我想将数据保存到现有的 sheet.
我该怎么做?
GetContextualAddOn.gs
var MESSAGE;
//Returns the sidebar with his cards
function getContextualAddOn(event) {
MESSAGE = getCurrentMessage(event);
var prefills = [getTitle(MESSAGE),
getBody(MESSAGE)];
var card = createExpensesCard(prefills);
return [card.build()];
}
//Get the current message opened
function getCurrentMessage(event) {
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}
Cards.gs
var FIELDNAMES = ['Título', 'Mensagem', 'URL da Planilha'];
/**
* Creates the main card users see with form inputs to log expense.
* Form can be prefilled with values.
*
* @param {String[]} opt_prefills Default values for each input field.
* @param {String} opt_status Optional status displayed at top of card.
* @returns {Card}
*/
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
var clearForm = CardService.newAction()
.setFunctionName('clearForm')
.setParameters({'Status': opt_status ? opt_status : ''});
var clearAction = CardService.newCardAction()
.setText('Clear form')
.setOnClickAction(clearForm);
card.addCardAction(clearAction);
if (opt_status) {
if (opt_status.indexOf('Error: ') == 0) {
opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
} else {
opt_status = '<font color=\'#1dd11d\'>' + opt_status + '</font>';
}
var statusSection = CardService.newCardSection();
statusSection.addWidget(CardService.newTextParagraph()
.setText('<b>' + opt_status + '</b>'));
card.addSection(statusSection);
}
var formSection = createFormSection(CardService.newCardSection(),FIELDNAMES, opt_prefills);
var newSheetSection = CardService.newCardSection();
var sheetName = CardService.newTextInput()
.setFieldName('Sheet Name')
.setTitle('Nome da planilha');
var createSheet = CardService.newAction()
.setFunctionName('createSheet');
var newSheetButton = CardService.newTextButton()
.setText('Nova planílha')
.setOnClickAction(createSheet);
newSheetSection.addWidget(sheetName);
newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton));
card.addSection(newSheetSection);
card.addSection(formSection);
return card;
}
function createFormSection(section, inputNames, opt_prefills) {
for (var i = 0; i < inputNames.length; i++) {
var widget = CardService.newTextInput()
.setFieldName(inputNames[i])
.setTitle(inputNames[i]);
if (opt_prefills && opt_prefills[i]) {
widget.setValue(opt_prefills[i]);
}
section.addWidget(widget);
}
var submitForm = CardService.newAction().setFunctionName('submitForm');
var submitButton = CardService.newTextButton()
.setText('Submit')
.setOnClickAction(submitForm);
section.addWidget(CardService.newButtonSet().addButton(submitButton));
return section;
}
/**
* Logs form inputs into a spreadsheet given by URL from form.
* Then displays edit card.
*
* @param {Event} e An event object containing form inputs and parameters.
* @returns {Card}
*/
function submitForm(e) {
try {
var res = e['formInput'];
FIELDNAMES.forEach(function(fieldName) {
if (! res[fieldName]) {
throw 'Formulário incompleto';
}
});
var sheet = SpreadsheetApp
.openByUrl((res['URL da Planilha']))
.getActiveSheet();
sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
PropertiesService.getUserProperties().setProperty('SPREADSHEET_URL', res['URL da Planilha']);
return createExpensesCard(null, 'Cobrança inserida com sucesso!').build();
}
catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'URL Inválido';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Erro: ' + err).build();
}
}
/**
* Returns an array corresponding to the given object and desired ordering of keys.
*
* @param {Object} obj Object whose values will be returned as an array.
* @param {String[]} keys An array of key names in the desired order.
* @returns {Object[]}
*/
function objToArray(obj, keys) {
return keys.map(function(key) {
return obj[key];
});
}
/**
* Recreates the main card without prefilled data.
*
* @param {Event} e An event object containing form inputs and parameters.
* @returns {Card}
*/
function clearForm(e) {
createSheet(e);
return createExpensesCard(null, e['parameters']['Status']).build();
}
function ifExists() {
var ss = SpreadsheetApp.getActive();
var shts = ss.getSheets();
for(let sheet of shts) {
if(sheet.getName() == 'DBQuiteOften') {
var retorno = [true,sheet];
return retorno;
}
}
var retorno = [false,];
return retorno;
}
function createSheet(e) {
try{
var res = e['formInput'];
var sheetName = res['Sheet Name'] ? res['Sheet Name'] : 'DBQuiteOften';
var exist = ifExists();
if(!exist[0]){
newSpreadsheet = SpreadsheetApp.create(sheetName);
newSpreadsheet.setFrozenRows(1);
newSpreadsheet
.getActiveSheet()
.getRange(1, 1, 1, FIELDNAMES.length - 1)
.setValues([FIELDNAMES.slice(0, FIELDNAMES.length - 1)]);
var prefills = objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1));
prefills.push(newSpreadsheet.getUrl());
return createExpensesCard(prefills, 'Planílha criada e inserida com nome <i>' +
sheetName ).build();
}else{
var prefills = objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1));
prefills.push(exist[1].getUrl());
return createExpensesCard(prefills, 'Planílha criada e inserida com nome <i>' +
sheetName ).build();
}
} catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'URL Inválido';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Erro: ' + err).build();
}
}
Helpers.gs
/*
* Get body of the selected message
*/
function getBody(message) {
return message.getBody();
}
function getUser(){
// If user has themselves in their contacts, return their name
// Prefer given name, if that's available
var userName = Session.getEffectiveUser().getUsername();
return userName;
}
/**
* Determines date the email was received.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getReceivedDate(message) {
return message.getDate().toLocaleDateString();
}
/**
* Determines title by joining sender name and message subject.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getTitle(message) {
var sender = message.getFrom();
var subject = message.getSubject();
return sender + " | " + subject;
}
/**
* Determines most recent spreadsheet URL.
* Returns null if no URL was previously submitted.
*
* @returns {String}
*/
/**
* Determines most recent spreadsheet URL.
* Returns null if no URL was previously submitted.
*
* @returns {String}
*/
function getSheetUrl() {
return PropertiesService.getUserProperties().getProperty('SPREADSHEET_URL');
}
appsscript.json
{
"timeZone": "GMT",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.google.com/m8/feeds"
],
"runtimeVersion": "V8",
"gmail": {
"name": "Salvar Email",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/bookmark_white_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "getContextualAddOn"
}],
"primaryColor": "#00FFFF",
"secondaryColor": "#99FFFF"
}
}
function ifExists(name) {
var ss=SpreadsheetApp.getActive();
var shts=ss.getSheets();
for(var i=0;i<shts.length;i++) {
if(shts[i].getName()==name) {
return true;
}
}
return false;
}
我会这样做的:
function ifExists() {
var ss = SpreadsheetApp.getActive();
var shts = ss.getSheets();
for(let sheet of shts) {
if(sheet.getName() == 'DBQuiteOften') {
var retorno = {found:true,sheet:sheet};
return retorno;
}
}
var retorno = {found:false,sheet:''};
return retorno;
}
那么这个 var exist = ifExists();
将是:var exist = ifExists().found;
而这个 if(!exist[0])
将是:if(!exist.found)
我找到了我需要的答案。使用 DriveApp。
function ifExists() {
var title = "SheetFileName";
var files = DriveApp.searchFiles('mimeType contains "spreadsheet" and title contains "' + title + '"');
while (files.hasNext()) {
var file = files.next();
var retorno = [true,file];
return retorno;
}
var retorno = [false,];
return retorno;
}
我正在尝试创建一个 sheet,它将像数据库一样工作,用于存储来自 Gmail 的某些数据(我的边栏仅适用于 Gmail)。
但是,在为此创建新的 google sheet 之前,我必须查看 sheet 是否已经存在。如果是,我想将数据保存到现有的 sheet.
我该怎么做?
GetContextualAddOn.gs
var MESSAGE;
//Returns the sidebar with his cards
function getContextualAddOn(event) {
MESSAGE = getCurrentMessage(event);
var prefills = [getTitle(MESSAGE),
getBody(MESSAGE)];
var card = createExpensesCard(prefills);
return [card.build()];
}
//Get the current message opened
function getCurrentMessage(event) {
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}
Cards.gs
var FIELDNAMES = ['Título', 'Mensagem', 'URL da Planilha'];
/**
* Creates the main card users see with form inputs to log expense.
* Form can be prefilled with values.
*
* @param {String[]} opt_prefills Default values for each input field.
* @param {String} opt_status Optional status displayed at top of card.
* @returns {Card}
*/
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
var clearForm = CardService.newAction()
.setFunctionName('clearForm')
.setParameters({'Status': opt_status ? opt_status : ''});
var clearAction = CardService.newCardAction()
.setText('Clear form')
.setOnClickAction(clearForm);
card.addCardAction(clearAction);
if (opt_status) {
if (opt_status.indexOf('Error: ') == 0) {
opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
} else {
opt_status = '<font color=\'#1dd11d\'>' + opt_status + '</font>';
}
var statusSection = CardService.newCardSection();
statusSection.addWidget(CardService.newTextParagraph()
.setText('<b>' + opt_status + '</b>'));
card.addSection(statusSection);
}
var formSection = createFormSection(CardService.newCardSection(),FIELDNAMES, opt_prefills);
var newSheetSection = CardService.newCardSection();
var sheetName = CardService.newTextInput()
.setFieldName('Sheet Name')
.setTitle('Nome da planilha');
var createSheet = CardService.newAction()
.setFunctionName('createSheet');
var newSheetButton = CardService.newTextButton()
.setText('Nova planílha')
.setOnClickAction(createSheet);
newSheetSection.addWidget(sheetName);
newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton));
card.addSection(newSheetSection);
card.addSection(formSection);
return card;
}
function createFormSection(section, inputNames, opt_prefills) {
for (var i = 0; i < inputNames.length; i++) {
var widget = CardService.newTextInput()
.setFieldName(inputNames[i])
.setTitle(inputNames[i]);
if (opt_prefills && opt_prefills[i]) {
widget.setValue(opt_prefills[i]);
}
section.addWidget(widget);
}
var submitForm = CardService.newAction().setFunctionName('submitForm');
var submitButton = CardService.newTextButton()
.setText('Submit')
.setOnClickAction(submitForm);
section.addWidget(CardService.newButtonSet().addButton(submitButton));
return section;
}
/**
* Logs form inputs into a spreadsheet given by URL from form.
* Then displays edit card.
*
* @param {Event} e An event object containing form inputs and parameters.
* @returns {Card}
*/
function submitForm(e) {
try {
var res = e['formInput'];
FIELDNAMES.forEach(function(fieldName) {
if (! res[fieldName]) {
throw 'Formulário incompleto';
}
});
var sheet = SpreadsheetApp
.openByUrl((res['URL da Planilha']))
.getActiveSheet();
sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
PropertiesService.getUserProperties().setProperty('SPREADSHEET_URL', res['URL da Planilha']);
return createExpensesCard(null, 'Cobrança inserida com sucesso!').build();
}
catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'URL Inválido';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Erro: ' + err).build();
}
}
/**
* Returns an array corresponding to the given object and desired ordering of keys.
*
* @param {Object} obj Object whose values will be returned as an array.
* @param {String[]} keys An array of key names in the desired order.
* @returns {Object[]}
*/
function objToArray(obj, keys) {
return keys.map(function(key) {
return obj[key];
});
}
/**
* Recreates the main card without prefilled data.
*
* @param {Event} e An event object containing form inputs and parameters.
* @returns {Card}
*/
function clearForm(e) {
createSheet(e);
return createExpensesCard(null, e['parameters']['Status']).build();
}
function ifExists() {
var ss = SpreadsheetApp.getActive();
var shts = ss.getSheets();
for(let sheet of shts) {
if(sheet.getName() == 'DBQuiteOften') {
var retorno = [true,sheet];
return retorno;
}
}
var retorno = [false,];
return retorno;
}
function createSheet(e) {
try{
var res = e['formInput'];
var sheetName = res['Sheet Name'] ? res['Sheet Name'] : 'DBQuiteOften';
var exist = ifExists();
if(!exist[0]){
newSpreadsheet = SpreadsheetApp.create(sheetName);
newSpreadsheet.setFrozenRows(1);
newSpreadsheet
.getActiveSheet()
.getRange(1, 1, 1, FIELDNAMES.length - 1)
.setValues([FIELDNAMES.slice(0, FIELDNAMES.length - 1)]);
var prefills = objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1));
prefills.push(newSpreadsheet.getUrl());
return createExpensesCard(prefills, 'Planílha criada e inserida com nome <i>' +
sheetName ).build();
}else{
var prefills = objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1));
prefills.push(exist[1].getUrl());
return createExpensesCard(prefills, 'Planílha criada e inserida com nome <i>' +
sheetName ).build();
}
} catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'URL Inválido';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Erro: ' + err).build();
}
}
Helpers.gs
/*
* Get body of the selected message
*/
function getBody(message) {
return message.getBody();
}
function getUser(){
// If user has themselves in their contacts, return their name
// Prefer given name, if that's available
var userName = Session.getEffectiveUser().getUsername();
return userName;
}
/**
* Determines date the email was received.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getReceivedDate(message) {
return message.getDate().toLocaleDateString();
}
/**
* Determines title by joining sender name and message subject.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getTitle(message) {
var sender = message.getFrom();
var subject = message.getSubject();
return sender + " | " + subject;
}
/**
* Determines most recent spreadsheet URL.
* Returns null if no URL was previously submitted.
*
* @returns {String}
*/
/**
* Determines most recent spreadsheet URL.
* Returns null if no URL was previously submitted.
*
* @returns {String}
*/
function getSheetUrl() {
return PropertiesService.getUserProperties().getProperty('SPREADSHEET_URL');
}
appsscript.json
{
"timeZone": "GMT",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.google.com/m8/feeds"
],
"runtimeVersion": "V8",
"gmail": {
"name": "Salvar Email",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/bookmark_white_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "getContextualAddOn"
}],
"primaryColor": "#00FFFF",
"secondaryColor": "#99FFFF"
}
}
function ifExists(name) {
var ss=SpreadsheetApp.getActive();
var shts=ss.getSheets();
for(var i=0;i<shts.length;i++) {
if(shts[i].getName()==name) {
return true;
}
}
return false;
}
我会这样做的:
function ifExists() {
var ss = SpreadsheetApp.getActive();
var shts = ss.getSheets();
for(let sheet of shts) {
if(sheet.getName() == 'DBQuiteOften') {
var retorno = {found:true,sheet:sheet};
return retorno;
}
}
var retorno = {found:false,sheet:''};
return retorno;
}
那么这个 var exist = ifExists();
将是:var exist = ifExists().found;
而这个 if(!exist[0])
将是:if(!exist.found)
我找到了我需要的答案。使用 DriveApp。
function ifExists() {
var title = "SheetFileName";
var files = DriveApp.searchFiles('mimeType contains "spreadsheet" and title contains "' + title + '"');
while (files.hasNext()) {
var file = files.next();
var retorno = [true,file];
return retorno;
}
var retorno = [false,];
return retorno;
}