Spaces:
Running
Running
| import os | |
| import time | |
| import json | |
| import requests | |
| # ===== Channel.io 設定 ===== | |
| CHANNEL_ID = "200605" | |
| GROUP_ID = "534868" | |
| ASSISTANT_PERSON_ID = "595702" | |
| MESSAGES_URL = f"https://desk-api.channel.io/desk/channels/{CHANNEL_ID}/groups/{GROUP_ID}/messages" | |
| X_ACCOUNT = os.getenv("channeliotokenbot2") | |
| if not X_ACCOUNT: | |
| raise RuntimeError("環境変数 channeliotokenbot2 が設定されていません") | |
| HEADERS = { | |
| "accept": "application/json", | |
| "accept-language": "ja", | |
| "content-type": "application/json", | |
| "x-account": X_ACCOUNT, | |
| } | |
| PARAMS = { | |
| "sortOrder": "desc", | |
| "limit": 50, | |
| } | |
| # ===== GPT API ===== | |
| GPT_API_URL = "https://izuemon-gpt-free-api.hf.space/v1/chat/completions" | |
| # ===== Utils ===== | |
| def get_messages(): | |
| res = requests.get( | |
| MESSAGES_URL, | |
| headers=HEADERS, | |
| params=PARAMS, | |
| timeout=30, | |
| ) | |
| res.raise_for_status() | |
| return res.json().get("messages", []) | |
| def build_chat_messages(messages): | |
| """ | |
| Channel.io の messages から | |
| ChatGPT 互換 messages を生成 | |
| """ | |
| chat_messages = [] | |
| # 古い順に並び替え | |
| messages = sorted( | |
| messages, | |
| key=lambda m: m.get("createdAt", 0) | |
| ) | |
| for msg in messages: | |
| plain = msg.get("plainText") | |
| if not plain: | |
| continue | |
| role = ( | |
| "assistant" | |
| if str(msg.get("personId")) == ASSISTANT_PERSON_ID | |
| else "user" | |
| ) | |
| chat_messages.append({ | |
| "role": role, | |
| "content": plain | |
| }) | |
| return chat_messages | |
| def call_gpt(chat_messages): | |
| payload = { | |
| "model": "gpt-3.5-turbo", | |
| "messages": chat_messages, | |
| } | |
| res = requests.post( | |
| GPT_API_URL, | |
| headers={"Content-Type": "application/json"}, | |
| data=json.dumps(payload), | |
| timeout=60, | |
| ) | |
| res.raise_for_status() | |
| data = res.json() | |
| return data["choices"][0]["message"]["content"] | |
| def send_to_channel(text): | |
| payload = { | |
| "requestId": f"desk-web-{int(time.time() * 1000)}", | |
| "blocks": [ | |
| {"type": "text", "value": text} | |
| ], | |
| } | |
| res = requests.post( | |
| MESSAGES_URL, | |
| headers=HEADERS, | |
| data=json.dumps(payload), | |
| timeout=30, | |
| ) | |
| res.raise_for_status() | |
| # ===== Main Loop ===== | |
| def main(): | |
| last_processed_id = None | |
| while True: | |
| try: | |
| messages = get_messages() | |
| if not messages: | |
| time.sleep(10) | |
| continue | |
| # 最新メッセージ(createdAt 最大) | |
| latest = max( | |
| messages, | |
| key=lambda m: m.get("createdAt", 0) | |
| ) | |
| latest_id = latest.get("id") | |
| latest_person = str(latest.get("personId")) | |
| latest_text = latest.get("plainText") | |
| # 空メッセージは無視 | |
| if not latest_text: | |
| time.sleep(10) | |
| continue | |
| # 既に処理済み | |
| if latest_id == last_processed_id: | |
| time.sleep(10) | |
| continue | |
| # 最後が GPT(595702)なら何もしない | |
| if latest_person == ASSISTANT_PERSON_ID: | |
| time.sleep(10) | |
| continue | |
| # GPT に送信 | |
| chat_messages = build_chat_messages(messages) | |
| gpt_reply = call_gpt(chat_messages) | |
| # Channel.io に返信 | |
| send_to_channel(gpt_reply) | |
| last_processed_id = latest_id | |
| print("送信完了") | |
| except Exception as e: | |
| print("エラー:", e) | |
| import traceback | |
| traceback.print_exc() | |
| time.sleep(15) | |
| if __name__ == "__main__": | |
| main() | |