TECH

SlackでランダムBOTを作る【初心者向け】

SlackでランダムBOTを作る [Slack × GAS]

Google App Script(GAS)を使ってSlackで投稿したワードからランダムに選んで投稿してくれるBOTを作成します。

BOTに対してランダムで選んでほしい単語を送るのでメンションじゃなくても、好きな単語を送るとその中からランダムなモノを選んで、同じスレッド内で返信してくれます。

完成イメージ

このようにrandom: の後ろにランダムで選びたい単語やメンションを空白区切りで書いてあげることで、スレッド内にランダムで選ばればモノがBOTから投稿されます。

実装イメージ

上記のようなBOTを作成したい場合、このような実装のイメージになります。

  • 特定のチャンネルに投稿されたら検知したい
  • その投稿文の中にrandom: があればランダム処理対象にしたい
  • 空白区切りで単語を分割して、ランダムに抽出したい
  • ランダムに1つ選び終わったら、投稿されたスレッドに結果を返信したい

やり方

SlackのAppを作成

まずはSlackのApp(BOT)を作りましょう。

ここで作成するApp(BOT)は以下の役割を果たしてくれます。

Slack Appの役割
  • BOTとして自動投稿してくれる
  • 特定のイベントが起きたら任意のURL(今回だとGAS)にリクエストできる

他にも色々とできることはありますが、今回重要になってくるSlackAppの機能はこの辺りです。

