LoginSignup
1
0

More than 1 year has passed since last update.

GAS(Google App Script)を使ってSlackのbotを作成してみる

Last updated at Posted at 2023-03-14

はじめに

Google App Scriptとスプレッドシートを連携してSlackのbotを作成したので、
自分の備忘録も兼ねてどういうことをしたのかをまとめた。

前提/作りたかったbotの概要

以前は社内のチャットで毎朝以下の手順を実施していた。

  1. 会社近くのお弁当屋さんをリストアップし、メッセージを投稿(「どこのお店にしましょう?」的なやつ)
  2. お昼前にそのメッセージに押されたスタンプの数を集計(手動)
  3. 多数決で決定したお店をチャット内で周知

→ 毎朝同じ内容を投稿して、お昼前に人力で集計するのがとてもめんどくさい
  リマインダーを使うにしても、スタンプの集計が出来ないので機能が不十分
→ botで出来たらとても素敵

実装した機能

上記を踏まえ、実装した機能としては以下の通り。

① メッセージの投稿
決まった時間に定型文を投稿する機能
集計結果を投稿する機能

② メッセージへのスタンプ押下
①で定型文を投稿すると同時に、メッセージに投票用のスタンプを押す機能
※投票したい人が選択肢のスタンプを探しに行くのがめんどくさいため

③ メッセージに押されたスタンプ数の取得
決まった時間に定型文メッセージに押されたスタンプの数を取得する機能
※今回は取得したスタンプをスプレッドシートで集計するために必要

おおまかな仕組み/シーケンス図

事前準備

必要なもの

・Googleアカウント(GAS、スプレッドシート利用のため)
・Slackのワークスペース権限(bot追加のため)
・やる気

先にしておくこと

slackのアプリ作成

  1. https://api.slack.com/apps の「Create New App」を選択
    ※2つ選択肢が出てくるので、From scratch を選択
    image.png
  2. 作りたいアプリの名前を入力し、追加したいワークスペースを選択
    image.png
  3. 「Create App」を選択してアプリ自体の作成は完了

アプリの権限周りの設定、ワークスペースへの追加

  1. 「OAuth & Permissions」タブを選択
    image.png

  2. 画面下部にある「Scopes」の「Add an OAuth Scope」を選択し、利用する権限を追加する
    image.png
    今回は以下の権限を追加する。
    「chat: write」...メッセージを投稿する権限
    「reactions: read」...メッセージに追加されたスタンプを読み取る権限
    「reactions: write」...メッセージにスタンプを追加する権限

  3. 「App Home」タブを選択し、「App Display name」の「Edit」を選択する
    image.png

  4. チャンネルに表示される名前と、デフォルトのユーザー名を設定し「Add」する
    image.png

  5. 名前を決めたら「Install App」タブを選択して「Install to Workspace」を選択
    image.png

  6. 以下のような確認画面が出てくるので許可する
    image.png

  7. 以上で権限を設定したアプリの、ワークスペースへの追加は完了

slackのbot用トークンの払い出し

ワークスペースへの追加が完了した状態で再度「Install App」タブを選択すると、
以下のようにbot利用のためのトークンが払い出されているのでコピーしておく
image.png

チャンネルIDの取得

メッセージ送信のときに使うのでコピーしておく(slackアプリから確認可能)
image.png

スプレッドシートのURL

こちらは必要な場合のみ。今回はスプレッドシートと連携したアプリなので必須。

自作アプリ作成

今回はGASでアプリを作成したので、GASでの手順をまとめる。

GASとは

Google App Scriptの略。
Java ScriptをベースにGoogleが提供している開発言語。
スプレッドシートやGoogle Map、Gmailなどのツールと連携が可能。

アプリ作成

  1. https://script.google.com/home のページから新規でプロジェクトを追加する
  2. javascriptでコードを書く
     a. 例)メッセージの送信関数
