Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

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

目的

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が来たらすぐに通知するというのはトリガーを変えて頑張ればなんとかなるかもしれない。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
5
Help us understand the problem. What are the problem?