$ cat node-template.py

L

Lark Update Task

// Updates an existing Lark task. Can modify title, description, due/start dates, and mark tasks as complete. Only provided fields are updated.

Process
Integration
template.py
1import os2import sys3import json4import traceback56try:7    import requests8except ImportError:9    import subprocess10    subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])11    import requests1213LARK_BASE_URL = "https://open.larksuite.com/open-apis"141516def get_lark_token():17    # Prefer user token (OAuth — sees user's resources)18    user_token = os.getenv("LARK_USER_TOKEN")19    if user_token:20        return user_token2122    # Fallback to tenant token (app-level — limited visibility)23    app_id = os.getenv("LARK_APP_ID")24    app_secret = os.getenv("LARK_APP_SECRET")25    if not app_id or not app_secret:26        raise ValueError(27            "Lark is not connected. Add LARK_APP_ID and LARK_APP_SECRET as workspace secrets, "28            "then connect via workspace settings to authorize user access."29        )30    resp = requests.post(31        f"{LARK_BASE_URL}/auth/v3/tenant_access_token/internal",32        json={"app_id": app_id, "app_secret": app_secret},33    )34    resp.raise_for_status()35    data = resp.json()36    if data.get("code") != 0:37        raise ValueError(f"Lark auth failed: {data.get('msg')}")38    return data["tenant_access_token"]394041def lark_request(method, path, **kwargs):42    token = get_lark_token()43    headers = {44        "Authorization": f"Bearer {token}",45        "Content-Type": "application/json; charset=utf-8",46    }47    resp = requests.request(48        method, f"{LARK_BASE_URL}{path}", headers=headers, **kwargs49    )50    resp.raise_for_status()51    data = resp.json()52    if data.get("code") != 0:53        raise ValueError(f"Lark API error ({data['code']}): {data.get('msg')}")54    return data555657def main():58    try:59        inputs = json.loads(sys.stdin.read()).get("inputs", {})6061        task_guid = inputs.get("taskGuid", "").strip()62        if not task_guid:63            raise ValueError("taskGuid is required")6465        # Build the update payload with update_fields66        task_update = {}67        update_fields = []6869        summary = inputs.get("summary", "").strip()70        if summary:71            task_update["summary"] = summary72            update_fields.append("summary")7374        description = inputs.get("description", "").strip()75        if description:76            task_update["description"] = description77            update_fields.append("description")7879        due = inputs.get("due", "").strip()80        if due:81            task_update["due"] = {"timestamp": due, "is_all_day": False}82            update_fields.append("due")8384        start = inputs.get("start", "").strip()85        if start:86            task_update["start"] = {"timestamp": start, "is_all_day": False}87            update_fields.append("start")8889        completed = inputs.get("completed", False)90        task = {}9192        # Apply field updates if any93        if update_fields:94            body = {"task": task_update, "update_fields": update_fields}95            result = lark_request(96                "PATCH", f"/task/v2/tasks/{task_guid}", json=body97            )98            task = result.get("data", {}).get("task", {})99100        # Mark as complete if requested101        if completed:102            result = lark_request(103                "POST", f"/task/v2/tasks/{task_guid}/complete", json={}104            )105            task = result.get("data", {}).get("task", task)106107        # If nothing was updated, just fetch current state108        if not update_fields and not completed:109            result = lark_request("GET", f"/task/v2/tasks/{task_guid}")110            task = result.get("data", {}).get("task", {})111112        output = {113            "task": task,114            "success": True,115        }116        print(json.dumps(output, indent=2, ensure_ascii=False))117118    except Exception as e:119        error_output = {120            "error": str(e),121            "errorType": type(e).__name__,122            "traceback": traceback.format_exc(),123        }124        print(json.dumps(error_output), file=sys.stderr)125        sys.exit(1)126127128if __name__ == "__main__":129    main()

$ git log --oneline

v1.0.1
HEAD
2026-05-07
v1.0.02026-04-09