LoginSignup
11
6

More than 3 years have passed since last update.

TwitterのDMをGmailを経由してSlackに通知する方法

Posted at

目的

SlackのTwitterアプリで自分の投稿などは通知することができますが、DMを通知することはできませんでした。
そこで、以前はDMをメール通知できることを利用して、Twitter→Gmail→IFTTT→Slackとすることで簡単に実装することができました。しかし、2019年3月末からGmail→IFTTTの連携が使用できなくなり、別の手段を考えることにしました。

概要

  • Twitterのメール通知機能でDMが来たら内容がGmailに届くようにする。
  • Gmailの設定から、DMに関するメールにDMというラベルを付けるようにする。
  • GASを用いてSlackに通知する。
  • 通知した分のメールにはスターを付ける。

実装

Twitterの設定

Twitterの設定>通知>メール通知 から「ダイレクトメッセージ」をONにしておきます。また、設定>アカウントのメールアドレスをGmailにしておきます。

Gmailの設定

Gmailの設定>フィルタとブロック中のアカウント から新しいフィルタを作成します。
条件は、

from: @twitter.com
件名:ダイレクトメッセージ

とし、DMというラベルが付くようにフィルタを更新します。

スクリーンショット (234).png

GASの設定

GASに以下のコードをコピペします。Incoming Webhooksのところは後ほど設定します。

GAS
var FindSubject = 'label:DM';

function getMail(){

  //指定した件名のスレッドを検索して取得 
  var myThreads = GmailApp.search(FindSubject); 
  //スレッドからメールを取得し二次元配列に格納
  var myMessages = GmailApp.getMessagesForThreads(myThreads);


  for(var i in myMessages){
    for(var j in myMessages[i]){

      //スターがないメッセージのみ処理   
      if(!myMessages[i][j].isStarred()){ 
        var strDate = myMessages[i][j].getDate();
        var strSubject = myMessages[i][j].getSubject();
        var oriMessage = myMessages[i][j].getBody();
        var cutMessage  =  oriMessage.match(/1px;font-size:1px;color:#ffffff;"> [\s\S]*?<d>/g);
        var strMessage  =  cutMessage[0].replace('1px;font-size:1px;color:#ffffff;">','').replace('<d>','');
        Logger.log(strMessage);
        Logger.log(strDate);
        Logger.log(strSubject);

        //Slackにメッセージを送信
        sendSlack(strDate,strSubject,strMessage);

        //処理済みのメッセージをスターをつける
        myMessages[i][j].star(); 
      }
    }
  }
}

function sendSlack(strDate,strSubject,strMessage){
  const userName = "DM通知";
  var jsonData = {
      "username": userName,
      "attachments":[
         {
            "fallback":strSubject,
            "pretext":strSubject,
            "color":"#1DA1F2",
            "fields":[
               {
                  "title":strDate,
                  "value":strMessage
               }
            ]
         }
      ]
    }   
  const payload = JSON.stringify(jsonData);
  post(payload);   
}

function post(payload) {
  const postUrl = "https://hooks.slack.com/services/****************"; //Incoming Webhooksの「Webhook URL」を入力
  const options = {
      "method" : "post",
      "contentType" : "application/json",
      "payload" : payload,
  };
  UrlFetchApp.fetch(postUrl, options);
}

トリガー

getMail()関数のトリガーを設定します。間隔はどれぐらいでも大丈夫ですが、あまりにも短いとGASがエラーを吐くので、注意が必要です。自分は即時性を求めていないので、1時間に1回にしています。

Slackの設定

Incoming Webhooksを導入します。設定時に表示されるWebhook URLを上記GASの該当部分にコピペします。表示名やアイコンは好みです。

困ったところ

メールでDMの内容は通知されるのですが、getPlainBody()で取得するとなぜかDMの内容が含まれないので、getBody()でHTML形式で丸々取得しています。そして内容が含まれるところの前後を正規表現で検索し、余分なところを空白に置換することで内容だけを取得するようにしています。

改善点

  • メールのHTML形式が変わったらそれに合わせて正規表現のところを変更しないといけない。
  • DMが来たらすぐに通知するというのはトリガーを変えて頑張ればなんとかなるかもしれない。
11
6
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
11
6