#!/usr/bin/env python3 """ Daily Task Sync - Read WIP tasks from Feishu Bitable """ import os import sys import requests import json sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) def load_env(): """Load environment from bashrc""" bashrc = os.path.expanduser("~/.bashrc") if os.path.exists(bashrc): with open(bashrc) as f: for line in f: line = line.strip() if line.startswith("export ") and "=" in line: key = line.replace("export ", "", 1).split("=")[0].strip() value = line.split("=", 1)[1].strip().strip('"').strip("'") os.environ[key] = value load_env() def get_feishu_token(): """Get Feishu token""" app_id = os.environ.get("CRONJOB_TEAM_WORKFLOW_APP_ID") app_secret = os.environ.get("CRONJOB_TEAM_WORKFLOW_APP_SECRET") if not app_id or not app_secret: print("Error: Missing CRONJOB_TEAM_WORKFLOW_APP_ID or CRONJOB_TEAM_WORKFLOW_APP_SECRET") return None try: resp = requests.post( "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", headers={"Content-Type": "application/json"}, json={"app_id": app_id, "app_secret": app_secret}, timeout=10 ) data = resp.json() if data.get("code") == 0: return data.get("tenant_access_token") except Exception as e: print(f"Error getting token: {e}") return None def get_wip_tasks(token): """Get WIP tasks from Bitable""" app_token = "Fll0wfrEbiLvUfk4QagcBXi0n0g" table_id = "tblDPojnEEtedjIA" resp = requests.get( f"https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records", headers={"Authorization": f"Bearer {token}"}, timeout=30 ) records = resp.json().get("data", {}).get("items", []) tasks_by_owner = {} for record in records: fields = record.get("fields", {}) owner_list = fields.get("Owner", []) owner_name = owner_list[0].get("en_name", "Unknown") if owner_list else "Unknown" task_name = fields.get("Task", "") status = fields.get("Status", {}) status_name = status.get("name", "") if isinstance(status, dict) else str(status) if task_name and "WIP" in str(status_name): if owner_name not in tasks_by_owner: tasks_by_owner[owner_name] = [] tasks_by_owner[owner_name].append(task_name) return tasks_by_owner WIKI_LINK = "https://pingcap.feishu.cn/wiki/Fll0wfrEbiLvUfk4QagcBXi0n0g" def format_message(tasks_by_owner): """Format message""" lines = ["📋 Daily WIP Tasks\n"] lines.append(f"📄 Doc: {WIKI_LINK}\n") for owner, tasks in tasks_by_owner.items(): lines.append(f"👤 {owner} ({len(tasks)} tasks)") for t in tasks: lines.append(f" • {t}") lines.append("") return "\n".join(lines) def send_feishu_message(token, receive_id, message): """Send message to Feishu""" receive_id_type = "open_id" if receive_id.startswith("ou_") else "chat_id" payload = { "receive_id": receive_id, "msg_type": "text", "content": json.dumps({"text": message}) } resp = requests.post( f"https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type={receive_id_type}", headers={ "Authorization": f"Bearer {token}", "Content-Type": "application/json" }, json=payload, timeout=30 ) return resp.json() def main(): print("=== Daily Task Sync ===") token = get_feishu_token() if not token: print("Error: Cannot get Feishu token") return print("Fetching WIP tasks...") tasks_by_owner = get_wip_tasks(token) print(f"Found {len(tasks_by_owner)} owners with WIP tasks") message = format_message(tasks_by_owner) # Send to user (for testing) or group receive_id = "oc_2c586abb5204eca2ddf6ddf5de338bf6" print(f"Sending to {receive_id}...") result = send_feishu_message(token, receive_id, message) print(f"Result: {result}") print("Done!") if __name__ == "__main__": main()