👋
【ChatGPT × Slack Bolt】メンションしたら答えてくれるSlack BOTを作ってみた
使ったもの
ここでは Glitch というサードパーティのサービスを使って作業を進めていきます。Glitch はウェブ上で動く IDE で、「リミックス」 (この Remix は GitHub で言う所の clone のようなものと考えてください) することにより元のソースをコピーして新規の自分のプロジェクトとして作業を進めていきます。ブラウザ上で実行できますので、デプロイの必要もありません。
Remix リンク: https://glitch.com/edit/#!/remix/slack-bolt-hello-world引用元: https://api.slack.com/lang/ja-jp/hello-world-bolt#:~:text=と思います。-,ソースコード,-ここでは Glitch
Slack BoltのGlitchでのテンプレートをSlack公式が用意してくれています。
また、Slack Boltのページの「Events API を使ってアプリを作成する」から、今回使うSlackアプリも作成してください。
コード
index.js
const { App } = require('@slack/bolt');
const { Configuration, OpenAIApi, ChatCompletionRequestMessageRoleEnum } = require("openai");
// TODO: .envファイルに、自身のものを設定する。.envファイルをGitで管理しないよう注意。
// OPENAI_API_TOKEN, SLACK_SIGNING_SECRET, SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_BOT_ID
const app = new App({
signingSecret: process.env.SLACK_SIGNING_SECRET,
token: process.env.SLACK_BOT_TOKEN,
appToken: process.env.SLACK_APP_TOKEN,
socketMode: true,
port: process.env.PORT || 3000,
})
app.event("app_mention", async ({ event, client, say }) => {
// スレッドのトップのメッセージであればthread_ts、スレッド中のメッセージであればtsを取得する。
const threadTs = event.thread_ts ? event.thread_ts : event.ts;
try {
// スレッドのメッセージを取得
const threadMessagesResponse = await client.conversations.replies({
channel: event.channel,
ts: threadTs,
});
const threadMessages = threadMessagesResponse.messages
const slackBotId = process.env.SLACK_BOT_ID;
// OpenAI APIに渡すためのメッセージオブジェクトを作成する。
const mentionMessages =
threadMessages.map(message => {
// メンション付きのものだけを抽出する。ここら辺は好み。
if(message.text?.includes(`<@${slackBotId}>`) || message.text?.includes(`<@${message.user}>`)){
const role = message.user === slackBotId ? ChatCompletionRequestMessageRoleEnum.Assistant : ChatCompletionRequestMessageRoleEnum.User
return { role: role, content: message.text }
};
}).filter(e => e) // undefinedを除く
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_TOKEN
});
const openai = new OpenAIApi(configuration);
// Chat completions APIを呼ぶ
const response = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [
{
role: ChatCompletionRequestMessageRoleEnum.System,
content: "あなたは有能なアシスタントです。",
},
...mentionMessages,
],
});
const message = response.data.choices[0].message?.content;
// Slack APIを呼んで回答を送信
await say(
{
text:`<@${event.user}>\n ${message}`,
thread_ts: threadTs
}
);
} catch (e) {
await say(
{
text:`<@${event.user}>\n 不具合が発生しました。開発者にお問い合わせください。`,
thread_ts: threadTs
}
);
}
});
// Start your app
(async () => {
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
終わりに
記事のタイトルには「ChatGPT」と書いてしまいましたが、正確には「ChatGPTで使われている言語モデル」を使っています。
ChatGPTの凄さが知れたのと同時に、Glitch,Slack Boltの便利さも実感しました。この2つはおそらく今後めちゃ使うと思います。
Discussion