File size: 4,406 Bytes
963016d
55b1be9
a5ad84f
 
 
 
 
d5eb5ca
2cf7795
a5ad84f
 
 
d57eb13
 
d5eb5ca
 
 
 
 
 
 
d7b5fcf
 
7a0a9ed
371da96
d7b5fcf
371da96
 
2fee05b
9accbde
1ce0901
 
a5ad84f
9accbde
1ce0901
f23a640
9accbde
55b1be9
9accbde
 
55b1be9
 
 
df5bf2a
55b1be9
 
 
 
9accbde
55b1be9
6482098
9accbde
2cf7795
9accbde
6482098
34287b9
 
 
 
 
9accbde
0a52d39
3a2e91a
9accbde
34287b9
 
 
3a2e91a
9accbde
34287b9
0385c62
2cf7795
9accbde
4a7f8d2
3a2e91a
4a7f8d2
cdb7b92
9accbde
cdb7b92
9accbde
 
 
 
 
cdb7b92
9accbde
df7b5e5
9accbde
4a7f8d2
 
9accbde
 
3a2e91a
df7b5e5
9accbde
df7b5e5
e5d9d13
9accbde
 
8a9ff95
a5ad84f
8a9ff95
d7b5fcf
889ff07
9accbde
6ec574f
9accbde
889ff07
9accbde
 
 
e5d9d13
9accbde
 
df7b5e5
9accbde
4a7f8d2
 
619c607
3bf6983
 
9accbde
e75a35a
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
121
122
123
import json, os, glob, pathlib
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
import PyPDF2

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

# Retrieve the PDF
files = glob.glob('docs/*.pdf')
pdf_content = ''
for filename in files:
    pdf_file = open(filename, 'rb')
    pdf_reader = PyPDF2.PdfReader(pdf_file)
    for i in range(len(pdf_reader.pages)):
        page = pdf_reader.pages[i]
        pdf_content+= page.extract_text()
        
# 設定生成文字的參數 + 角色扮演
system_instruction = pdf_content+"\n"+"您是一位問答助手。請僅限使用以上提供的內容來回答問題。如果您不知道答案,請說您不知道,不要捏造答案。"
thinking_config = genai.types.ThinkingConfig(thinking_budget=0) # thinking_budget = 0,  turn off thinking mode
generation_config = genai.types.GenerateContentConfig(max_output_tokens=3000, temperature=0.1, top_p=0.2,
                                                      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"

# 處理文字訊息事件
@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: 
            # 取得使用者輸入的文字
            prompt = event.message.text
            # gemini-2.5-flash
            completion = client.models.generate_content(
                                model="gemini-2.5-flash",
                                contents=prompt,
                                config=generation_config).text
            # 檢查生成結果是否為空
            if (completion != None):
                # 取得生成結果
                out = completion
            else:
                # 回覆 "Gemini沒答案!請換個說法!"
                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)