Last active
April 25, 2018 09:24
-
-
Save soundTricker/4c60b20e2d7c986115e9e4d549ce4ba6 to your computer and use it in GitHub Desktop.
Gmail Add-ons ハンズオン
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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" | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()]; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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