Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit cdf350a

Browse files
authored
Feat : DEFERRED_CHANNEL_MESSAGE 를 이용하여 응답에 3초 이상 걸리는 경우도 응답 가능하도록 수정 (#3)
* feat : Proxy 함수가 먼저 Response를 전달하고, 비동기적으로 OpenAI Response Lambda를 호출하도록 수정 * feat : OpenAI Response 함수 추가 * chore : README.md 업데이트
1 parent 27fbd48 commit cdf350a

File tree

7 files changed

+821
-24
lines changed

7 files changed

+821
-24
lines changed

README.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
### FAQ
9595

9696
- **프롬프트를 수정하고 싶어요!**
97-
- src/openai.ts 에 들어가서, `generatePrompt` 내부의 글자를 수정합니다. 이 때, Question은 유저가 입력한 값입니다.
97+
- src/openai-response/openai.ts 에 들어가서, `generatePrompt` 내부의 글자를 수정합니다. 이 때, Question은 유저가 입력한 값입니다.
9898
- 기본값으론, 예를 들어 유저가 "안녕" 이라고 입력했다면 ChatGPT에게는 다음과 같이 전달됩니다.
9999
```
100100
너는 디스코드에서 운영되고 있는 봇이야.
@@ -128,9 +128,21 @@
128128
├── register.ts # Discord Server에 Slash Command를 등록할 떄 실행되는 파일입니다.
129129
├── serverless.yml
130130
├── src
131+
│ ├── openai-response
132+
│ │ ├── handler.ts # proxy/handler.ts 에 의해 호출되는 함수입니다. OpenAI 서버와 통신 후 Discord 대화를 업데이트합니다.
133+
│ │ └── openai.ts # OpenAI API를 사용하기 위한 파일입니다. generatePrompt 함수를 수정하여 프롬프트를 변경할 수 있습니다.
134+
│ ├── proxy
135+
│ │ └── handler.ts # 요청을 받으면 openai-response/handler를 비동기적으로 호출 뒤, 바로 응답을 반환합니다.
131136
│ ├── commands.ts # 등록되는 Slash Command입니다.
132-
│ ├── openai.ts # OpenAI API를 사용하기 위한 파일입니다. generatePrompt 함수를 수정하여 프롬프트를 변경할 수 있습니다.
133137
│ └── util.ts # 유틸 함수입니다.
134138
├── tsconfig.json
135139
└── yarn.lock
136140
```
141+
142+
![image](https://user-images.githubusercontent.com/31124212/222947308-df2a3b89-e9f2-490b-af39-2b6276d2a085.png)
143+
144+
145+
### 업데이트 노트
146+
147+
* v0.0.1 : 기본 API 및 응답 구현
148+
* v0.1.1 : 3초 이상 걸리는 Response도 정상 응답 가능하도록, Multi Layer Architecture로 변경

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"author": "lemondouble",
77
"license": "MIT",
88
"scripts": {
9-
"register" : "ts-node register.ts",
9+
"register": "ts-node register.ts",
1010
"lint": "eslint .",
1111
"lint:fix": "eslint --fix ."
1212
},
@@ -28,6 +28,7 @@
2828
"typescript": "*"
2929
},
3030
"dependencies": {
31+
"@aws-sdk/client-lambda": "^3.282.0",
3132
"axios": "^1.3.4",
3233
"discord-interactions": "^3.3.0",
3334
"dotenv": "^16.0.3",

serverless.yml

+11-4
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@ provider:
55
name: aws
66
runtime: nodejs18.x
77
region: ap-northeast-1
8-
architecture: arm64 # ARM이 X86보다 조금이라도 쌉니다..
9-
8+
architecture: arm64 # ARM이 x86보다 조금이라도 싸서..
9+
iamRoleStatements:
10+
- Effect: "Allow"
11+
Action:
12+
- "lambda:InvokeFunction"
13+
Resource: '*'
1014

1115
plugin:
1216
- serverless-plugin-typescript
1317
- serverless-dotenv-plugin
1418

1519
functions:
16-
api:
17-
handler: handler.handle
20+
proxy:
21+
handler: src/proxy/handler.handle
1822
events:
1923
- httpApi:
2024
path: /
2125
method: any
26+
openai-response:
27+
handler: src/openai-response/handler.handle
28+
timeout: 30 # OpenAI Response가 느린 경우도 있으므로 넉넉하게 설정
2229

2330
plugins:
2431
- serverless-plugin-typescript

src/openai-response/handler.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import axios from "axios";
2+
import { getChatGptAnswer } from "./openai";
3+
4+
interface OpenAIQuestionRequest {
5+
token: string;
6+
question: string;
7+
}
8+
9+
export const handle = async (event: OpenAIQuestionRequest): Promise<void> => {
10+
console.log(event);
11+
12+
const answer = await getChatGptAnswer(event.question);
13+
14+
await axios.post(
15+
`https://discord.com/api/v9/webhooks/${process.env.DISCORD_APPLICATION_ID}/${event.token}`,
16+
JSON.stringify({
17+
content: answer,
18+
}),
19+
{
20+
headers: {
21+
"Content-Type": "application/json",
22+
},
23+
}
24+
);
25+
};

src/openai.ts src/openai-response/openai.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import { throwError } from "./util";
21
import { Configuration, OpenAIApi } from "openai";
2+
import { throwError } from "../util";
33

44
const generatePrompt = (question: string): string => {
55
return `너는 디스코드에서 운영되고 있는 봇이야.
66
너는 가능한 한 친절하게 대답해야 해.
77
이 질문에 대해 답해봐.
8-
질문 : ${question}`;
8+
질문 : ${question}
9+
답변 :
10+
`;
911
};
1012

1113
export const getChatGptAnswer = async (question: string) => {

handler.ts src/proxy/handler.ts

+23-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { type APIGatewayEvent, type APIGatewayProxyResult } from "aws-lambda";
22
import nacl from "tweetnacl";
3-
import { InteractionType } from "discord-interactions";
4-
import { throwError } from "./src/util";
5-
import { AVAILABLE_COMMANDS } from "./src/commands";
6-
import { getChatGptAnswer } from "./src/openai";
3+
import { InteractionResponseType, InteractionType } from "discord-interactions";
4+
import { throwError } from "../util";
5+
import { AVAILABLE_COMMANDS } from "../commands";
6+
import {
7+
InvocationType,
8+
InvokeCommand,
9+
LambdaClient,
10+
} from "@aws-sdk/client-lambda";
711

812
export const handle = async (
913
event: APIGatewayEvent
@@ -52,22 +56,27 @@ export const handle = async (
5256
switch (message.data.name) {
5357
case AVAILABLE_COMMANDS.name: {
5458
if (message.data.name === "질문") {
55-
const question = message.data.options[0].value;
56-
57-
const answer = await getChatGptAnswer(question);
58-
59-
console.log(`question : ${question}, answer : ${answer}`);
60-
59+
const client = new LambdaClient({});
60+
await client.send(
61+
new InvokeCommand({
62+
FunctionName:
63+
"chatgpt-serverless-discord-bot-dev-openai-response",
64+
InvocationType: InvocationType.Event,
65+
Payload: Buffer.from(
66+
JSON.stringify({
67+
token: message.token,
68+
question: message.data.options[0].value,
69+
})
70+
),
71+
})
72+
);
6173
return {
6274
statusCode: 200,
6375
headers: {
6476
"content-type": "application/json",
6577
},
6678
body: JSON.stringify({
67-
type: 4,
68-
data: {
69-
content: `${answer}`,
70-
},
79+
type: InteractionResponseType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE,
7180
}),
7281
};
7382
}

0 commit comments

Comments
 (0)