postMessage
function postMessage(message) {
  // slack api のメッセージ送信機能
  const url        = 'https://slack.com/api/chat.postMessage';
  const method     = 'post';

  const payload = {
    // 払い出しておいたbotのトークン
    'token'      : BOT_USER_OAUTH_TOKEN,
    // slackチャンネルのID
    'channel'    : CHANNEL_ID,
    'text'       : message,
  };
  const params = {
    'method' : method,
    'payload' : payload
  };

  // メッセージ送信APIの呼び出し
  const responseJson = UrlFetchApp.fetch(url, params);
  // メッセージのタイムスタンプ取得のために、レスポンスを返却しておく
  return JSON.parse(responseJson.getContentText());
}

 b. 例)リアクションの追加関数

addReaction
// timeStampはリアクションを追加したいメッセージの送信時タイムスタンプ
// reactionListはリアクションの文字列リスト 例)「:smile:」みたいなやつ
function addReaction(timeStamp, reactionList){
  // slack api のリアクション追加機能
  const url = 'https://slack.com/api/reactions.add?' + '&name=';
  const method = 'post';

  const payload = {
    // 払い出しておいたbotのトークン
    'token'      : BOT_USER_OAUTH_TOKEN,
    // slackチャンネルのID
    'channel' : CHANNEL_ID,
    'timestamp' : timeStamp,
  };
  const params = {
    'method': method,
    'payload': payload
  };

  // リストからリアクション文字列を取り出してループ
  for (const reaction of reactionList) {
    // urlにリアクション文字列を追加して、slack api 呼び出し
    UrlFetchApp.fetch(url + reaction, params);
    // 感覚をおかずにスタンプを送信させると、順番がバグることがあるため1秒待つ
    Utilities.sleep(1000);
  }
}

 c. 例)リアクションの取得関数

getReactions
// timeStampはリアクションを追加したいメッセージの送信時タイムスタンプ
function getReactions(timestamp){
  // slack api のリアクション取得機能
  const url = "https://slack.com/api/reactions.get";
  const method = 'get';
  const payload = {
    // 払い出しておいたbotのトークン
    'token'      : BOT_USER_OAUTH_TOKEN,
    // slackチャンネルのID
    'channel' : CHANNEL_ID,
    'timestamp' : timestamp,
  };
  const params = {
    'method': method,
    'payload': payload
  };

  // リアクション取得apiを呼び出してレスポンス取得
  const response = UrlFetchApp.fetch(url, params);
  // レスポンスをJSON形式にパース
  const responseJson = JSON.parse(response.getContentText());

  // パースしたレスポンスからリアクション郡を返却
  return responseJson.message.reactions;
}

 d. 例)スプレッドシートとの連携

// SPREADSHEET_URLはスプレッドシートのURL
// sheetNameはスプレッドシートのシート名
const sheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL).getSheetByName(sheetName);

// 書き込み
// この場合はシートのE2に値を設定する
const sheetValue = sheet.getRange("E2").setValue()

// 読み込み
// この場合はシートのE2の値を取得する
const sheetValue = sheet.getRange("E2").getValue()

3. 上記もろもろを組み合わせて、やりたい機能を実装する
あまりにもコードが乱雑だったのでコードは割愛
実際にできたものがこちら。
image.png
リアクションもちゃんとbotが押してくれてる。
image.png

アプリにトリガーを追加

GASではトリガーを設定して、特定条件で命令を実行させることが可能。
image.png
「トリガーを追加」を選択すると以下のようなダイアログが出てくる。
image.png
今回は朝の時間帯に定型文を送信したいため、日付ベースのタイマーを使って
朝の8~9時のどこかで定型文送信イベントを発火させる。
同様にリアクションの集計結果を取得するイベントをお昼前に発火させて、結果を送信させれば完了。

まとめ

やってみると技術的な敷居も高くなかったし、
無料で作成出来るので(一番大事)「試しになんかやってみよう」の入門として最適だった。
他にもbotに権限を追加すればもっとやれることもあるので、
暇なときに機能追加とかしても面白いかもしれない。

後日談
スタンプでの集計ではなく、指名された誰かが日替わりで店舗を決める制度になったことと、
作成完了時点で作成者のやる気とデプロイする気力がなかったことから、このbotが実用化されることはなかった。

1
0
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
1
0