ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。エンジニアの日々の開発などの記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

【GAS】SlackのEvent APIを用いて、投稿などをGASで受け取って処理してみよう!

Slackのボット作成でGoogle Apps Script(以下、GAS)を利用することで、サーバ費が不要になり、無料でボット作成を行うことができます。 今回の記事では、Event Subscriptionsを用いて、Slackへの投稿をトリガーとして、GASでなにか処理を行うことを目指します。

Event Subscriptions

今回使用するEvent APIのEvent Subscriptionsは、Slackへの投稿やリアクションなどのコマンドがあった場合、用意したサーバなどにSlackからリクエストが飛んできて、ほぼリアルタイムに返信などその投稿などに対しての処理を行うことができます。

api.slack.com

今回は、これのサーバ側をGASで行いたいと思います。

GAS側でサーバを用意しよう

Slackのアプリボットを作成する前にGAS側の一時的なプログラムを用意しちゃいます。

GASを開いて、以下のようなプログラムを書きましょう。

function doPost(e){
  var params = JSON.parse(e.postData.getDataAsString());
  return ContentService.createTextOutput(params.challenge);
}

こちらをウェブアプリケーションとして公開しておきます。

ウェブアプリケーションとして公開する方法については以下の記事に詳細をまとめておきましたので、こちらを参考にしてみてください。

www.pnkts.net

ここで公開されたURL(Current web app URLのところ)をメモしておきましょう。

ボットアプリを作成してみよう

まずはSlack上でアプリを作成してみたいと思います。 以下のリンクからSlackのアプリを作成することができます。

api.slack.com

App NameDevelopment Slack Workspaceを入力してCreate Appをクリックします。

f:id:ponkotsu0605:20200328173318p:plain

今回はテキトーにごみという名前で作成しています。

作成すると以下のようなページが開かれると思います。

f:id:ponkotsu0605:20200328173431p:plain

Add features and functionalityからEvent Subscriptionsを選択します。

f:id:ponkotsu0605:20200328173548p:plain

Offになっていると思うので、Onにしましょう。

Onにすると以下のように入力項目が表示されるかと思います。

f:id:ponkotsu0605:20200328174148p:plain

Request URLのところにGAS側で発行されたURLを入力します。

もし、入力が間違えていたり、上のプログラムが間違っていた場合に、例えば以下のようなエラーが表示されるかと思います。

f:id:ponkotsu0605:20200328174334p:plain

Your request URL didn’t respond with the correct challenge value. Update your URL to receive a new request and value.

アプリボットを作成するときに、challengeパラメータをちゃんと返すようなAPIを作成しないとボットの作成ができないようです。

うまくいけば以下のように、Verifiedという文字が表示されるかと思います。

f:id:ponkotsu0605:20200328174543p:plain

Subscribe to events on behalf of usersの項目にmessage.channelsを追加します。そして、右下のSave Changesをクリックします。

f:id:ponkotsu0605:20200328175233p:plain

最後に左のサイドメニューのInstall Appをクリックして、アプリをインストールします。 以下のInstall App to Your TeamからInstall App to Workspaceをクリックするとインストールできます。

f:id:ponkotsu0605:20200328175400p:plain

アクセスの許可の確認がでると思うので、許可を行います。

これで完了です。

アクセスを確認してみましょう。

GASのプログラムを以下のようにログを出力するように変更してみましょう。

function doPost(e){
  var params = JSON.parse(e.postData.getDataAsString());
  console.log(e.postData.getDataAsString())
  
  return ContentService.createTextOutput(params.challenge);
}

console.logでのログの確認については以下の記事にまとめてあるので参考にしてみてください。

www.pnkts.net

このようにすることでStackdriver LoggingでSlackから飛んでくるリクエストのパラメータを確認することができます。

このSlackボットを利用した例

さて、ここの項目は参考程度に見ていただければと思うのですが、このAPIを応用して作成したボットの例を紹介したいと思います。

ざっくりとした概要

以前の記事で、Feedlyの人気の記事・ホットな話題の記事をSlackに投稿することで、情報のキャッチアップを素早く行う方法を紹介しました。

www.pnkts.net

こちらのボットの投稿に対してスレッドで返信をしたら、その返信内容でTwitterでツイートしてくれる、というものです。

ツイートについては、以下の記事で紹介した方法を用いて即座にツイートさせることを実現しています。

www.pnkts.net

例えば、以下のような投稿に返信をしてみます。

f:id:ponkotsu0605:20200328180857p:plain

これに対して、即座にツイッターに投稿されます。

このように、今流行っているコロナウィルスのニュース記事に対して、スレッドで意見を書くとその内容をツイートしてくれてますね。

GASプログラム

今回作成したのは以下のようなソースコードになります。

function doPost(e) {
  console.log(e.postData.getDataAsString())
  var data = JSON.parse(e.postData.getDataAsString())
  console.log(data)
  console.log(data.api_app_id)
  var apiAppId = data.api_app_id;
  if (apiAppId != 'A0105T5L3SP') return;
  //  api_app_id: 'A0105T5L3SP'
  console.log(data.event)
  var user = data.event.user;
  if (user != 'U6TJP8Q49') return;
  console.log(data.event.user)
  
  var threadTs = data.event.thread_ts;
  console.log(data.event.thread_ts)
  
  var channel = data.event.channel;
  console.log(channel)
  
  var text = data.event.text;
  console.log(text)
  
  var botData = getFromSlack(channel, threadTs);
  console.log(botData.messages[0].bot_id)
  
  var botId = botData.messages[0].bot_id
  if (botId != 'BL7HFTKQE') return;
  
  console.log(botData.messages[0].attachments[0].text)
  var botText = botData.messages[0].attachments[0].text;
  
  var reg = new RegExp("\<((https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+))\>");
//  Logger.log(botText.replace(reg,"\n$1"));
  
  tweetByIftttMail(text + '\n\n' + botText.replace(reg,"\n$1"));
  
  var params = JSON.parse(e.postData.getDataAsString());
  return ContentService.createTextOutput(params.challenge);
}

function getFromSlack(channel, threadTs) {
  var token = 'xoxp-0000000000-00000000000-000000000000-00000000000000000000000000000'
  var url = 'https://slack.com/api/channels.replies?token=' + token + '&channel=' + channel + '&thread_ts=' + threadTs;
  var response = JSON.parse(UrlFetchApp.fetch(url).getContentText());
  Logger.log(response. messages[0]. attachments[0])
  return response;
  return response. messages[0]. attachments[0]
}

function tweetByIftttMail(text) {
  MailApp.sendEmail('trigger@applet.ifttt.com', '件名', text)
}

ちょっと汚いですが、スレッドに対して投稿されたかを独自のバリデーションでチェックして、スレッドの元の投稿のテキスト内容を取得して、それを引用しながら、自分が投稿した文字と結合してメール送信しているような仕組みになっています。

さいごに

今回はSlackのEvent APIを利用する方法と、その利用例を紹介しました。 自分の場合は、このようなボットを導入したことで、技術・情報・流行りのキャッチアップをしつつ、それについての発信をSlackのスレッドに返信するだけと手軽に行えるようになりました。 そのため、最近急にツイート数が増えたかもしれませんが、これはこういった理由です。 今後もいろんなAPIを利用したりして、いろんなボットを作ってみたいと思います。

お問い合わせプライバシーポリシー制作物