GASでやっていたが、好きなチャンネルにボットを読んでやり取りしたかったのと、権限周りの関係で、Cloud functionsでやってみた。
package.json
{
"name": "slack-chatgpt-gcloud",
"version": "1.0.0",
"description": "Slack bot with GPT-4 integration on Google Cloud Functions",
"main": "index.js",
"dependencies": {
"@slack/web-api": "^6.6.0",
"axios": "^0.26.1",
"express": "^4.17.1",
"body-parser": "^1.19.1"
},
"engines": {
"node": "14"
}
}
API_keyやbotのkeyは、ランタイム環境変数に入れておく。
ログは、console.logで出しておく。
あと、chatgptが返答遅い時に、再度リクエストしないようにケアしておく。
index.js
const { WebClient } = require('@slack/web-api');
const axios = require('axios');
const express = require('express');
const bodyParser = require('body-parser');
// Slack APIとOpenAI APIのキー
const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN;
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
// Slack WebClientのインスタンス作成
const slackClient = new WebClient(SLACK_BOT_TOKEN);
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/', async (req, res) => {
// タイムアウトしないためにとにかく先に返す
res.status(200).send()
// Slackのチャレンジリクエストに対応
if (req.body.type === 'url_verification') {
res.status(200).send(req.body.challenge);
return;
}
const { event } = req.body;
if (event && event.type === 'app_mention') {
const inputText = event.text;
const channelId = event.channel;
try {
const gptResponse = await axios.post(
'https://api.openai.com/v1/chat/completions',
{
messages: [{ "role": "user", "content": inputText }],
model: "gpt-3.5-turbo"
},
{
headers: {
'Authorization': `Bearer ${OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
}
);
const gptReply = gptResponse.data.choices[0].message.content;
const userInfoResponse = await slackClient.users.info({
user: event.user,
});
const userName = userInfoResponse.user.profile.display_name;
// ユーザー名とメッセージを記録
console.log(`${userName}: ${inputText}`);
console.log(`GPT-3.5: ${gptReply}`);
await slackClient.chat.postMessage({
channel: channelId,
text: gptReply,
thread_ts: event.ts
});
res.status(200).send();
} catch (error) {
console.error('Error:', error);
res.status(500).send();
}
} else {
res.status(200).send();
}
res.end()
});
const PORT = process.env.PORT || 8080;
exports.slackBot = app;
slackbotの設定はいつもの通り。
デプロイ
gcloud functions deploy slackBot --runtime nodejs14 --trigger-http --allow-unauthenticated --project your-project-id