이번 글에서는 AWS CloudFormation을 이용해, 별도의 코딩 없이 간단하게 ChatGPT SlackApp을 만드는 방법을 소개하겠습니다.!
Slack Slash Command는 3초안에 응답이 이루어져야함
PT엔진으로 검색할시 대부분 3초이상이 걸림
응답을 하는 AWS Lambda 따로, 검색 한 뒤, 결과를 Slack에 Post하는 AWS Lambda 따로
api.slack.com에 접속하여 Create an app 클릭
From scratch 선택
SlackApp Name & workspace 설정
chat:write 추가
(slach command는 AWS CloudFomation을 이용해 AWS APIGATEWAY를 설치한 뒤 설정)
OpenAI에서 회원가입을 한다
OpenAI apikey 에서 api keys 생성
(추후 AWS Lambda의 환경 변수로 설정 될 예정)
위 링크 클릭시 다음과 같은 화면이 나옵니다.
Parameters:
ApiGatewayName:
Type: String
Default: ChatGPTAPI
OpenaiKey:
Description: "OpenAI Key"
Type: String
SlackToken:
Description: "Slack Token"
Type: String
SlackChannel:
Description: "Slack Channel name import #"
Type: String
Default: "#mayfgpt"
LambdaFunctionName1:
Type: String
Default: "SlackToLambda"
LambdaFunctionName2:
Type: String
Default: "LambdaToChatGPT"
LambdaMemorySize1:
Type: Number
Default: 1024
MinValue: 128
MaxValue: 3000
LambdaTimeOut1:
Type: Number
Default: 5
LambdaMemorySize2:
Type: Number
Default: 1024
MinValue: 128
MaxValue: 3000
LambdaTimeOut2:
Type: Number
Default: 300
Resources:
ChatGPTApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Description: ChatGPT APIGATEWAY
BinaryMediaTypes:
- application/json
EndpointConfiguration:
Types:
- EDGE
Name:
Ref : ApiGatewayName
ApiGatewayResource:
Type: AWS::ApiGateway::Resource
Properties:
ParentId: !GetAtt ChatGPTApiGateway.RootResourceId
PathPart: 'gpt'
RestApiId: !Ref ChatGPTApiGateway
ApiGatewayMethod:
Type: AWS::ApiGateway::Method
Properties:
ApiKeyRequired: false
AuthorizationType: NONE
HttpMethod: POST
Integration:
ConnectionType: INTERNET
Credentials: !GetAtt ApiGatewayIamRole.Arn
IntegrationHttpMethod: POST
PassthroughBehavior: WHEN_NO_MATCH
TimeoutInMillis: 29000
Type: AWS_PROXY
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SlackToLambda.Arn}/invocations'
OperationName: 'lambda'
ResourceId: !Ref ApiGatewayResource
RestApiId: !Ref ChatGPTApiGateway
ApiGatewayModel:
Type: AWS::ApiGateway::Model
Properties:
ContentType: 'application/json'
RestApiId: !Ref ChatGPTApiGateway
Schema:
title: DataModel
type: object
properties:
username:
type: string
text:
type: string
ApiGatewayStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref ApiGatewayDeployment
Description: Stage for chatGPT
RestApiId: !Ref ChatGPTApiGateway
StageName: 'chat'
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn: ApiGatewayMethod
Properties:
Description: Lambda API Deployment
RestApiId: !Ref ChatGPTApiGateway
ApiGatewayIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ''
Effect: 'Allow'
Principal:
Service:
- 'apigateway.amazonaws.com'
Action:
- 'sts:AssumeRole'
Path: '/'
Policies:
- PolicyName: LambdaAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'lambda:*'
Resource: !GetAtt SlackToLambda.Arn
ApiGatewayPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref SlackToLambda
Principal: "apigateway.amazonaws.com"
SourceArn:
!Join
- ''
- - 'arn:aws:execute-api'
- ':'
- !Ref AWS::Region
- ':'
- !Ref AWS::AccountId
- ':'
- !Ref ChatGPTApiGateway
- '/*/POST/gpt'
LambdaExecutionRole1:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- "sts:AssumeRole"
Policies:
- PolicyDocument:
Version: "2012-10-17"
Statement:
#Lambda Basic Excution Role
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
- Effect: Allow
Action:
- "lambda:InvokeFunction"
Resource: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaToChatGPT}"
PolicyName: chatgptpolicy1
LambdaExecutionRole2:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- "sts:AssumeRole"
Policies:
- PolicyDocument:
Version: "2012-10-17"
Statement:
#Lambda Basic Excution Role
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
PolicyName: chatgptpolicy2
SlackToLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName :
Ref : LambdaFunctionName1
Handler: lambda_function.lambda_handler
Runtime: python3.9
Code:
S3Bucket: !Sub 'chatgptcode'
S3Key: !Sub 'code1.zip'
MemorySize:
Ref : LambdaMemorySize1
Timeout:
Ref : LambdaTimeOut1
Role: !GetAtt LambdaExecutionRole1.Arn
Environment:
Variables:
LambdaToChatGPT:
Ref : LambdaFunctionName2
LambdaToChatGPT:
Type: AWS::Lambda::Function
Properties:
FunctionName :
Ref : LambdaFunctionName2
Handler: lambda_function.lambda_handler
Runtime: python3.9
Code:
S3Bucket: !Sub 'chatgptcode'
S3Key: !Sub 'code2.zip'
MemorySize:
Ref : LambdaMemorySize2
Timeout:
Ref : LambdaTimeOut2
Role: !GetAtt LambdaExecutionRole2.Arn
Environment:
Variables:
OPENAI_KEY:
Ref : OpenaiKey
SLACK_TOKEN:
Ref : SlackToken
SLACK_CHANNEL:
Ref : SlackChannel
Layers:
- arn:aws:lambda:ap-northeast-2:858869084011:layer:openai:1
- arn:aws:lambda:ap-northeast-2:858869084011:layer:slack:1
Outputs:
ApiEndponit:
Description: "API Endpoint"
Value: !Sub "https://${ChatGPTApiGateway}.execute-api.${AWS::Region}.amazonaws.com/chat/gpt"
import json
import boto3
import os
def lambda_handler(event, context):
bodys=event['body'].split("&")
username=""
text=""
for data in bodys:
if "user_name" in data:
user_name_split=data.split('=')
username=user_name_split[1]
if "text" in data:
text_split= data.split('=')
text=text_split[1]
str=username+"님의 질문: "+text+"이 접수되었습니다."
print(str)
lambda_client = boto3.client('lambda')
response = lambda_client.invoke(
FunctionName=os.environ['LambdaToChatGPT'],
InvocationType='Event',
Payload=json.dumps({"username": username, "text": text})
)
return {
'statusCode': 200,
"headers": {
"Content-Type": "application/json"
},
"body": str
}
import json
import openai
import slack_sdk
import os
def lambda_handler(event, context):
openai.api_key=os.environ['OPENAI_KEY']
slack_token=os.environ['SLACK_TOKEN']
channel_name=os.environ['SLACK_CHANNEL']
print(event)
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": event['text']}]
)
str=event['username']+"님 의 질문에 대한 답변"+"\n\n"+completion["choices"][0].message.content
print(completion["choices"][0].message.content)
client=slack_sdk.WebClient(token=slack_token)
client.chat_postMessage(channel=channel_name, text=str)
Slack App Slash Command를 추가
RequestURL에는 이전 단계에서 AWS CloudFormation 설치 획득한 URL 입력
Slack Command 추가 시 Workspace에 재설치가 필요함
최근 ChatGPT의 등장으로 이를 이용한 다양한 시도가 이어지고 있는 것 같습니다.
Slack을 이용한다면 좀 더 편하게 업무와 연결을 시킬 수 있을 것이라 생각해 해당 포스트를 작성하였습니다.
또한 코딩을 모르시는 분들도 간편하게 Slack에서 ChatGPT를 사용하기 위해 AWS CloudFormation을 활용했습니다.