""" 東吳大學資料系 2025 LINEBOT """ import logging import os from flask import Flask, abort, request from bs4 import BeautifulSoup import markdown from google.genai.types import Tool, GenerateContentConfig, GoogleSearch from linebot.v3 import WebhookHandler from linebot.v3.exceptions import InvalidSignatureError from linebot.v3.messaging import ( ApiClient, Configuration, MessagingApi, ReplyMessageRequest, TextMessage, ) from linebot.v3.webhooks import MessageEvent, TextMessageContent # Initialize Google Gemini GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") client = genai.Client(api_key=GOOGLE_API_KEY) chat = client.chats.create(model="gemini-2.0-flash", config=GenerateContentConfig( system_instruction="你是一個中文的AI助手,請用繁體中文回答", tools=[google_search_tool], response_modalities=["TEXT"], )) # Initialize Flask app app = Flask(__name__) logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) app.logger.setLevel(logging.INFO) channel_secret = os.getenv("YOUR_CHANNEL_SECRET") channel_access_token = os.getenv("YOUR_CHANNEL_ACCESS_TOKEN") configuration = Configuration(access_token=channel_access_token) handler = WebhookHandler(channel_secret) def query(payload: str) -> str: """Send a prompt to Gemini and return the response text.""" try: response = chat.send_message(message=payload) return response.text except Exception as e: return f"發生錯誤:{e}" @app.route("/", methods=["GET"]) def home(): """Health check endpoint.""" return {"message": "Line Webhook Server"} @app.route("/", methods=["POST"]) def callback(): """Handle incoming webhook from LINE.""" signature = request.headers.get("X-Line-Signature") body = request.get_data(as_text=True) app.logger.info("Request body: %s", body) try: handler.handle(body, signature) except InvalidSignatureError: app.logger.warning( "Invalid signature. Please check channel credentials." ) abort(400) return "OK" @handler.add(MessageEvent, message=TextMessageContent) def handle_text_message(event): """Handle incoming text message event.""" user_input = event.message.text.strip() response_text = query(user_input) html_msg = markdown.markdown(response_text) soup = BeautifulSoup(html_msg, "html.parser") 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=soup.get_text())], ) )