import os import sys import subprocess import logging from fastapi import FastAPI, Request, HTTPException import requests import json from datetime import datetime import importlib import pkgutil from mysite.libs.utilities import validate_signature, no_process_file #from mysite.database.database import ride,create_ride from controllers.gra_04_database.rides import test_set_lide from mysite.interpreter.prompt import prompt_genalate,test_prompt from mysite.interpreter.google_chat import send_google_chat_card,send_google_chat_card_thread #from mysite.interpreter.interpreter import chat_with_interpreter from controllers.gra_02_openInterpreter.OpenInterpreter import chat_with_interpreter_no_stream from mysite.appsheet.appsheet import get_senario import asyncio logger = logging.getLogger(__name__) """ router """ def include_routers(app): package_dir = "/home/user/app/routers" if not os.path.exists(package_dir): logger.error(f"Package directory {package_dir} does not exist.") return for module_info in pkgutil.iter_modules([package_dir]): try: if module_info.ispkg: sub_package_dir = os.path.join(package_dir, module_info.name) for sub_module_info in pkgutil.iter_modules([sub_package_dir]): module_name = ( f"routers.{module_info.name}.{sub_module_info.name}" if sub_module_info.ispkg else f"routers.{module_info.name}.{sub_module_info.name}" ) module = importlib.import_module(module_name) if hasattr(module, "router"): app.include_router(module.router) else: module_name = f"routers.{module_info.name}" module = importlib.import_module(module_name) if hasattr(module, "router"): app.include_router(module.router) except ModuleNotFoundError as e: logger.error(f"Module not found: {e}") except Exception as e: logger.error(f"An error occurred: {e}") from datetime import datetime def get_user_profile(user_id, access_token): url = f'https://api.line.me/v2/bot/profile/{user_id}' headers = { 'Authorization': f'Bearer {access_token}' } response = requests.get(url, headers=headers) if response.status_code == 200: profile = response.json() user_name = profile.get('displayName') user_thumbnail = profile.get('pictureUrl') return user_name, user_thumbnail else: print(f"Failed to get user profile: {response.status_code}, {response.text}") return None, None #from routers.webhooks import router def setup_webhook_routes(app: FastAPI): from polls.routers import register_routers register_routers(app) """ @app.post("/webhooks") def get_choices( messages ): logger.info("[Start] ====== LINE webhook ======") try: now = datetime.now().strftime("%Y%m%d%H%M%S") user_id_with_timestamp = messages[:10] #user_id_with_timestamp = messages#f"{now}_{title}_{user_id}" no_process_file(messages, user_id_with_timestamp) #db登録 test_set_lide(messages, user_id_with_timestamp) except Exception as e: logger.error("Error: %s", str(e)) """ @app.post("/webhook") async def webhook(request: Request): #return #logger.info("[Start] ====== LINE webhook ======") body = await request.body() received_headers = dict(request.headers) body_str = body.decode("utf-8") logger.info("Received Body: %s", body_str) body_json = json.loads(body_str) events = body_json.get("events", []) webhook_url = os.getenv("chat_url") token = os.getenv("token") ChannelAccessToken = os.getenv('ChannelAccessToken') thread_name="" #return #url = github(token,foldername) try: DEBUG=0 for event in events: if event["type"] == "message" and event["message"]["type"] == "text": user_id = event["source"]["userId"] text = event["message"]["text"] user_name,thmbnail = get_user_profile(user_id,ChannelAccessToken) logger.info("Received Headers: %s", user_name) logger.info("Received Headers: %s", thmbnail) #logger.info("------------------------------------------") first_line = text.split('\n')[0] #logger.info(f"User ID: {user_id}, Text: {text}") prompt = """ 1, Q&Aのテーブルを作成してください DBはpostgress pk はPostgresのAutoIncrementの serialでの自動追加 2, 質問が来た際には、まず質問に対しての答えを過去のデータから探します 3, Q&Aから役割を作成します 質問に対しての答えを出す、シナリオを考える 4, 実際にテストして正しい答えがでるか確認 5, 出ない場合は再度作成しなおします 1から6を繰り返し、答えが出たプロンプトを登録します 7, 成功した場合それを保存します 8, 同じ質問が来たら質問別にプロンプトを変更します 9, 上記をラインの質問に内部の方が納得いくまで、日々修正していきます """ prompt2 = f""" # 返信について日本語で必ず答えて下さい # 役割 あなたはリファスタという会社のアシスタントです 金、ダイヤモンド、商品を売りにきた顧客います 売りに来た顧客の質問内容は {text} この質問を買取店の査定人に対して、理解がしやすい わかりやすい質問に変更してください 会社にはデータベースがあり質問内容から、商品を検索するSQLを作成してください 必要なテーブルのCreate文も作成してして下さい pk は postgress なので 自動連番のserialにして下さい 質問の内容をそのテーブルにいれるインサート文も作成してくさい ほかに、良い提案があればして下さい。こうしたらもっと、良くなるよなど。 ## リファスタの住所 〒170-0013 東京都豊島区東池袋1丁目25−14 アルファビルディング 4F ## 買取ダイヤテンプレート - price, - carat, - cut, - color, - clarity, - depth, - diamondprice.table, - x, - y, - z ## 買取ブランドテンプレート ・ブランド名: ・モデル名: ・型番や品番: ・購入店: ・購入時期: ・購入金額: ・付属品: ・コンディション: (10段階評価厳しめ) ・貴金属品位: ・貴金属重量: (キッチンスケールでも(sparkle)) ・ダイヤや宝石の鑑定書はお写真で! ・イニシャル:あり なし ## リファスタのサイト (monitor)24h対応事前査定 https://kinkaimasu.jp/estimate/?openExternalBrowser=1&utm_source=LINE (open book)買取システムナビ https://kinkaimasu.jp/system/?openExternalBrowser=1&utm_source=LINE (car)店舗アクセス https://goo.gl/veQZ03 (?)よくある質問 https://kinkaimasu.jp/faq/?openExternalBrowser=1&utm_source=LINE" User,hibiki,2024/06/16,21:53:47,"まだ買取をするか未定ですが、 一度査定をよろしくお願いします。" Account,応答メッセージ,2024/06/16,21:53:47,"(clock)ただ今対応時間外(clock) 営業時間:11:00~20:00 ※年中無休 翌営業日に順次対応致しますので、お写真や情報はいつでもお送りください(moon wink) (monitor)24h対応事前査定 https://kinkaimasu.jp/estimate/?openExternalBrowser=1&utm_source=LINE (open book)買取システムナビ https://kinkaimasu.jp/system/?openExternalBrowser=1&utm_source=LINE (car)店舗アクセス https://goo.gl/veQZ03 (?)よくある質問 https://kinkaimasu.jp/faq/?openExternalBrowser=1&utm_source=LINE" ## サービス ## フリーダイヤル お気軽にお電話くださいませ(sparkle) 10:30〜20:00 年中無休 オンライン買取も受付中 https://kinkaimasu.jp/online-promise/?openExternalBrowser=1&utm_source=LINE ## (smartphone) 電話番号 0120-954-679 ## (LINE messenger) LINE通話 https://lin.ee/c6inM4V """ # 査定用のプロンプト promps,prompt_res = prompt_genalate("返信は日本語で答えて下さい "+text,prompt2) #test_set_lide(text,"a1") #no_process_file(text, "ai") #\r\m ######################################################################### #user_name,thmbnail# title = f""" {user_name}様から下記の質問があります""" subtitle = f"""ユーザーID {user_id}\r\n 質問内容\r\n {text}""" link_text = "\r\nチャットボット設定用シート\r\n シート用のアプリはチャットから\r\n @リファペディア\r\n と打ち込むと開きます" link_url = "https://docs.google.com/spreadsheets/d/13pqP-Ywo5eRlZBsYX2m3ChARG38EoIYOowFd3cWij1c/edit?gid=283940886#gid=283940886" #test_set_lide(subtitle, text) thread_name = send_google_chat_card(webhook_url, title, subtitle, link_text, link_url,thmbnail) from command.n8n import post_data import time n8nurl = os.getenv("n8nhook") post_data(n8nurl,text,thread_name) time.sleep(10) ######################################################################### title = f""" プロンプト作成 {promps}""" subtitle = f"""userid {user_id}\r\n chatid {thread_name}\r\n{prompt_res}""" link_text = "データを確認する" link_url = "https://kenken999-php.hf.space/diamondprice_list.php" #test_set_lide(subtitle, text) if DEBUG==0: thread_name = send_google_chat_card_thread(webhook_url, title, subtitle, link_text, link_url,thread_name) #thread_name = send_google_chat_card_thread(webhook_url, title, subtitle, link_text, link_url,thread_name) #return #test case ######################################################################### first_line = text.split('\n')[0] #test_prompt res = test_prompt("返信は必ず日本語でして下さい \r\n"+prompt_res,text) if DEBUG==0: thread_name = send_google_chat_card_thread(webhook_url, "プロンプトテスト "+first_line, str(res), link_text, link_url,thread_name) #thread_name = send_google_chat_card_thread(webhook_url, title, subtitle, link_text, link_url,thread_name) now = datetime.now() yyyymmddhis = now.strftime('%Y%m%d%H%M%S') prompt_for_create_system = """ 下記の質問に対応するコードをdjangoでアプリを作成 プロジェクトはいりません fastapiでrouter部分を作成 組み込みはメイン部分でします フロントエンドをgradioで作成 #google apps script frontend googleappsscript doGet でのgradioの表示処理を作成 google.script.runで関数は呼び出し #google apps script backend frontendからの呼び出し用のバックエンドスクリプト 仕様書の作成 PlantUMLでシーケンス図の作成 Markdownでのプログラム殺名 #下記参考にAPIも作成しておいて action insert list edit update でCRUDがかわる 同じようにGASのAPIも作成しておいて def create_vector(): inputs = tokenizer(result, return_tensors="pt", max_length=512, truncation=True) outputs = model(**inputs) # [CLS]トークンの出力を取得 embeddings = outputs.last_hidden_state[:,0,:].squeeze().detach().cpu().numpy().tolist() print(embeddings) import requests url = "https://kenken999-php.hf.space/api/v1.php" payload = "model_name={embeddings}&vector_text={result}&table=products&action=insert"" headers = { 'X-Auth-Token': 'admin', 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': 'runnerSession=muvclb78zpsdjbm7y9c3; pD1lszvk6ratOZhmmgvkp=13767810ebf0782b0b51bf72dedb63b3' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) return True 下記の質問 作成対応内容 """ ######################################################################### ## excute create program res_no_process = no_process_file(prompt_for_create_system+res, "gpt_enginner"+ yyyymmddhis,thread_name) # execute open interpreter ######################################################################### full_response,history = chat_with_interpreter_no_stream(prompt_for_create_system+"\r\n"+res) if DEBUG==1: thread_name = send_google_chat_card_thread(webhook_url, f"自動設定開始 {res}", str(full_response), link_text, link_url,thread_name) ######################################################################### #ダイヤ金額計算 from babyagi.classesa.diamond import calculate title = f""" ダイヤ予測計算の実行 類似5件表示 {text} id,price,carat, cut, color, clarity, depth, diamondprice.table, x, y, z 類似度""" res_calculate = calculate(text) subtitle = res_calculate link_text = "データを確認する" link_url = "https://kenken999-php.hf.space/diamondprice_list.php" #test_set_lide(subtitle, text) if DEBUG==0: thread_name = send_google_chat_card_thread(webhook_url, title, subtitle, link_text, link_url,thread_name) ######################################################################### from babyagi.babyagi import completion #import tempfile text = text.replace("\r\n","") # コマンドを構築 command = f"""make runbabyagi "{text}に対して、より良いチャットボットでのQAプランデータ設定の提案を日本語で作成してください" {thread_name}""" with open('/home/user/app/babyagi/prompt.txt', 'w') as file: file.write(f"""{text}の質問 についてチャットボットでよりよく対応するプランを日本語で作成して""") # proc = subprocess.Popen( ["make", "runbabyagi", thread_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, ) #await asyncio.sleep(30) """ proc = subprocess.Popen( command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True ) """ #prompt_res_agi = completion("日本語で下記のプランを考えて "+res) #thread_name = send_google_chat_card_thread(webhook_url, title, prompt_res_agi, link_text, link_url,thread_name) #title = f""" タスク作成 再度考える {promps}""" #subtitle = prompt_res_agi #link_text = "データを確認する" #link_url = "https://kenken999-php.hf.space/diamondprice_list.php" #thread_name = send_google_chat_card_thread(webhook_url, title, prompt_res_agi, link_text, link_url,thread_name) #send_google_chat_card(webhook_url, title, subtitle, link_text, link_url) #return #return #return """ for event in events: if event["type"] == "message" and event["message"]["type"] == "text": user_id = event["source"]["userId"] text = event["message"]["text"] logger.info(event) logger.info(f"User ID: {user_id}, Text: {text}") now = datetime.now().strftime("%Y%m%d%H%M%S") title = text[:10] user_id_with_timestamp = title#f"{now}_{title}_{user_id}" no_process_file(text, user_id_with_timestamp) #db登録 test_set_lide(text, user_id_with_timestamp) """ logger.info("Received Headers: %s", received_headers) logger.info("Received Body: %s", body.decode("utf-8")) ############################################################################### #send to appsheet get_senario("user_id",str(body)) #apps script send headers = { "Content-Type": "application/json", } logger.info("Received Body: %s", "send data to appsheet ") #response = requests.post(os.getenv("WEBHOOK_URL"), headers=headers, data=body) # check signature line_signature = received_headers.get("x-line-signature") logger.info("Received Body: %s", "start send messages ") #headers = { # "Content-Type": "application/json", # "X-Line-Signature": line_signature, # "Authorization": f"Bearer {os.getenv('ChannelAccessToken')}", # } #r#esponse = requests.post(os.getenv("WEBHOOK_URL"), headers=headers, data=body) if not line_signature: raise HTTPException(status_code=400, detail="X-Line-Signature header is missing.") if not validate_signature(body.decode("utf-8"), line_signature, os.getenv("ChannelSecret")): raise HTTPException(status_code=400, detail="Invalid signature.") if not os.getenv("WEBHOOK_URL") or not os.getenv("WEBHOOK_URL").startswith("https://"): raise HTTPException(status_code=400, detail="Invalid webhook URL") headers = { "Content-Type": "application/json", "X-Line-Signature": line_signature, "Authorization": f"Bearer {os.getenv('ChannelAccessToken')}", } logger.info("Forwarding to URL: %s", os.getenv("WEBHOOK_URL")) logger.info("Forwarding Headers: %s", headers) logger.info("Forwarding Body: %s", body.decode("utf-8")) #response = requests.post(os.getenv("WEBHOOK_URL"), headers=headers, data=body) responses = requests.post(os.getenv("WEBHOOK_GAS"), headers=headers, data=body) logger.info("Response Code: %s", response.status_code) logger.info("Response Content: %s", response.text) logger.info("Response Headers: %s", response.headers) return {"status": "success", "response_content": response.text}#, response.status_code except Exception as e: error_file = os.path.basename(__file__) # ファイル名を取得 error_line = sys._getframe(1).f_lineno # 行番号を取得 print(f"Error occurred at file {error_file} on line {error_line}: {str(e)}") #エラー内容の分析 promps,res = prompt_genalate(str(e)) #test_set_lide(text,"a1") #no_process_file(text, "ai") custormer_supportpage = "\r\n カスタマーサポートはこちらから \r\n https://bpmboxesscom-46463613.hubspotpagebuilder.com/ja \r\n " title = f"""エラーが起こりました -+errer file is {error_file} error line is {error_line} {str(e)} 自動修復の開始 """ subtitle = custormer_supportpage+res link_text = "test" link_url = "url" #test_set_lide(subtitle, text) logger.error(res) #send error to google chat send_google_chat_card_thread(webhook_url, title, subtitle, link_text, link_url,thread_name) logger.error("Error: %s", str(e)) #raise するとシステムとまるのでアンコメント #raise HTTPException(status_code=500, detail=str(e)) return {"status": "success", "response_content": str(e)}#, response.status_code