LoginSignup
2
2

More than 1 year has passed since last update.

[GAS]複数のチャンネルに投稿できるSlack Bot アプリが欲しい!

Last updated at Posted at 2022-04-22

はじめに

私は社内で活性化委員会という会社を盛り上げるというチームみたいな活動に参加しています。
コロナ禍の長期化により、リモートワークすることが増え他部署との関わりが減ってきました。:sob:
この問題を解決すべく、コロナ禍でも無理なく行える社内交流イベントをすることにしました。
そのイベントでは複数のSlackチャンネルに投稿できるBotが必要になり、GASを使用したBotアプリを作ったのでメモとして残そうと思います!
もし読者の皆さんが社内の活性化等で何かしらのBotを作りたいなどあれば本記事が参考になれば幸いです!

本記事の対象者

  • 社内の活性化のイベントでSlack(スレットも含む)投稿できるBotを使いたい方
  • 1つ以上のチェンネルに投稿可能なGASのソースコードが欲しい方
    • 本記事では複数チャンネル投稿用でtoken を使用して実装していますが、1チャンネルでも良い場合はWebHook用の実装に変えてもSlack 投稿の仕様(複数チャンネルに投稿可以外)の条件を満たすことが可能です
  • GASを使ってみたい(Slack 投稿の仕様の機能をGASで作ってみたい)方

Slack 投稿の仕様

  • 複数のチャンネルに投稿可
    • プライベートチャンネル、パブリックチャンネルに投稿可
  • スレットに返信可
  • 投稿するときに投稿詳細を変更可(例:弊社では架空のキャラを複数用意し投稿する必要があったため)
    • 投稿内容
    • 名前(name)
    • アイコン(icon)

作り方

  1. ボットユーザーを作成する
  • https://slack.com/services/new/bot にアクセスする
  • ユーザー名を記入しボットインテグレーションからボットユーザーを作成する
    • (私はbot-app の名前で作成しました)

スクリーンショット 2022-04-04 12.55.07.png

2. (1)で作成したボットユーザーのインテグレーションの設定 > API トークン からtoken(xoxb-から始まるもの)を取得する

  • token は(4)の実装時に必要になる

Cursor_と_Bots___Slack_App_ディレクトリ.png

3. Googleスプレットシートで投稿フォームを作成する

  • 以下画像のように投稿フォームを追加してください
    • 以下セルは(4)の実装でSlackに投稿するためのOption で使用するため必ず用意する
      • 2C: 投稿内容
      • 3C: 投稿チャンネル
      • 4C: 名前(name)
      • 5C: アイコン(icon)
      • 6C: スレットID
  • 1C は(4)の実装で投稿内容、投稿チャンネル、名前(name)、アイコン(icon)を必須として実装しているため、メモとして記載しています。(こちらは適宜変更/未記入でも大丈夫です)

スクリーンショット 2022-04-04 13.13.23.png

4. GAS に以下ソースコードを追加する

  • token を設定している箇所に(2)で取得したtoken と入れ替える
function validateParams(params) {
  // 必須項目のvalidation
  if (!params.text.length || !params.channel.length ||!params.username.length || !params.icon_emoji.length) {
    Browser.msgBox("投稿内容、投稿チャンネル、名前(name)、アイコン(icon)は必須です。");
    return true
  }
  return false
}

function setParams(sheet) {
  return {
    "text" : sheet.getRange(2, 3).getValue(),
    "channel": sheet.getRange(3, 3).getValue(),
    "username" : sheet.getRange(4, 3).getValue(),
    "icon_emoji": sheet.getRange(5, 3).getValue().trim(), // Slackから絵文字をコピーしてきたときに文末に空白文字が入るためtrim()で文字列前後の空白を削除
    "thread_ts": sheet.getRange(6, 3).getValue(),
  }
}

