Skip to content

Instantly share code, notes, and snippets.

@soundTricker
Last active April 25, 2018 09:24
Show Gist options
  • Save soundTricker/4c60b20e2d7c986115e9e4d549ce4ba6 to your computer and use it in GitHub Desktop.
Save soundTricker/4c60b20e2d7c986115e9e4d549ce4ba6 to your computer and use it in GitHub Desktop.
Gmail Add-ons ハンズオン
{
"timeZone": "Asia/Tokyo",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute"
],
"gmail": {
"version": "TRUSTED_TESTER_V2",
"name": "Expense It!",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/receipt_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "getContextualAddOn"
}],
"primaryColor": "#41f470",
"secondaryColor": "#94f441"
}
}
function getContextualAddOn(event) {
// Gmail Addons用のUIオブジェクト
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
// UIの作成
var section = CardService.newCardSection();
section.addWidget(CardService.newTextInput().setFieldName('Date').setTitle('Date'));
section.addWidget(CardService.newTextInput().setFieldName('Amount').setTitle('Amount'));
section.addWidget(CardService.newTextInput().setFieldName('Description').setTitle('Description'));
section.addWidget(CardService.newTextInput().setFieldName('Spreadsheet URL').setTitle('Spreadsheet URL'));
card.addSection(section);
return [card.build()];
}
var FIELDNAMES = ['Date', 'Amount', 'Description', 'Spreadsheet URL'];
function getContextualAddOn(event) {
var message = getCurrentMessage(event);
var prefills = [getReceivedDate(message),
getLargestAmount(message),
getExpenseDescription(message),
getSheetUrl()];
var card = createExpensesCard(prefills);
return [card.build()];
}
function getCurrentMessage(event) {
// eventからメッセージ情報を取得
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}
function getReceivedDate(message) {
return "TODO";
}
function getLargestAmount(message) {
return "TODO";
}
function getExpenseDescription(message) {
return "TODO";
}
function getSheetUrl(message) {
return "TODO";
}
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
if (opt_status) {
if (opt_status.indexOf('Error: ') == 0) {
opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
} else {
opt_status = '<font color=\'#228B22\'>' + 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);
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);
}
return section;
}
function getContextualAddOn(event) {
var message = getCurrentMessage(event);
var prefills = [getReceivedDate(message),
getLargestAmount(message),
getExpenseDescription(message),
getSheetUrl()];
var card = createExpensesCard(prefills);
return [card.build()];
}
function getCurrentMessage(event) {
// eventからメッセージ情報を取得
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}
function getReceivedDate(message) {
return "TODO";
}
function getLargestAmount(message) {
return "TODO";
}
function getExpenseDescription(message) {
return "TODO";
}
function getSheetUrl(message) {
return "TODO";
}
var FIELDNAMES = ['Date', 'Amount', 'Description', 'Spreadsheet URL'];
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
if (opt_status) {
if (opt_status.indexOf('Error: ') == 0) {
opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
} else {
opt_status = '<font color=\'#228B22\'>' + 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);
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;
}
function submitForm(e) {
var res = e['formInput'];
try {
FIELDNAMES.forEach(function(fieldName) {
if (! res[fieldName]) {
throw 'incomplete form';
}
});
var sheet = SpreadsheetApp.openByUrl((res['Spreadsheet URL'])).getActiveSheet();
sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
return createExpensesCard(null, 'Logged expense successfully!').build();
}
catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'Invalid URL';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Error: ' + err).build();
}
}
function objToArray(obj, keys) {
return keys.map(function(key) {
return obj[key];
});
}
function getContextualAddOn(event) {
var message = getCurrentMessage(event);
var prefills = [getReceivedDate(message),
getLargestAmount(message),
getExpenseDescription(message),
getSheetUrl()];
var card = createExpensesCard(prefills);
return [card.build()];
}
function getCurrentMessage(event) {
// eventからメッセージ情報を取得
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}
function getReceivedDate(message) {
return message.getDate().toLocaleDateString();
}
function getLargestAmount(message) {
var amount = 0;
var messageBody = message.getPlainBody();
var regex = /([\d,]+)円/g;
var match = regex.exec(messageBody);
while (match) {
amount = Math.max(amount, parseFloat(match[1].replace(/,/g,'')));
match = regex.exec(messageBody);
}
return amount ? amount.toString() + "円" : null;
}
function getExpenseDescription(message) {
var sender = message.getFrom();
var subject = message.getSubject();
return sender + " | " + subject;
}
function getSheetUrl(message) {
return PropertiesService.getUserProperties().getProperty('SPREADSHEET_URL');
}
var FIELDNAMES = ['Date', 'Amount', 'Description', 'Spreadsheet URL'];
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
if (opt_status) {
if (opt_status.indexOf('Error: ') == 0) {
opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
} else {
opt_status = '<font color=\'#228B22\'>' + 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);
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;
}
function submitForm(e) {
var res = e['formInput'];
try {
FIELDNAMES.forEach(function(fieldName) {
if (! res[fieldName]) {
throw 'incomplete form';
}
});
var sheet = SpreadsheetApp.openByUrl((res['Spreadsheet URL'])).getActiveSheet();
sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
PropertiesService.getUserProperties().setProperty('SPREADSHEET_URL', res['Spreadsheet URL']);
return createExpensesCard(null, 'Logged expense successfully!').build();
}
catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'Invalid URL';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Error: ' + err).build();
}
}
function objToArray(obj, keys) {
return keys.map(function(key) {
return obj[key];
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment