File size: 4,005 Bytes
f91846a
55b1be9
34287b9
297afd5
f91846a
 
 
 
98dc21e
d64ab05
98dc21e
fa541eb
fb0b1aa
13d3707
ba00282
13d3707
 
98dc21e
 
1ce0901
 
98dc21e
 
1ce0901
f23a640
98dc21e
55b1be9
98dc21e
 
55b1be9
 
 
df5bf2a
55b1be9
 
 
 
98dc21e
55b1be9
6482098
a7c9894
2cf7795
98dc21e
6482098
34287b9
 
 
 
 
98dc21e
0a52d39
3a2e91a
98dc21e
34287b9
 
 
3a2e91a
98dc21e
34287b9
0385c62
ad630db
98dc21e
ad630db
4a7f8d2
3a2e91a
4a7f8d2
cdb7b92
98dc21e
cdb7b92
98dc21e
 
 
 
 
cdb7b92
98dc21e
df7b5e5
98dc21e
4a7f8d2
 
98dc21e
 
3a2e91a
df7b5e5
98dc21e
df7b5e5
50928f0
a7d72c9
17ddbda
a7d72c9
98dc21e
a145c04
 
1c424f7
a145c04
98dc21e
a145c04
f91846a
 
50928f0
 
 
df7b5e5
50928f0
 
 
 
3bf6983
 
98dc21e
774d03c
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
import json, os
from fastapi.middleware.cors import CORSMiddleware
from fastapi import FastAPI, Request,  Header, BackgroundTasks, HTTPException, status
from google import genai
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage, ImageSendMessage, AudioMessage

# 設定 Google AI API 金鑰
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))

# 設定生成文字的參數 + 角色扮演
system_instruction = "你是一位熱情開朗的機器人,每次回答問題之餘,還會講一個100字以內的笑話! "
thinking_config = genai.types.ThinkingConfig(thinking_budget=0) # thinking_budget = 0,  turn off thinking mode
generation_config = genai.types.GenerateContentConfig(max_output_tokens=512, temperature=0.5, top_p=0.5,
                                                      thinking_config=thinking_config,
                                                      system_instruction=system_instruction)

# 設定 Line Bot 的 API 金鑰和秘密金鑰
line_bot_api = LineBotApi(os.environ["CHANNEL_ACCESS_TOKEN"])
line_handler = WebhookHandler(os.environ["CHANNEL_SECRET"])

# 設定是否正在與使用者交談
working_status = os.getenv("DEFALUT_TALKING", default = "true").lower() == "true"

# 建立 FastAPI 應用程式
app = FastAPI()

# 設定 CORS,允許跨域請求
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 處理根路徑請求
@app.get("/")
def root():
    return {"title": "Line Bot"}

# 處理 Line Webhook 請求
@app.post("/webhook")
async def webhook(
    request: Request,
    background_tasks: BackgroundTasks,
    x_line_signature=Header(None),
):
    # 取得請求內容
    body = await request.body()
    try:
        # 將處理 Line 事件的任務加入背景工作
        background_tasks.add_task(
            line_handler.handle, body.decode("utf-8"), x_line_signature
        )
    except InvalidSignatureError:
        # 處理無效的簽章錯誤
        raise HTTPException(status_code=400, detail="Invalid signature")
    return "ok"
    
# 處理文字訊息事件
chat_sessions = {}
@line_handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    global working_status
    
    # 檢查事件類型和訊息類型
    if event.type != "message" or event.message.type != "text":
        # 回覆錯誤訊息
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text="Event type error:[No message or the message does not contain text]")
        )
        
    # 檢查使用者是否輸入 "再見"
    elif event.message.text == "再見":
        # 回覆 "Bye!"
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text="Bye!")
        )
        return
       
    # 檢查是否正在與使用者交談
    elif working_status:
        try: 
            user_id = event.source.user_id
            chat = chat_sessions.get(user_id) or client.chats.create(model="gemini-2.5-flash", config=generation_config)
            chat_sessions[user_id] = chat
            # 取得使用者輸入的文字
            user_input = event.message.text
            # 發送使用者的輸入到聊天會話並獲得回應
            response = chat.send_message(user_input)
            if (response.text != None):
                # 取得生成結果
                out = response.text
            else:
                out = "Gemini沒答案!請換個說法!"
        except:
            # 處理錯誤
            out = "Gemini執行出錯!請換個說法!" 
  
        # 回覆生成結果
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=out))

if __name__ == "__main__":
    # 啟動 FastAPI 應用程式
    uvicorn.run("main:app", host="0.0.0.0", port=7860, reload=True)