何かやってみるブログ

興味をもったこと、趣味のこと、技術について色々書きます。

[メモ] Slack APIでThreadにメッセージを送る。

概要

www.takayasugiyama.com

SlackでメッセージにハートをつけたらNotionのDBにレコード(ページ)が作成されるようになったものの無事に追加できたのか気になったり、結局追加したレコード(ページ)を探しにNotionに行ったりすることもありそうなので、作成されたページのURLを含むテキストメッセージをスタンプが押さたメッセージに返信するようにする。

実装

chat.postMessageを使ってメッセージを送信するようにした。thread_tsにタイムスタンプを渡せば良い。 api.slack.com

diff --git a/src/index.ts b/src/index.ts
index 58e3c99..724303a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,7 +1,8 @@
 import { Hono } from 'hono'
 import { poweredBy } from 'hono/powered-by'
 import { addItem, NotionAddItemParams } from './notion'
-import { searchStampedMessage, QueryParams } from './slack'
+import { searchStampedMessage, QueryParams, postMessage, PostMessageParams } from './slack'
+import { CreatePageResponse, PageObjectResponse } from '@notionhq/client/build/src/api-endpoints'
 
 const app = new Hono()
 
@@ -28,11 +29,21 @@ app.post('/', async(c) => {
 
   // inser into record to notion database
   const notionParams: NotionAddItemParams = {...searchResult, auth: c.env.NOTION_AUTH, databaseId: c.env.DATABASE_ID}
-  const response = await addItem(notionParams)
+  const response: CreatePageResponse = await addItem(notionParams)
   if(!response){
     throw new Error("レコードの作成に失敗しました。")
   }
 
+  // replay to thread
+  const castResponse = response as PageObjectResponse
+  const text = `レコードを作成しました。 ${castResponse.url}`
+  const postParams: PostMessageParams = { thread_ts: String(ts), channel: channel, text: text }
+  const postSlackResponse = await postMessage(postParams, c.env.SLACK_BOT_TOKEN)
+
+  if(!postSlackResponse){
+    throw new Error("返信に失敗しました。")
+  }
+
   return c.json({ status: 'success' })
 })
 
diff --git a/src/notion.ts b/src/notion.ts
index 1614b08..7998da3 100644
--- a/src/notion.ts
+++ b/src/notion.ts
@@ -1,4 +1,5 @@
 import { Client } from "@notionhq/client"
+import {CreatePageResponse} from'@notionhq/client/build/src/api-endpoints'
 
 export type NotionAddItemParams = {
   title: string
@@ -10,7 +11,7 @@ export type NotionAddItemParams = {
   databaseId: string
 }
 
-export async function addItem({title, movieUrl, imageUrl, girlUrl, timestamp, auth, databaseId}: NotionAddItemParams) : Promise<any> {
+export async function addItem({title, movieUrl, imageUrl, girlUrl, timestamp, auth, databaseId}: NotionAddItemParams) : Promise<CreatePageResponse | null> {
   try {
     const notion = new Client({ auth: auth})
     const response = await notion.pages.create({
diff --git a/src/slack.ts b/src/slack.ts
index 61885e9..68a8204 100644
--- a/src/slack.ts
+++ b/src/slack.ts
@@ -12,7 +12,29 @@ export type SlackSearchResult = {
   timestamp: number
 }
 
-function encodeQueryData(data: QueryParams) {
+export type PostMessageParams = {
+  thread_ts: string
+  channel: string
+  text: string
+}
+
+export async function postMessage(postParams: PostMessageParams, token: string){
+  try {
+    const queryParamsString = encodeQueryData(postParams)
+    const response = await fetch("https://slack.com/api/chat.postMessage?" + queryParamsString, {
+      method: 'POST',
+      headers: {
+        'Authorization': `Bearer ${token}`,
+      },
+    })
+    return response
+  }catch(error){
+    console.log(error)
+    return null
+  }
+}
+
+function encodeQueryData(data: QueryParams | PostMessageParams) {
   const ret = [];
   for (let d in data) {
     ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));

動作確認

スタンプを押すとメッセージでページのURLをbotが返信してくれることを確認した。