作成するのは簡単で、SlackAppのトップページ(https://api.slack.com/apps)から直ぐに作ることができます。

①「Create New App」をクリックするとモーダルが表示される(下記画像の状態)
②「From scratch」を選択

③「App Name」に好きな名前を入力してBOTに名前をつける
④「Pick a workspace to develop your app in」で自分の参加しているワークスペースが表示されるので、BOTを導入したいワークスペースを選択
⑤ ここまでできたら「Create App」をクリックしてApp作成完了!

SlackAppがチャンネルに投稿できるようにする

SlackAppが出来たら、実際にAppから特定のチャンネルへ投稿できるようにします。
少し難しい言葉で言うと、Webhookを設定します。

Webhookについて詳しく知りたい方はこのあたりを参考にしてみてください

Webhookとは?
https://qiita.com/soarflat/items/ed970f6dc59b2ab76169

Webhookの設定

先ほど作成したAppのページのIncoming Webhooksから「Add New Webhook to Workspace」を選択します。

ランダムBotを追加したいチャンネルを選択。

無事許可できたら、許可しチャンネルへ投稿できるURLが生成されます。
GASでランダムに選んだ結果をこのURLに向けて送ることで、Slack上で結果を投稿することができるようになります。

なのでこのWebhook URLは後で使うのでコピーするか、いつでもコピーできる状態にしておいてください。
※ URLの値は見えないようにしています

実際にこのURLへリクエストを送ってみるとこんな感じ。

curl -X POST -H 'Content-type: application/json' --data '{"text":"Webhook URLで投稿してみましょう!"}' https://hooks.slack.com/services/<チャンネルID>/<それぞれの値>

GoogleAppScript(GAS)の作成

今度は、実際にランダムで選ぶロジックをGASで作って行きます。

GASの役割
  • Slack Appからリクエストされた情報を処理する
  • Slack上で入力された文字列を空白ごとに分割し、ランダムに選ぶ
  • 選び終わったらSlackへ結果を返す

プロジェクト作成

GASのトップページから新しいプロジェクトを作成します。

コードを追加

このコードでSlackで入力された文字をランダムに選んでSlackへ返しています
詳しく知りたい方はコードにコメントを記載しているので、その辺りを参考にしてください。

Slackでこのような入力がされることを想定しています。

random: @Aさん @Bさん @Cさん @Dさん

プロジェクト作成して開いたエディタに以下のコードをコピペしてください。

function doPost(e) {
  
  // 分割文字
  const SEPARATOR = /\s+/ 
  // この文字列が含まれていたらランダムを実行する
  const PREFIX = "random: "
  // スクリプトプロパティからURLを取得
  const scriptProperties = PropertiesService.getScriptProperties()
  const WEBHOOK_URL = scriptProperties.getProperty('WEBHOOK_URL')
  
  var result = ""
  var ts = ""
  
  // 実行用にnullの場合はSlack APIの仕様をスキップ
  if(e != null) {
    // 疎通確認
    var params = JSON.parse(e.postData.getDataAsString())
    Logger.log(params)
    if('challenge' in params){
      return ContentService.createTextOutput(params.challenge)
    }
    
    // Botの投稿に反応しないように修正
    if('subtype' in params.event) {
      return
    }
    
    // 入力文字列があるか確認
    if('text' in params.event) {
      // 入力文字列を取得
      let inputText = params.event.text
      
      // "random: "が含まれているか確認
      if ( inputText.indexOf(PREFIX) != -1) {
        // PREFIXを抜いてSEPARATORで分割
        let targetList = params.event.text.replace(PREFIX, "").split(SEPARATOR)
        
        // リストサイズ内でランダムな値を決める
        var random = Math.floor(Math.random() * targetList.length)
        
        result = targetList[random]
        ts = params.event.ts
      } else {
        // "random: "が含まれていなければ何もせず終了
        return
      }
    }
    
    // リクエスト内容を整形
    var options = {
      "method" : "post",
      "contentType" : "application/json",
      "payload" : JSON.stringify(
        {
          "text" : result,
          "thread_ts" : ts
        }
      )
    }
      
    // WEBHOOK_URLがあれば投稿
    if (WEBHOOK_URL === null) {
      // URLが設定されていなければ何もしない
      Logger.log("スクリプトプロパティのWEBHOOK_URLが設定されていません")
    } else {
      UrlFetchApp.fetch(WEBHOOK_URL, options);
    }
  }

}

入力後はこのようになると思います。
①と②は必須ではありませんが、設定することをお勧めします。

スクリプト プロパティの設定

上記のコードはSlackに投稿できるWebhook URLをスクリプト プロパティから取得するようにしています。(コードの9行目)
なので、スクリプト プロパティに先ほどSlack App画面で発行したWebhook URLを設定してあげます。

① 左側にあるメニューから歯車マークの「プロジェクト設定」を開く
② プロジェクト設定画面の一番下にあるスクリプト プロパティからプロパティ名「WEBHOOK_URL」、値にWebhook URLを入力する

デプロイ

ここまで設定できたら、デプロイしてアプリケーションにしてみましょう!

① 右上の「デプロイ」をクリックしたら3つ選択肢が出てくるので「新しいデプロイ」を選択
② 「デプロイタイプを選択してくだと」と出てくるので歯車マークから「ウェブアプリ」を選択
③ 「アクセスできるユーザー」を「全員」にしてSlackからアクセスできるように
④ ここまでできたら「デプロイ」をクリックして完了!

ウェブアプリ URLが作成されるのでコピーしておく。
ここのURLへリクエストするとさっきのコードが実行されるので、今度はSlackからここへリクエストする設定を追加してあげます。

Slackで投稿されたらGASへリクエストする

GASでランダムに選んでくれるアプリケーションが完成したので、
Slack Appで特定のチャンネルへ投稿されたら、GASを呼び出してあげるようにします。

Event Subscriptionsの設定

これを設定すると、Appが許可されたチャンネルで特定のイベント(メッセージが投稿されたら、ファイルが作られたらなど)が起きると、意図したURLへリクエストを送れるようになります。

① 左側のメニューから「Event Subscriptions」を選択
② 右上のトグルを「Off」から「On」へ
③ 「Request URL」にさっき作成したGASのアプリケーション URLを入力
④ 「Subscribe to bot events」で「message.channels」(検知したいイベント)を選択
⑤ ④までできたら「Save Chanes」から設定保存!

Appをチャンネルに追加

さっき設定したイベントを検知するにはApp(Bot)がチャンネルに入っている必要があります

なので追加してあげましょう。
私はいつもメンション付けてチャンネルに入れてますが、好きな方法で大丈夫です。

これでやる事は以上です!お疲れ様でした!

動作確認してみる

今日の夜ご飯をランダムで決めてみようと思います。

random: うどん そば ラーメン カレー つけ麺

ちゃんと同じスレッド内で「つけ麺」が選ばれたことが確認できました。

ちなみに同じスレッド内で再度ランダムで選ぶこともできます。

最後に

今回はGASを使ってSlackをちょこっと便利にする技を紹介しました。

Slackでこんなことやってみたいとかあれば是非コメントなどで教えて頂けると助かります!

MATTSU