-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
120 lines (103 loc) · 3.6 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import os
from dotenv import load_dotenv
# Load environment variables from a '.env' file
load_dotenv()
from flask import Flask, request, abort, jsonify
from linebot.v3 import (
WebhookHandler
)
from linebot.v3.exceptions import (
InvalidSignatureError
)
from linebot.v3.messaging import (
Configuration,
ApiClient,
MessagingApi,
PushMessageRequest,
ReplyMessageRequest,
TextMessage
)
from linebot.v3.webhooks import (
MessageEvent,
TextMessageContent
)
from chat_bot import chat_bot
# Load secrets from environment variables
LINE_CHANNEL_ACCESS_TOKEN = os.environ.get('LINE_CHANNEL_ACCESS_TOKEN')
LINE_CHANNEL_SECRET = os.environ.get('LINE_CHANNEL_SECRET')
app = Flask(__name__)
configuration = Configuration(access_token=LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)
# The /echo endpoint is used to echo back users' chat messages on LINE platform
@app.route('/echo', methods=['GET', 'POST'])
def echo(request):
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
"""
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
app.logger.info('Invalid signature. Please check your channel access token/channel secret.')
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
line_bot_api.reply_message_with_http_info(
ReplyMessageRequest(
reply_token=event.reply_token,
messages=[TextMessage(text=event.message.text)]
)
)
import threading
from openai import OpenAI
client = OpenAI(
# Defaults to os.environ.get("OPENAI_API_KEY")
# Otherwise use: api_key="Your_API_Key"
api_key=os.environ['OPENAI_API_KEY'],
)
def async_get_response(user_id, prompt):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{ "role": "user", "content": prompt, }],
)
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
line_bot_api.push_message(
PushMessageRequest(
to=user_id,
messages=[TextMessage(text=response.choices[0].message.content)]
)
)
# The /chat endpoint is called by the fulfillment of my intents on Dialogflow
@app.route('/chat', methods=['POST'])
def chat(request):
json = request.get_json()
query_result = json['queryResult']
action = query_result.get('action')
if action == 'input.unknown':
# Relay the query text to chatGPT and asynchronous push back the response
user_id = json['originalDetectIntentRequest']['payload']['data']['source']['userId']
prompt = query_result['queryText']
CT = threading.Thread(target=async_get_response, args=(user_id, prompt,))
CT.start()
return jsonify({ 'fulfillmentText': '...' })
return jsonify({ 'fulfillmentText': chat_bot(json) })
if __name__ == '__main__':
port = os.environ.get('SERVER_PORT')
if port == None:
port = 80
else:
port = int(port)
app.run(host='0.0.0.0', port=port)