function sheet01() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet();
  const targetSeet = sheet.getSheetByName("sheet01");
  const params = setParams(targetSeet);
  if (validateParams(params)) return;

  const alertMessage = params.thread_ts ? "スレットに投稿しますか?" : "Slackに投稿しますか?"
  const checkAlert = Browser.msgBox(alertMessage, Browser.Buttons.OK_CANCEL);
  if (checkAlert !== "ok") {
    return Browser.msgBox("送信をキャンセルしました。");
  }

  pushSlack(JSON.stringify(params), targetSeet);
}

function pushSlack(params, targetSeet) {
  const token = "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxx";

  // UrlFetchApp.fetch docs: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
  const res = UrlFetchApp.fetch(
    "https://slack.com/api/chat.postMessage",
    {
      "method" : "post",
      "contentType" : "application/json",
      "headers": { "Authorization": `Bearer ${token}` },
      "payload" : params
    }
  );
  if (!params.thread_ts) {
    json = JSON.parse(res.getContentText());
    targetSeet.getRange(6, 3).setValue(json.ts);
  }
  return Browser.msgBox("送信しました。");
}

5. 送信ボタンにSlackAPI 実行スクリプトを割り当てる

  • 右クリックすると三点マークが出るので、そこからスクリプトの割り当てを選択しsheet01 と記入してください(sheet01はGoogleスプレットシートのシート名、GASのsheet01関数名を統一する)

Cursor_と_Qiita_投稿用_bot_-_Google_スプレッドシート.png

6. 完成(投稿してみる)

  • 以下のように設定する
    • 投稿チャンネル: 投稿したいチャンネル名を記載する (Slack > チャンネル名を右クリック > 名前をコピー から取得)
      • パブリックチャンネルは#がつき、プライベートチェンネルは #がつかない
      • ※注意点としてプライベートチャンネルに投稿したい場合は(1)で追加したボットユーザーをチャンネルに招待する必要がある
    • 名前(name): 投稿したい名前を設定
    • アイコン(icon): Slackで使用されているアイコン画像をコピペしたもの(文頭、文末にコロン付き文字列)

スクリーンショット 2022-04-04 13.41.34.png

  • 設定後に送信ボタンを押す
    • Slackに送信しますかのポップアップメッセージが出るのではいを選択で投稿
  • 投稿結果は以下の画像のようにSlackに表示される

スクリーンショット 2022-04-04 13.49.06.png

  • Slackへ投稿後、投稿した内容のスレットIDをGoogleスプレットシートの6Cに追加するように(4)で実装しているので、スレットIDが追加された状態で送信ボタンを押すとスレットに返信ができる

スクリーンショット 2022-04-04 13.49.52.png

終わりに

久しぶりにGAS に触れましたが、V8からconst, let が使えるようになっているんですね...! (知らなかった:sweat_smile:)

現在の実装ではエラーハンドリング周りは細かく実装していないです...orz

例.

  • 存在しないチャンネル名を設定して投稿した場合
    • Slackアカウントの全てのチャンネルをチェック
  • チャンネル内のスレットIDのチェック
    • チャンネル内の全て/数投稿前のスレットIDをチェック

ここまでBotの実装する必要はないと思いますが...今度機会があれば作ってみようと思います:muscle:

参考ドキュメント

[その他]投稿に関する参考ドキュメント

投稿するときにユーザーにメンションをつけたい時、@hereや、ユーザーにメンションをつけたい時があると思います。その場合のテキストの記載のドキュメントを以下にリンクを載せていますので、興味があれがご参考ください :raised_hands:

スレットIDの取得の仕方
(スレットのみに投稿したい場合や、スレットIDがわからなくなった場合にご参考ください)

  • その他 -> リンクをコピー -> コピーしたリンクにthread_ts= があるので =から&までの数字がスレットIDです
    • ex) https://channel-nam-co.slack.com/archives/CXXXXXXXXX/p1650592743917399?thread_ts=1650592674.494669&cid=C02GV6417M01650592674.494669がスレットIDになります

Slack___slack-batch___miyagi.png

2
2
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
2
2