CoolFace
Apppublic

yuna456789/Linebot

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
main.py181 linesDownload Raw Back to root
1from fastapi.middleware.cors import CORSMiddleware2from fastapi import FastAPI, Request,  Header, BackgroundTasks, HTTPException, status3from fastapi.staticfiles import StaticFiles4from google import genai5from linebot import LineBotApi, WebhookHandler6from linebot.exceptions import InvalidSignatureError7from linebot.models import MessageEvent, TextMessage, TextSendMessage, ImageSendMessage, AudioMessage, ImageMessage8import json, os9import io10import PIL.Image11from Image_text_generation import Image_text_Generator12from Uploading_images_file import get_image_url, store_user_message, analyze_with_gemini, get_previous_message13 14#==========================15#  API 金鑰16#==========================17 18# 設定 Google AI API 金鑰19client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))20 21# 設定生成文字的參數22generation_config = genai.types.GenerateContentConfig(max_output_tokens=256, temperature=0.5, top_p=0.5, top_k=16)23 24# 設定 Line Bot 的 API 金鑰和秘密金鑰25line_bot_api = LineBotApi(os.environ["CHANNEL_ACCESS_TOKEN"])26line_handler = WebhookHandler(os.environ["CHANNEL_SECRET"])27 28# 設定是否正在與使用者交談29working_status = os.getenv("DEFALUT_TALKING", default = "true").lower() == "true"30 31# 建立 FastAPI 應用程式32app = FastAPI()33app.mount("/static", StaticFiles(directory="static"), name="static")34 35# 設定 CORS,允許跨域請求36app.add_middleware(37    CORSMiddleware,38    allow_origins=["*"],39    allow_credentials=True,40    allow_methods=["*"],41    allow_headers=["*"],42)43 44# 處理根路徑請求45@app.get("/")46def root():47    return {"title": "Line Bot"}48 49# 處理 Line Webhook 請求50@app.post("/webhook")51async def webhook(52    request: Request,53    background_tasks: BackgroundTasks,54    x_line_signature=Header(None),55):56    # 取得請求內容57    body = await request.body()58    try:59        # 將處理 Line 事件的任務加入背景工作60        background_tasks.add_task(61            line_handler.handle, body.decode("utf-8"), x_line_signature62        )63    except InvalidSignatureError:64        # 處理無效的簽章錯誤65        raise HTTPException(status_code=400, detail="Invalid signature")66    return "ok"67    68 69#==========================70# 主程式(圖片與文字)71#==========================72# 建立 chat_sessions 字典73chat_sessions = {}74@line_handler.add(MessageEvent, message=(ImageMessage, TextMessage))75def handle_image_message(event):76    user_id = event.source.user_id77    user_text = event.message.text if event.message.type == "text" else None78    previous_message = get_previous_message(user_id)79 80    if event.message.type != "text" and event.message.type != "image":81        line_bot_api.reply_message(event.reply_token, TextSendMessage(text="請輸入文字或圖片~"))82        return83    elif user_text == "再見":84        line_bot_api.reply_message(event.reply_token, TextSendMessage(text="Bye!"))85        return86        87    # ========88    # 生成圖片89    # ========90    elif user_text and user_text.startswith("生成圖片"):91        prompt = user_text.replace("生成圖片", "").strip()92 93         # 先立即回覆避免token過期94        line_bot_api.reply_message(event.reply_token, TextSendMessage(text="圖片生成中~ 請稍候.....✨"))95        image_generator = Image_text_Generator(user_id)96        # 生成圖片97        image_binary = image_generator.generate_image_with_gemini(prompt)98 99        if image_binary:100            image_url = os.path.join(os.getenv("HF_SPACE"),image_generator.upload_image_to_tmp(image_binary)) ### os.getenv("HF_SPACE") => https://xxxxx.hf.space101 102            if image_url:103                # 使用 push message 發送圖片,避免 reply token 超時104                line_bot_api.push_message(105                    event.source.user_id,106                    [107                        TextSendMessage(text="✨ 這是我為你生成的圖片喔~"),108                        ImageSendMessage(original_content_url=image_url, preview_image_url=image_url)109                    ]110                )111            else:112                line_bot_api.push_message(113                    event.source.user_id,114                    TextSendMessage(text="⚠️ 圖片上傳失敗,請稍後再試~")115                )116        else:117            line_bot_api.push_message(118                event.source.user_id,119                TextSendMessage(text="⚠️ 圖片生成失敗,請稍後再試~")120            )121        return122        123    # ========124    # 純文字125    # ========126    elif event.message.type == "text" and previous_message["type"] != "image":127        try: 128            user_id = event.source.user_id129            chat = chat_sessions.get(user_id) or client.chats.create(model="gemini-2.0-flash", config=generation_config)130            chat_sessions[user_id] = chat131            # 取得使用者輸入的文字132            user_input = event.message.text133            response = chat.send_message(user_input)134            if (response.text != None):135                out = response.text136            else:137                out = "Gemini沒答案!請換個說法!"138        except:139            # 處理錯誤140            out = "Gemini執行出錯!請換個說法!" 141        142    elif previous_message and previous_message["type"] == "image" and event.message.type == "text":143        image_path = previous_message["content"]144        user_text = event.message.text145        store_user_message(user_id, "text", user_text)146        try:147            if not os.path.exists(image_path):148                raise FileNotFoundError(f"圖片路徑無效:{image_path}")149            previous_img = PIL.Image.open(image_path)150            user_id = event.source.user_id151            chat = chat_sessions.get(user_id) or client.chats.create(model="gemini-2.0-flash", config=generation_config)152            chat_sessions[user_id] = chat153            # 取得使用者輸入的文字154            user_input = event.message.text155            response = chat.send_message([previous_img, user_input])156            if (response.text != None):157                out = response.text158            else:159                out = "Gemini沒答案!請換個說法!"160        except:161            # 處理錯誤162            out = "Gemini執行出錯!請換個說法!" 163 164    # ========165    # 上傳圖片166    # ========167    elif event.message.type == "image":168        image_path = get_image_url(event.message.id)169        if image_path:170            store_user_message(user_id, "image", image_path)171            line_bot_api.reply_message(event.reply_token, TextSendMessage(text="圖片已接收成功囉,幫我輸入你想詢問的問題喔~"))172        else:173            line_bot_api.reply_message(event.reply_token, TextSendMessage(text="沒有接收到圖片~"))174        return175 176    line_bot_api.reply_message(event.reply_token, TextSendMessage(text=out))177 178 179if __name__ == "__main__":180    # 啟動 FastAPI 應用程式181    uvicorn.run("main:app", host="0.0.0.0", port=7860, reload=True)