|
from fastapi import FastAPI, Request |
|
import time |
|
import asyncio |
|
import json |
|
from dotenv import load_dotenv |
|
|
|
|
|
from redis_service import connect_redis, redis_subscriber, r as redis_client, publish_message as publish_to_redis |
|
from feishu_service import get_valid_tenant_access_token, send_feishu_reply |
|
|
|
load_dotenv() |
|
|
|
|
|
REDIS_CHANNEL_NAME = 'my_feishu_channel' |
|
|
|
app = FastAPI() |
|
|
|
|
|
@app.on_event("startup") |
|
async def startup_event(): |
|
|
|
await connect_redis() |
|
|
|
asyncio.create_task(redis_subscriber(redis_client, REDIS_CHANNEL_NAME)) |
|
print("Redis subscriber task started.") |
|
|
|
@app.get("/") |
|
def greet_json(): |
|
return {"Hello": "World!"} |
|
|
|
@app.post("/webhook/feishu") |
|
async def handle_webhook(request: Request): |
|
|
|
data = await request.json() |
|
|
|
|
|
if data.get('type') == "url_verification": |
|
|
|
print("Received URL verification request.") |
|
return {"challenge": data.get('challenge')} |
|
|
|
|
|
|
|
event = data.get('event', {}) |
|
message = event.get('message', {}) |
|
chat_type = message.get('chat_type') |
|
|
|
message_type = 'unknown' |
|
if chat_type == 'p2p': |
|
message_type = 'private' |
|
elif chat_type == 'group': |
|
if message.get('mentions'): |
|
message_type = 'group_mention' |
|
else: |
|
message_type = 'group_all' |
|
|
|
|
|
content_str = message.get('content') |
|
content_dict = {} |
|
if content_str: |
|
try: |
|
content_dict = json.loads(content_str) |
|
except json.JSONDecodeError: |
|
print(f"Warning: Could not parse message content as JSON: {content_str}") |
|
|
|
content_dict = {"text": content_str} |
|
|
|
ret_data = { |
|
'bot_id': data.get('header', {}).get('app_id'), |
|
'message_type': message_type, |
|
'original_msg_type': message.get('message_type'), |
|
'msg_id': message.get('message_id'), |
|
"content": content_dict, |
|
"sender": { |
|
"id": event.get('sender', {}).get('sender_id', {}).get('open_id'), |
|
"sender_type": event.get('sender', {}).get('sender_type'), |
|
"name": "", |
|
"is_human": None |
|
}, |
|
"timestamp": time.time(), |
|
"platform_specific": { |
|
"app_id": data.get('header', {}).get('app_id') |
|
} |
|
} |
|
|
|
|
|
await publish_to_redis(REDIS_CHANNEL_NAME, json.dumps(ret_data)) |
|
return {'status': 'OK'} |
|
|
|
|
|
|
|
|
|
@app.post("/publish") |
|
async def publish_message_route(request: Request): |
|
""" |
|
Publishes a message to a Redis channel via the redis_service. |
|
Expects JSON body with 'channel' and 'message'. |
|
""" |
|
try: |
|
data = await request.json() |
|
channel = data.get("channel") |
|
message = data.get("message") |
|
|
|
if not channel or not message: |
|
return {"status": "error", "message": "Missing channel or message"} |
|
|
|
|
|
result = await publish_to_redis(channel, message) |
|
return result |
|
|
|
except Exception as e: |
|
return {"status": "error", "message": str(e)} |
|
|