这是indexloc提供的服务,不要输入任何密码
Skip to content

Send periodical reminder mail to notify team of website status monitoring #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 64 additions & 5 deletions src/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const MESSAGES = {
menuTriggers: 'Triggers',
menuSetStatusCheckTrigger: 'Set Status Check Trigger',
menuSetLogExtractionTrigger: 'Set Log Extraction Trigger',
menuSetReminderTrigger: 'Set Reminder Trigger',
menuDeleteTriggers: 'Delete Triggers',
menuCheckStatus: 'Check Status',
menuExtractStatusLogs: 'Extract Status Logs',
Expand All @@ -38,6 +39,8 @@ const MESSAGES = {
alertTitleCompleteTriggerSetup: 'Complete ({{handlerFunction}})',
alertMessageCompleteTriggerSetup:
'Trigger set at {{frequency}}-{{frequencyUnit}} interval.',
alertMessageCompleteReminderTriggerSetup:
'Monthly reminder to notify {{myEmail}} of the website status settings is now set up. You will be notified of the monitoring status on the first day of each month.',
alertTitleContinueTriggerDelete: 'Deleting All Triggers',
alertMessageContinueTriggerDelete:
'Deleting all existing trigger(s) on this spreadsheet/script set by {{myEmail}}. Are you sure you want to continue?',
Expand All @@ -55,7 +58,7 @@ const MESSAGES = {
'\nChanges to website status have been emailed to {{myEmail}}',
alertTitleCompleteStatusCheck: '[Website Status] Complete: Status Check',
mailSubErrorStatusCheck: '[Website Status] Error: Status Check',
mailBodyErrorStatusCheck:
mailBodyError:
'{{errorStack}}\n\n-----\nThis notice is managed by the following spreadsheet:\n{{spreadsheetUrl}}',
alertTitleError: 'ERROR',
errorHeaderNameTargetUrlNotFound:
Expand All @@ -70,12 +73,21 @@ const MESSAGES = {
'[Website Status] Error in Status Log Extraction:\n{{errorStack}}',
errorInvalidResponseCode:
'Invalid response code "{{code}}" at ALLOWED_RESPONSE_CODES or ERROR_RESPONSE_CODES.',
mailSubSendReminderPrefix: '[Website Status] ',
mailSubSendReminder: 'Reminder: Active Triggers',
mailBodySendReminder:
'This is a monthly reminder, sent automatically, of the time-based triggers set for this website monitoring script:\n\n{{triggerInfo}}\nSee the managing spreadsheet for details on the latest website status.\n\n-----\nThis notice is managed by the following spreadsheet:\n{{spreadsheetUrl}}',
mailSubErrorSendReminder: 'Error: Send Reminder',
messageMonitoredSitesPrefix: 'Monitored Websites',
messageTriggerLogExtractionIsSet:
'Trigger for periodical status log extraction is set.',
},
ja_JP: {
menuTitle: 'サイト公開ステータス',
menuTriggers: 'トリガー',
menuSetStatusCheckTrigger: 'トリガー設定(ステータス確認)',
menuSetLogExtractionTrigger: 'トリガー設定(ログ抽出)',
menuSetReminderTrigger: 'トリガー設定(リマインダー)',
menuDeleteTriggers: 'トリガー削除',
menuCheckStatus: 'ステータス確認',
menuExtractStatusLogs: '確認ログを抽出',
Expand All @@ -93,6 +105,8 @@ const MESSAGES = {
alertTitleCompleteTriggerSetup: '完了({{handlerFunction}})',
alertMessageCompleteTriggerSetup:
'トリガー設定完了:{{frequency}}-{{frequencyUnit}}間隔.',
alertMessageCompleteReminderTriggerSetup:
'{{myEmail}}宛にサイト公開ステータス監視の設定状況をリマインドするトリガーの設定が完了しました。毎月1日に、公開監視状況の設定が通知されます。',
alertTitleContinueTriggerDelete: '全てのトリガーを削除します',
alertMessageContinueTriggerDelete:
'このスプレッドシート/スクリプトで {{myEmail}} によって設定された全てのトリガーを削除します。このまま続けますか?',
Expand All @@ -112,7 +126,7 @@ const MESSAGES = {
alertTitleCompleteStatusCheck:
'[サイト公開ステータス] 完了:ステータス確認',
mailSubErrorStatusCheck: '[サイト公開ステータス] エラー:ステータス確認',
mailBodyErrorStatusCheck:
mailBodyError:
'{{errorStack}}\n\n-----\nこの通知は次のGoogleスプレッドシートによって管理されています:\n{{spreadsheetUrl}}',
alertTitleError: 'エラー',
errorHeaderNameTargetUrlNotFound:
Expand All @@ -127,6 +141,14 @@ const MESSAGES = {
'[サイト公開ステータス] ログ抽出エラー:\n{{errorStack}}',
errorInvalidResponseCode:
'無効なレスポンスコード「{{code}}」が ALLOWED_RESPONSE_CODES または ERROR_RESPONSE_CODES にて指定されています。',
mailSubSendReminderPrefix: '[サイト公開ステータス] ',
mailSubSendReminder: 'リマインダー:設定されているトリガー',
mailBodySendReminder:
'これは、サイト公開ステータス監視のトリガー設定状況をお知らせするため、毎月1日に自動的に送信されるリマインダーです。\n\n{{triggerInfo}}\n最新のサイト公開ステータスについては、管理スプレッドシートをご確認ください。\n\n-----\nこの通知は次のGoogleスプレッドシートによって管理されています:\n{{spreadsheetUrl}}',
mailSubErrorSendReminder: 'エラー:リマインダー送信',
messageMonitoredSitesPrefix: '公開ステータスの監視対象サイト',
messageTriggerLogExtractionIsSet:
'公開ステータスログを定期的に抽出するトリガーが設定されています。',
},
};

Expand Down Expand Up @@ -324,13 +346,13 @@ class LocalizedMessage {
return text;
}
/**
* Replace placeholder string in this.messageList.mailBodyErrorStatusCheck
* Replace placeholder string in this.messageList.mailBodyError
* @param {String} errorStack
* @param {String} spreadsheetUrl
* @returns {String} The replaced text.
*/
replaceMailBodyErrorStatusCheck(errorStack, spreadsheetUrl) {
let text = this.messageList.mailBodyErrorStatusCheck;
replaceMailBodyError(errorStack, spreadsheetUrl) {
let text = this.messageList.mailBodyError;
let placeholderValues = [
{
regexp: '{{errorStack}}',
Expand Down Expand Up @@ -424,4 +446,41 @@ class LocalizedMessage {
text = this.replacePlaceholders_(text, placeholderValues);
return text;
}
/**
* Replace placeholder string in this.messageList.alertMessageCompleteReminderTriggerSetup
* @param {String} myEmail
* @returns {String} The replaced text.
*/
replaceAlertMessageCompleteReminderTriggerSetup(myEmail) {
let text = this.messageList.alertMessageCompleteReminderTriggerSetup;
let placeholderValues = [
{
regexp: '{{myEmail}}',
value: myEmail,
},
];
text = this.replacePlaceholders_(text, placeholderValues);
return text;
}
/**
* Replace placeholder string in this.messageList.mailBodySendReminder
* @param {String} triggerInfo
* @param {String} spreadsheetUrl
* @returns {String} The replaced text.
*/
replaceMailBodySendReminder(triggerInfo, spreadsheetUrl) {
let text = this.messageList.mailBodySendReminder;
let placeholderValues = [
{
regexp: '{{triggerInfo}}',
value: triggerInfo,
},
{
regexp: '{{spreadsheetUrl}}',
value: spreadsheetUrl,
},
];
text = this.replacePlaceholders_(text, placeholderValues);
return text;
}
}
132 changes: 125 additions & 7 deletions src/websiteMonitoring.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
deleteTimeBasedTriggers,
extractStatusLogsTriggered,
onOpen,
sendReminder,
setupLogExtractionTrigger,
setupReminderTrigger,
setupStatusCheckTrigger,
websiteMonitoringTriggered
*/
Expand Down Expand Up @@ -62,6 +64,10 @@ function onOpen() {
localMessage.messageList.menuSetLogExtractionTrigger,
'setupLogExtractionTrigger'
)
.addItem(
localMessage.messageList.menuSetReminderTrigger,
'setupReminderTrigger'
)
.addSeparator()
.addItem(
localMessage.messageList.menuDeleteTriggers,
Expand All @@ -84,7 +90,7 @@ function setupStatusCheckTrigger() {
const handlerFunction = 'websiteMonitoringTriggered';
const frequencyKey = 'TRIGGER_MINUTE_FREQUENCY_STATUS_CHECK';
const frequencyUnit = 'minute';
setupTrigger(handlerFunction, frequencyKey, frequencyUnit);
setupTrigger_(handlerFunction, frequencyKey, frequencyUnit);
}

/**
Expand All @@ -95,7 +101,7 @@ function setupLogExtractionTrigger() {
const handlerFunction = 'extractStatusLogsTriggered';
const frequencyKey = 'TRIGGER_DAYS_FREQUENCY_LOG_EXTRACTION';
const frequencyUnit = 'day';
setupTrigger(handlerFunction, frequencyKey, frequencyUnit);
setupTrigger_(handlerFunction, frequencyKey, frequencyUnit);
}

/**
Expand All @@ -105,7 +111,7 @@ function setupLogExtractionTrigger() {
* @param {String} frequencyKey Key in the options sheet that refers to the trigger frequency for this handler function.
* @param {String} frequencyUnit Unit of the value of frequencyKey, i.e., minute, hour, day, or week.
*/
function setupTrigger(handlerFunction, frequencyKey, frequencyUnit) {
function setupTrigger_(handlerFunction, frequencyKey, frequencyUnit) {
const ui = SpreadsheetApp.getUi();
const myEmail = Session.getActiveUser().getEmail();
const ss = SpreadsheetApp.getActiveSpreadsheet();
Expand Down Expand Up @@ -200,6 +206,34 @@ function setupTrigger(handlerFunction, frequencyKey, frequencyUnit) {
}
}

/**
* Set time-based trigger for sending monthly reminders
* of active time-based triggers set by this user in this script.
* Trigger will be set for the first day of each month.
*/
function setupReminderTrigger() {
const ui = SpreadsheetApp.getUi();
const localMessage = new LocalizedMessage(
SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetLocale()
);
const handlerFunction = 'sendReminder';
// Delete existing trigger for the same handler function.
ScriptApp.getProjectTriggers().forEach((trigger) => {
if (trigger.getHandlerFunction() === handlerFunction) {
ScriptApp.deleteTrigger(trigger);
}
});
// Set new trigger
ScriptApp.newTrigger(handlerFunction).timeBased().onMonthDay(1).create();
ui.alert(
localMessage.replaceAlertTitleCompleteTriggerSetup(handlerFunction),
localMessage.replaceAlertMessageCompleteReminderTriggerSetup(
Session.getActiveUser().getEmail()
),
ui.ButtonSet.OK
);
}

/**
* Delete existing trigger(s).
*/
Expand Down Expand Up @@ -540,10 +574,7 @@ function websiteMonitoring(triggered = false) {
'NA',
]);
let messageSub = localMessage.messageList.mailSubErrorStatusCheck;
let messageBody = localMessage.replaceMailBodyErrorStatusCheck(
e.stack,
ss.getUrl()
);
let messageBody = localMessage.replaceMailBodyError(e.stack, ss.getUrl());
if (options.ENABLE_CHAT_NOTIFICATION) {
// Post on Google Chat
postToChat_(
Expand Down Expand Up @@ -740,6 +771,93 @@ function extractStatusLogs(triggered = false) {
}
}

/**
* Send a reminder to the user on the website status monitoring settings.
*/
function sendReminder() {
const triggers = ScriptApp.getProjectTriggers();
if (triggers.length > 0) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const localMessage = new LocalizedMessage(ss.getSpreadsheetLocale());
const myEmail = Session.getActiveUser().getEmail();
// Parse options data from spreadsheet
const optionsArr = ss
.getSheetByName(SHEET_NAME_OPTIONS)
.getDataRange()
.getValues();
optionsArr.shift();
const options = optionsArr.reduce((obj, row) => {
let [key, value] = [row[1], row[2]]; // Assuming that the keys and their options are set in columns B and C, respectively.
if (key) {
obj[key] = value;
}
return obj;
}, {});
var messageSub = localMessage.messageList.mailSubSendReminderPrefix;
var messageBody = '';
try {
let triggerInfo = triggers
.reduce((info, trigger) => {
if (trigger.getHandlerFunction() === 'websiteMonitoringTriggered') {
// Get the list of target websites to monitor
const targetWebsitesSheet = ss.getSheetByName(SHEET_NAME_DASHBOARD);
const targetWebsitesArr = targetWebsitesSheet
.getRange(
TARGET_WEBSITES_RANGE_POSITION.row,
TARGET_WEBSITES_RANGE_POSITION.col,
targetWebsitesSheet.getLastRow() -
TARGET_WEBSITES_RANGE_POSITION.row +
1,
TARGET_WEBSITES_COL_NUM
)
.getValues();
targetWebsitesArr.shift();
info.push(
`${
localMessage.messageList.messageMonitoredSitesPrefix
}:\n${targetWebsitesArr
.map((website) => `- ${website.join(' ')}`)
.join('\n')}`
);
} else if (
trigger.getHandlerFunction() === 'extractStatusLogsTriggered'
) {
info.push(
localMessage.messageList.messageTriggerLogExtractionIsSet
);
}
return info;
}, [])
.join('\n');
messageSub += localMessage.messageList.mailSubSendReminder;
messageBody = localMessage.replaceMailBodySendReminder(
triggerInfo,
ss.getUrl()
);
} catch (e) {
console.error(e.stack);
messageSub += localMessage.messageList.mailSubErrorSendReminder;
messageBody = localMessage.replaceMailBodyError(e.stack, ss.getUrl());
} finally {
if (options.ENABLE_CHAT_NOTIFICATION) {
// Post on Google Chat
postToChat_(
options.CHAT_WEBHOOK_URL,
`*${messageSub}*\n\n${messageBody}`
);
}
if (
!options.ENABLE_CHAT_NOTIFICATION ||
!options.DISABLE_MAIL_NOTIFICATION
) {
// If chat notification is disabled OR mail notification is NOT disabled
// send email notification
MailApp.sendEmail(myEmail, messageSub, messageBody);
}
}
}
}

/**
* Parse a given array of HTTP reponse codes (in strings) into actual codes.
* For example, ["201", "30x"] will be converted into the following array of codes:
Expand Down