#!/usr/bin/env python3 """ send_message.py - 发送飞书消息(Python 版本,自动处理 JSON 转义) 用法: python3 send_message.py [msg_type] 示例: python3 send_message.py oc_xxxxxx "Hello World" python3 send_message.py oc_xxxxxx "{\"text\":\"Hello\"}" text python3 send_message.py oc_xxxxxx "{\"title\":\"Title\",\"content\":\"Body\"}" post """ import json import sys import os import urllib.request def get_token(): """获取 tenant_access_token""" app_id = os.environ.get('FEISHU_APP_ID', 'cli_a91b01debab81cd1') app_secret = os.environ.get('FEISHU_APP_SECRET') if not app_secret: # 尝试从 .env 文件读取 env_file = os.path.expanduser('~/.hermes/.env') if os.path.exists(env_file): with open(env_file, 'r') as f: for line in f: if line.startswith('FEISHU_APP_SECRET='): app_secret = line.split('=', 1)[1].strip() break if not app_secret: print("Error: FEISHU_APP_SECRET not found") sys.exit(1) token_data = json.dumps({ "app_id": app_id, "app_secret": app_secret }).encode('utf-8') token_req = urllib.request.Request( 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', data=token_data, headers={'Content-Type': 'application/json'}, method='POST' ) with urllib.request.urlopen(token_req, timeout=30) as response: token_result = json.loads(response.read().decode('utf-8')) if token_result.get('code') != 0: print(f"Error getting token: {token_result}") sys.exit(1) return token_result['tenant_access_token'] def send_message(chat_id, message, msg_type='text'): """发送消息到飞书""" token = get_token() # 处理 content 格式 if msg_type == 'text': # 如果 message 已经是 JSON 字符串,直接使用 try: json.loads(message) content = message except json.JSONDecodeError: # 否则包装为 JSON 字符串 content = json.dumps({"text": message}) elif msg_type == 'post': try: json.loads(message) content = message except json.JSONDecodeError: content = json.dumps({ "zh_cn": { "title": message, "content": [[{"tag": "text", "text": message}]] } }) elif msg_type == 'interactive': # 卡片消息,必须是 JSON 字符串 try: json.loads(message) content = message except json.JSONDecodeError: print("Error: interactive message must be valid JSON") sys.exit(1) else: content = message message_data = { "receive_id": chat_id, "msg_type": msg_type, "content": content } msg_req = urllib.request.Request( 'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id', data=json.dumps(message_data).encode('utf-8'), headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' }, method='POST' ) with urllib.request.urlopen(msg_req, timeout=30) as response: result = json.loads(response.read().decode('utf-8')) if result.get('code') == 0: print(f"✅ Message sent successfully!") print(f"Message ID: {result['data']['message_id']}") else: print(f"❌ Error: {result.get('msg', 'Unknown error')}") print(f"Full response: {json.dumps(result, indent=2, ensure_ascii=False)}") sys.exit(1) def main(): if len(sys.argv) < 3: print("Usage: python3 send_message.py [msg_type]") print(" msg_type: text (default), post, interactive") sys.exit(1) chat_id = sys.argv[1] message = sys.argv[2] msg_type = sys.argv[3] if len(sys.argv) > 3 else 'text' send_message(chat_id, message, msg_type) if __name__ == '__main__': main()