背景
本研究室では昔から使用しているグループメール(googlegroups)がありました.そして数年後,slackが導入されたのです.
slackは便利ですね,なんでもslackで連絡したくなります.generalチャンネルを使えば全体への通知も簡単ですし.
ところが我が研究室のボスは,諸事情から重要な連絡はグループメールを使っているのです.slackのgeneralに投げてほしいなあと思いますが,まあ色々な考えがあるのでしょう.
とはいってもグループメールはslackのgeneralでも確認したいのです.つまりメールをslackのgeneralに自動転送する仕組みが欲しいのです.しかしネットで調べても,基本的にはslackのEmaliのアプリ(slackの料金プランが有料以上)を使用するだったり,自分のslackbotに送るだったり,何とも微妙なのです.
ということで,Gmail (Google Apps Script)とSlack (Slack Bot)を組み合わせて,届いたメールをslackのgeneralに(無料で)転送する仕組みを作った話をします.
アイデアと手続き
インターネットを調べた感じ,Slackのボットをまず作って,そのボットを他のスクリプトから操作する,みたいな感じでいけそうでした.
Slackボットを操作するスクリプトとしてはGoogle Apps Scriptが妥当そうです.なぜならば,Google Apps ScriptにはSlackを操作するライブラリがあり,かつGmailとの連携により,メールボックスを確認することも可能だからです.
そのため手続きとしては以下になります.
- Slackのボットを作る
- Google Apps Scriptを作成,ScriptからSlackボットを通じてメッセージを送る
- 上Scriptを定期的に実行させる
Slackのボットを作る
以下のページを参考にしました.このままやればできます.
基本的には,アプリ(ボット)を作る,ワークスペースにアプリをインストールする,アプリがメッセージを送信できるように設定する,アプリをGoogle Apps Scriptから操作するためのトークンを取得する,といった感じです.
Google Apps Scriptの作り方,Slackライブラリの追加も上リンクに書いてあるので,そちらを参照で.
Google Apps Scriptを作成,ScriptからSlackボットを通じてメッセージを送る
最終的には以下のscriptを作成しました.checkMailBox()
がエントリポイントです.
function postSlackbot( message ) {
let token = "YOUR TOKEN";
let slackApp = SlackApp.create( token );
const channelId = "#general";
slackApp.postMessage( channelId, message );
}
function formatDate( date ) {
const formated = Utilities.formatDate( date, "Asia/Tokyo", "yyyy-MM-dd HH:mm:ss" );
return formated;
}
function checkMailBox() { // Step 1
const start = 0;
const max = 5;
const query = "from:(xxx@gmail.com)"; // Step 2
const threads = GmailApp.search( query, start, max );
const messagesForThreads = GmailApp.getMessagesForThreads( threads );
for( const messages of messagesForThreads ){
const message = messages[0];
const subject = message.getSubject();
const body = message.getPlainBody();
const numAttatchments = message.getAttachments().length;
const numAttatchmentsAsStr = Utilities.formatString( "*%d オリジナルのメールを確認してください*", numAttatchments );
const attatchmentStr = numAttatchments > 0 ? numAttatchmentsAsStr : "0";
const date = formatDate( message.getDate() );
if( !message.isUnread() ) { // Step 3
console.log( Utilities.formatString( "%s is already read", subject ) );
continue;
}
const txts = [ // Step 4
"xxxにメールが届きました.generalに転送します",
Utilities.formatString( "送信日: %s 添付ファイルの数: %s", date, attatchmentStr ),
Utilities.formatString( "*%s*", subject ),
body
];
const txt = txts.join( "\n\n" );
console.log( txt.substr(0, 200) );
message.markRead(); // Step 5
postSlackbot( txt ); // Step 6
}
}
流れとしては以下のような感じです.
Step 1: スクリプトが走るGoogleアカウントのメールボックスを確認
Step 2: 変数query
に従って,取り出すメールを検索
Step 3: 取り出されたメールが既読だったら処理をしない(未読のメールをSlackに投げたいので).
Step 4: メールのデータを適当に整形する
Step 5: メールを既読にする
Step 6: slackに投げる
簡単ですね.
ちなみにこのスクリプトはメールを新着5件までしか検索しません.またメールのスレッドの先頭に対してしか仕事をしません.必要に応じて適当に作り替えてください.
作成したスクリプトはトリガーを使用して,定周期に実行しておきます.サーバにあまり負荷をかけると申し訳ないですし,さほど即時性を求められるものではないので,一時間に一回などでよいのではないでしょうか.
実行結果
ちょっと黒塗りしすぎてわかりにくいですが,自分で作ったslackのアプリ(GroupMail2General
)が***-all
から送られたメールを転送してくれてる感じがわかると思います.
終わりに
とりあえずできて良かったです.
より良い方法を知っている人がいたら教えてください.