create project

This commit is contained in:
Nebel 2023-01-30 03:37:33 +09:00
parent a4c0e0cd31
commit f6256a0b22
8 changed files with 6367 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.vercel
node_modules

48
README.md Normal file
View file

@ -0,0 +1,48 @@
# だらずさん GPT
GPT 版だらずさん
## インストール
Step 1
: Vercel へのデプロイ
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fkou029w%2Fdaraz-gpt)
Step 2
: Slack アプリの作成
[Slack Applications](https://api.slack.com/apps) → Create New App → From an app manifest
下記の Manifest をコピペして、Slack アプリを作成します。
```yaml
display_information:
name: daraz-gpt
features:
bot_user:
display_name: daraz-gpt
oauth_config:
scopes:
bot:
- app_mentions:read
- chat:write
settings:
event_subscriptions:
request_url: https://daraz-gpt.vercel.app/api/slack/events
bot_events:
- app_mention
```
Step 3
: 環境変数の設定
[Vercel Dashboard](https://vercel.com/dashboard) → 対象のプロジェクト → Settings → Environment Variables
- `SLACK_BOT_TOKEN` ... [Slack Applications](https://api.slack.com/apps) → "daraz-gpt" → Permissions ページにある `xoxb-` から始まるボットトークン
- `SLACK_SIGNING_SECRET` ... [Slack Applications](https://api.slack.com/apps) → "daraz-gpt" → Basic Information ページにある Signing Secret
- `OPENAI_API_KEY` … [OpenAI API Key](https://beta.openai.com/account/api-keys)
## ライセンス
WTFPL

47
api/slack/events.ts Normal file
View file

@ -0,0 +1,47 @@
import { App, AwsLambdaReceiver } from "@slack/bolt";
import type { AwsHandler } from "@slack/bolt/dist/receivers/AwsLambdaReceiver";
const openaiApiKey = process.env.OPENAI_API_KEY ?? "";
async function gpt(prompt: string): Promise<string> {
const endpoint = "https://api.openai.com/v1/completions";
const body = {
model: "text-davinci-003",
prompt,
temperature: 0.5,
max_tokens: 2048,
};
const res = await fetch(endpoint, {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${openaiApiKey}`,
},
body: JSON.stringify(body),
});
const json = await res.json();
return json.choices[0].text.trim();
}
const token = process.env.SLACK_BOT_TOKEN ?? "";
const signingSecret = process.env.SLACK_SIGNING_SECRET ?? "";
const receiver = new AwsLambdaReceiver({ signingSecret });
const awsHandler = receiver.toHandler();
const app = new App({ token, receiver });
// required app_mentions:read chat:write
app.event("app_mention", async ({ event, say }) => {
const prompt = `語尾を「にゃん」に。${event.text
.replace(/<@[0-9A-Z]+>/, "")
.trim()}`;
const text = await gpt(prompt);
await say(text);
});
export const handler: AwsHandler = async (event, context, callback) => {
// AWS Lambda ウォームアップ時に発生しうるタイムアウトを無視
if (event.headers["x-slack-retry-reason"] === "http_timeout") {
return { statusCode: 200, body: "OK" };
}
return await awsHandler(event, context, callback);
};

6247
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

11
package.json Normal file
View file

@ -0,0 +1,11 @@
{
"name": "daraz-gpt",
"version": "0.0.0",
"private": true,
"dependencies": {
"@slack/bolt": "^3.12.2"
},
"devDependencies": {
"vercel": "^28.14.0"
}
}

1
public/index.txt Normal file
View file

@ -0,0 +1 @@
OK

4
renovate.json Normal file
View file

@ -0,0 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base", "config:semverAllMonthly", ":automergeMinor"]
}

7
vercel.json Normal file
View file

@ -0,0 +1,7 @@
{
"build": {
"env": {
"NODEJS_AWS_HANDLER_NAME": "handler"
}
}
}