slackのAPI chat.postMessage で投稿したメッセージのURLを取得するGAS

※記事投稿後にもっと簡単なやり方があるよ!と教えていただき修正しました(*´▽`人)
(team.infoを使用→chat.getPermalinkを使用)


ご無沙汰しております。
なかなか書くネタが見つからないカインです。

slackのAPI chat.postMessage で投稿したメッセージのURLを取得するスクリプトを作ったので備忘録的に書いていきます。

処理の流れ

  1. chat.postMessage APIでslackへメッセージを投稿
  2. 投稿結果からチャンネルIDタイムスタンプを取得
  3. chat.getPermalink APIでチャンネルIDとタイムスタンプからURLを取得

使用するAPI

  • chat.postMessage
    • メッセージ投稿に使用します。
  • chat.getPermalink
    • チャンネルIDとタイムスタンプからURLを取得するために使用します。

準備

まずはslackアプリとGASを用意します。
GAS作成参考
アプリ作成参考

slackアプリの設定

権限の設定

メニューのOAuth & Permissionsを選択します。

f:id:simple-josys:20220118212943p:plain

Add an OAuth Scopeをクリックして、

  • chat:write

の権限をBotに追加します。

f:id:simple-josys:20220118232540p:plain

権限追加後は、Workspaceへインストールしましょう。

f:id:simple-josys:20220118213256p:plain

インストールしたら、Bot User OAuth Tokenを控えます。

f:id:simple-josys:20220118214105p:plain

また、slackのチャンネルにアプリを追加しておきます。

f:id:simple-josys:20220118220109p:plain

コード全体

GASにコードをコピペします。
botトーク投稿先のチャンネルIDは書き換えてください。

function getSlackUrl(){
  const bot_token = "xoxb-*******************************"; //slackアプリ OAuth & PermissionsのBot User OAuth Access Token
  
  //メッセージを投稿
  const post_channel = "*********"; //投稿先のチャンネルID
  var message_data = "投稿するメッセージの内容(適当)";
  var created_message = createMessage(message_data,bot_token,post_channel); //createMessage関数を呼び出してAPIに必要な情報を整理
  var response = UrlFetchApp.fetch("https://slack.com/api/chat.postMessage", created_message); //メッセージを投稿
  
  //responseをcreateSlackUrl関数へ渡してURLを生成
  var slack_url = createSlackUrl(response,bot_token);
  
  //確認用に生成したURLを投稿してみる
  var message_data = slack_url;
  var created_message = createMessage(message_data,bot_token,post_channel); 
  var response = UrlFetchApp.fetch("https://slack.com/api/chat.postMessage", created_message);
}

//----------------------------------------postMessage作成
function createMessage(message_data,bot_token,channel_id){
  var payload = {
    "token" : bot_token,
    "channel" : channel_id,
    "text" : message_data
  }
  var options = {
    "method" : "POST",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  return options;
}

//----------------------------------------createSlackUrl
function createSlackUrl(response_pm,bot_token){
  var r_pm = JSON.parse(response_pm); //JSONを解析
  var channel = r_pm.channel; //チャンネルIDを抽出
  var ts = r_pm.ts; //タイムスタンプを抽出
  
  var payload = {
    "token" : bot_token,
    "channel" : channel,
    "message_ts" : ts
  }
  var options = {
    "method" : "GET",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  
  //チャンネルIDとタイムスタンプを元に、chat.getPermalink APIでURLを取得する
  var response_ti = UrlFetchApp.fetch("https://slack.com/api/chat.getPermalink", options);
  var slack_url = JSON.parse(response_ti).permalink; //URLを抽出
  
  return slack_url;
}

chat.postMessageのresponseの中身

※一部 *** でボカしています。
channeltsを取り出して使用します。

{
  "ok": true,
  "channel": "C0*******A8",
  "ts": "1642******.****00",
  "message": {
    "bot_id": "B02******NL",
    "type": "message",
    "text": "投稿するメッセージの内容(適当)",
    "user": "U02******HY",
    "ts": "1642******.****00",
    "team": "TR*****F3",
    "bot_profile": {
      "id": "B02******NL",
      "app_id": "A02******CC",
      "name": "get_slack_url",
      "icons": {
        "image_36": "https://a.slack-edge.com/80588/img/plugins/app/bot_36.png",
        "image_48": "https://a.slack-edge.com/80588/img/plugins/app/bot_48.png",
        "image_72": "https://a.slack-edge.com/80588/img/plugins/app/service_72.png"
      },
      "deleted": false,
      "updated": 1642509170,
      "team_id": "TR*****F3"
    }
  }
}

chat.getPermalinkのresponseの中身

permalinkを取り出して使用します。

{
  "ok": true,
  "permalink": "https://s*****t.slack.com/archives/C0*******A8/p1642******.****00",
  "channel": "C0*******A8"
}

functionの説明

getSlackUrl

実行用

createMessage

chat.postMessageメソッドに必要な中身を作る処理

createSlackUrl

chat.postMessageのsuccess responseの中身からURLを作成する処理

実行テスト

function getSlackUrlを実行

f:id:simple-josys:20220118225016p:plain

メッセージが投稿された後、生成したURLが投稿されました!

終わりに

難しいことは特にしていませんが、今日までpostMessageで投稿したものをOutgoing Webhookで拾ってURLを生成するというアホなことをやっていました。
Outgoing Webhookはプライベートチャンネルでは使えませんが、今回作ったものはプライベートチャンネルでも使えますし、何より仕組みそのものがスッキリしました!