🤖

SlackのTimesチャンネル一覧をスレッドでお知らせするbotをつくりました

に公開

こんにちは、TRUSTDOCKのよもぎたです。

前回の記事の派生系で、Timesチャンネルの一覧をお知らせするbotもつくりました。ただ、いきなり一覧を投稿すると長くなるので、一覧自体はスレッドで返信する形で投稿するようにしています。

アプローチ

Google Apps Scriptで定期実行するようにします。
まず一手目で起点となるメッセージを送信するとともに、その応答からリプライをするのに必要な情報を取り出します。それをもとに、二手目でTimesチャンネルの一覧を返信するようにします。

実行結果

自分のワークスペースなので2つしかありませんが、こんな感じになります。

botの実行結果

実装

Slackアプリの準備

前回の記事同様、こちらの私の投稿を参考にしました。
アプリに付与した権限も前回の記事と同じです。

いざ実装

今回もmain()から各関数を呼び出すスタイルです。

main()

function main() {

  // SlackアプリのOAuth Tokenを代入します
  const slack_oauth_token = 'xoxb-deafbeef...';

  // メッセージ送信先のチャンネルのIDを代入します
  // いまは自分のTimesチャンネルのIDを設定しています
  const slack_dest_channel_id = 'C...';

  // すべてのTimesチャンネルを取得します
  let all_times_channels = get_all_times_channels(slack_oauth_token);

  // メッセージを送信します
  post_all_channels(slack_oauth_token, slack_dest_channel_id, all_times_channels);
}

get_all_times_channels()

function get_all_times_channels(slack_oauth_token){

  // SlackのConversations.list APIのURLを代入します
  const slack_conversations_api_url = 'https://slack.com/api/conversations.list?exclude_archived=true&limit=1000';

  // ヘッダとオプションを代入します
  const headers = {'Authorization': 'Bearer ' + slack_oauth_token};
  const options = {'headers': headers};

  // チャンネル一覧を取得します
  // この時点ではTimesチャンネル以外のチャンネルも含まれています
  const channels = JSON.parse(UrlFetchApp.fetch(slack_conversations_api_url, options).toString()).channels;

  // Timesチャンネルを抽出して格納する配列を宣言します
  let times_channels = [];

  // 取得した全チャンネルからTimesチャンネルを抽出して
  // チャンネルのIDと作成者を配列に格納します
  channels.forEach((channel) =>
  {
    if(channel.name.match(/^z-times-/)){
      times_channels.push([channel.id, channel.creator]);
    }
  }
  )

  // Timesチャンネルの一覧を返します
  return times_channels;
}

post_all_channels()

function post_all_channels(slack_oauth_token, slack_dest_channel_id, times_channels){
  // SlackのChat.postMessage APIのURLを代入します
  const slack_post_message_api = 'https://slack.com/api/chat.postMessage';

  // 最初に投稿する短い文章を代入します
  const first_message = 'いまあるTimesチャンネルの一覧をスレッドでお知らせします。';

  // 返信で返すTimesチャンネル一覧の冒頭部分を代入します
  let second_message = 'いまあるTimesチャンネルの一覧です\n\n';

  // Timesチャンネル一覧をもとに、返信で返すメッセージを組み立てます
  times_channels.forEach((channel) =>
  {
    second_message = second_message + get_user_displayname(slack_oauth_token, channel[1]) + 'さんの <#' + channel[0] + '>\n';
  }
  )

  // 最初のメッセージ送信に必要な情報を組み立てていきます
  const headers = {'Authorization': 'Bearer ' + slack_oauth_token, 'Content-types': 'application/json; charset=UTF-8'};
  let payload = {'channel': slack_dest_channel_id, 'text': first_message};
  let options = {'method': 'POST', 'headers': headers, 'payload': payload};

  // 最初のメッセージを送信し、レスポンスをJSONで取得します
  let first_response = JSON.parse(UrlFetchApp.fetch(slack_post_message_api, options).getContentText());

  // 返信先の指定で必要な情報(おそらくTimeStamp)を取り出します
  let first_message_ts = first_response.ts;

  // 返信に必要な情報を組み立てていきます
  payload = {'channel': slack_dest_channel_id, 'text': second_message, 'thread_ts': first_message_ts};
  options = {'method': 'POST', 'headers': headers, 'payload': payload};

  // 返信でTimesチャンネル一覧を送信します。
  UrlFetchApp.fetch(slack_post_message_api, options);

  // この関数は戻り値を返しません

}

get_user_displayname()

これは前回の記事の同名の関数をそのまま流用しています。

最後に

これは、新しくご入社頂いた方向け、ということと、前につくったモノを発展させる、ということを意識して作りました。

やっぱりコードを書くのは楽しいですね。

最後までお読みいただきありがとうございました。

TRUSTDOCK テックブログ

Discussion