何らかのメールで飛んできた情報を、全体広報したいみたいな場合がある。例えば僕の場合は、秘書サービスでかかってきた電話の情報がそうだ。
今はこれをメーリングリストで解決しているのだけれど、Slackに流してナウくしたいと思った。Slackならリアクションとかも使えるので応答状態の可視化も楽だ。
方針
時間を掛けたくないので、下記のような方針で手軽に作ることにした。
- Google Apps Scriptで実装する
- Slackにはwebhookで流す
- 1分に1回実行する
- 通知対象のメールはInboxを経由させずに取って、未読のものを通知するようにする。
ハマったポイント
GmailのQuotaが少ないのにハマった。
このドキュメントによると、意外と"Email read/write"のQuotaが5万回。メール1つの既読/未読を判定するだけでもQuotaを消費するので、1日1440回も雑に実行していると、すぐに枯渇する。
そういうわけで適当にコードで判定するんじゃなくて、検索クエリで縛ってやることにした。
僕は、検索ワード is:unread
というクエリにして対応した。
(最初、これを知らずにやっていてGASのエラー通知メールがエラいことになった)
GASとJavaScriptが微妙に違う
何故かfor-in
とかfor-of
が動かない気がした。
多分、GASにはこの文法が無い。僕にはGASの正確な文法についてのドキュメントが見つけられなかったのですが、おそらく無い。 "based on JavaScript"であってJavaScriptではないらしい。
そういうわけで
作った。僕の場合はこんな感じのコードになりました。Spreadsheetでも、単体Scriptでも動きます。
時間トリガーで1分ごとに動かしています。
function Check() {
var threads = GmailApp.search("ほげほげ is:unread")
for (var i=0; i<threads.length; i++) {
var thread = threads[i]
if (!thread.isUnread()) {
continue
}
var messages = thread.getMessages()
for (var j=0; j<messages.length; j++) {
message = messages[j]
if (!message.isUnread()) {
continue
}
str = message.getBody().match(/ほしい文字の上([\s\S]*)ほしい文字の下/)
if (str == null || str.length != 2) {
Logger.log("miss?")
} else {
sendToSlack(str[1].trim())
message.markRead()
}
}
}
}
function sendToSlack(message){
var url = 'https://hooks.slack.com/services/****************';
var payload = {
'text' : message,
};
var params = {
"payload": JSON.stringify(payload),
"method": "POST",
}
UrlFetchApp.fetch(url, params);
}
感想
Google Apps Script本当に便利ですね。
こういう感じで便利スクリプト書いていきたい。