はじめに
弊社ではエンジニア・デザイナーを中心にSlackで分報(timesチャンネル)作成しています。
今回は「timesチャンネルの集約チャンネルがあったらいいなぁ 」
という要望をいただいたので、作ってみました。
実装したこと
- timesチャンネルに投稿された内容を、times_allチャンネルに自動投稿する
参考記事
以下の記事を参考にさせていただきました。ありがとうございます。
Slackの分報を社内Twitterに!皆の分報を一つのチャネルに集約するSlackボットを作ってみた
Slackのチャンネルのメッセージを1つのチャンネルに集約するSlackボットを作ってみた
実際の画面
times_allチャンネルに投稿されるまでの流れ
- timesチャンネルに新しいメッセージが投稿される
- GASでメッセージのパーマリンクURLを取得
- SlackのAPIにPOSTリクエストを送信
- times_allに投稿される
Slackアプリの作成と設定
https://api.slack.com/apps からアプリを作成します。
OAuth & PermissionsのScopesで以下の項目を設定します。
- channels:history
- channels:read
- chat:write
- incoming-webhook
同ページ内のBot User OAuth Token(「xoxb-」から始まる)は後で使用します。
Spreadsheetの作成とGASの開発
Google Spreadsheetを作成します。
拡張機能のApps Scriptを選択し、以下のコードを記述します。
function doPost(e) {
const params = JSON.parse(e.postData.contents);
// SlackからのURL検証リクエストの確認
if (params.type === 'url_verification') {
return ContentService.createTextOutput(params.challenge); // challengeパラメータをそのまま返す
}
// メッセージがtimes_userN
ameチャンネルから来た場合に処理を実行
const event = params.event;
if (event.type === 'message' && event.channel && event.text) {
// 複数のtimes_userNameチャンネルIDを配列に格納
const TIMES_USERNAME_CHANNEL_IDS = [
'channelId', // times_userName1
'channelId', // times_userName2
'channelId', // times_userName3
// 必要なだけチャンネルIDを追加
];
const TIMES_ALL_CHANNEL_ID = 'channelId'; // times_all チャンネルのID
// 「投稿元のチャンネルがtimes_userNameチャンネル」かつ「ワークフローやbotメッセージではない」場合に処理を実行
if (TIMES_USERNAME_CHANNEL_IDS.includes(event.channel) && event.subtype !== 'bot_message' && event.subtype !== 'workflow_run') {
// ワークスペース名を含めたSlackメッセージのパーマリンクURL
const workspace = 'companyName'; // Slackワークスペース名
const messageUrl = `https://${workspace}.slack.com/archives/${event.channel}/p${String(event.ts).replace('.', '')}`;
// messageUrlが正しく作成されたか確認
Logger.log('Generated message URL: ' + messageUrl);
postToTimesAll(messageUrl, TIMES_ALL_CHANNEL_ID);
} else {
Logger.log('Excluded message: ' + event.text);
}
}
return ContentService.createTextOutput('OK');
}
const SLACK_API_TOKEN = 'xoxb-hogehoge'; // SlackのBot User OAuth Token
// Slackのメッセージをtimes_allに送信する関数
function postToTimesAll(messageUrl, channelId) {
const payload = {
channel: channelId,
text: `新しい投稿です: <${messageUrl}|投稿を見る>` // パーマリンク形式で投稿
};
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': 'Bearer ' + SLACK_API_TOKEN
},
payload: JSON.stringify(payload)
};
try {
// SlackのAPIにPOSTリクエストを送信
const response = UrlFetchApp.fetch('https://slack.com/api/chat.postMessage', options);
const jsonResponse = JSON.parse(response.getContentText());
if (!jsonResponse.ok) {
Logger.log('Error posting to Slack: ' + jsonResponse.error);
}
} catch (error) {
Logger.log('Error in postToTimesAll: ' + error.message);
}
}
GASのプロジェクトをデプロイする
Apps Scriptページのデプロイボタンから新しいデプロイを選択します。
種類は「ウェブアプリ」、アクセスできるユーザーは「全員」を選択します。
ウェブアプリのURLが発行されるのでコピーします。
SlackアプリでEvent Subscriptionsの設定
SlackアプリのEvent Subscriptionsに移動します。
Request URLに先ほどコピーしたURLを貼り付けて、Verifiedが表示されたら成功です。
次にSubscribe to bot eventsで、message.channelsを追加して完了です。
完成
times_allチャンネルには、パーマリンク形式で投稿されます。
(botアイコンはshigureni free illustからお借りしました。可愛い)
誰かがtimesチャンネルに参加したときも自動投稿されてしまうので、
「チャンネルに参加しました」を含むメッセージは除外でもいいかもしれません。
※今回の実装でtimes_allチャンネルに自動投稿されないメッセージの種類
- ワークフローによる投稿
- botメッセージ
- 画像のみの投稿
まとめ
参考記事の内容が私には難しかったので、よりシンプルな方法でチャレンジしてみました。
X(旧:Twitter)感覚で、メンバーのtimesを確認できるので、お気に入りです
これからも社内外の要望を実現できるように、色々な分野で知識を身につけていきます。