LoginSignup
3
2

More than 1 year has passed since last update.

受信したメールをslackのgeneralに自動転送したい.無料で

Last updated at Posted at 2021-06-16

背景

本研究室では昔から使用しているグループメール(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との連携により,メールボックスを確認することも可能だからです.

そのため手続きとしては以下になります.

  1. Slackのボットを作る
  2. Google Apps Scriptを作成,ScriptからSlackボットを通じてメッセージを送る
  3. 上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から送られたメールを転送してくれてる感じがわかると思います.

mail2slack.png

終わりに

とりあえずできて良かったです.

より良い方法を知っている人がいたら教えてください.

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2