{
  "schemaVersion": "1.0",
  "item": {
    "slug": "feishu-interactive-cards",
    "name": "Feishu Interactive Cards",
    "source": "tencent",
    "type": "skill",
    "category": "通讯协作",
    "sourceUrl": "https://clawhub.ai/leecyang/feishu-interactive-cards",
    "canonicalUrl": "https://clawhub.ai/leecyang/feishu-interactive-cards",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/feishu-interactive-cards",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=feishu-interactive-cards",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "CHANGELOG.md",
      "examples/confirmation-card.json",
      "examples/form-card.json",
      "examples/poll-card.json",
      "examples/todo-card.json",
      "package.json"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/feishu-interactive-cards"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/feishu-interactive-cards",
    "agentPageUrl": "https://openagent3.xyz/skills/feishu-interactive-cards/agent",
    "manifestUrl": "https://openagent3.xyz/skills/feishu-interactive-cards/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/feishu-interactive-cards/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Core Principle",
        "body": "When replying to Feishu and there is ANY uncertainty: send an interactive card instead of plain text.\n\nInteractive cards let users respond via buttons rather than typing, making interactions faster and clearer."
      },
      {
        "title": "When to Use",
        "body": "Must use interactive cards:\n\nUser needs to make a choice (yes/no, multiple options)\nConfirmation required before action\nDisplaying todos or task lists\nCreating polls or surveys\nCollecting form input\nAny uncertain situation\n\nPlain text is OK:\n\nSimple notifications (no response needed)\nPure data display (no interaction)\nConfirmed command results\n\nExample:\n\nWrong: \"I deleted the file for you\" (direct execution)\nRight: Send card \"Confirm delete file?\" [Confirm] [Cancel]"
      },
      {
        "title": "1. Start Callback Server (Long-Polling Mode)",
        "body": "cd E:\\openclaw\\workspace\\skills\\feishu-interactive-cards\\scripts\nnode card-callback-server.js\n\nFeatures:\n\nUses Feishu long-polling (no public IP needed)\nAuto-reconnects\nSends callbacks to OpenClaw Gateway automatically"
      },
      {
        "title": "2. Send Interactive Card",
        "body": "# Confirmation card\nnode scripts/send-card.js confirmation \"Confirm delete file?\" --chat-id oc_xxx\n\n# Todo list\nnode scripts/send-card.js todo --chat-id oc_xxx\n\n# Poll\nnode scripts/send-card.js poll \"Team activity\" --options \"Bowling,Movie,Dinner\" --chat-id oc_xxx\n\n# Custom card\nnode scripts/send-card.js custom --template examples/custom-card.json --chat-id oc_xxx"
      },
      {
        "title": "3. Use in Agent",
        "body": "When Agent needs to send Feishu messages:\n\n// Wrong: Send plain text\nawait message({ \n  action: \"send\", \n  channel: \"feishu\", \n  message: \"Confirm delete?\" \n});\n\n// Right: Send interactive card\nawait exec({\n  command: `node E:\\\\openclaw\\\\workspace\\\\skills\\\\feishu-interactive-cards\\\\scripts\\\\send-card.js confirmation \"Confirm delete file test.txt?\" --chat-id ${chatId}`\n});"
      },
      {
        "title": "Card Templates",
        "body": "See examples/ directory for complete card templates:\n\nconfirmation-card.json - Confirmation dialogs\ntodo-card.json - Task lists with checkboxes\npoll-card.json - Polls and surveys\nform-card.json - Forms with input fields\n\nFor detailed card design patterns and best practices, see references/card-design-guide.md."
      },
      {
        "title": "Callback Handling",
        "body": "Callback server automatically sends all card interactions to OpenClaw Gateway. For detailed integration guide, see references/gateway-integration.md.\n\nQuick example:\n\n// Handle confirmation\nif (callback.data.action.value.action === \"confirm\") {\n  const file = callback.data.action.value.file;\n  \n  // ⚠️ SECURITY: Validate and sanitize file path before use\n  // Use OpenClaw's built-in file operations instead of shell commands\n  const fs = require('fs').promises;\n  const path = require('path');\n  \n  try {\n    // Validate file path (prevent directory traversal)\n    const safePath = path.resolve(file);\n    if (!safePath.startsWith(process.cwd())) {\n      throw new Error('Invalid file path');\n    }\n    \n    // Use fs API instead of shell command\n    await fs.unlink(safePath);\n    \n    // Update card\n    await updateCard(callback.context.open_message_id, {\n      header: { title: \"Done\", template: \"green\" },\n      elements: [\n        { tag: \"div\", text: { content: `File ${path.basename(safePath)} deleted`, tag: \"lark_md\" } }\n      ]\n    });\n  } catch (error) {\n    // Handle error\n    await updateCard(callback.context.open_message_id, {\n      header: { title: \"Error\", template: \"red\" },\n      elements: [\n        { tag: \"div\", text: { content: `Failed to delete file: ${error.message}`, tag: \"lark_md\" } }\n      ]\n    });\n  }\n}"
      },
      {
        "title": "Card Design",
        "body": "Clear titles and content\nObvious button actions\nUse danger type for destructive operations\nCarry complete state in button value to avoid extra queries"
      },
      {
        "title": "Interaction Flow",
        "body": "User request -> Agent decides -> Send card -> User clicks button \n-> Callback server -> Gateway -> Agent handles -> Update card/execute"
      },
      {
        "title": "Error Handling",
        "body": "Timeout: Send reminder if user doesn't respond\nDuplicate clicks: Built-in deduplication (3s window)\nFailures: Update card to show error message"
      },
      {
        "title": "Performance",
        "body": "Async processing: Quick response, long tasks in background\nBatch operations: Combine related actions in one card"
      },
      {
        "title": "Configuration",
        "body": "Configure in ~/.openclaw/openclaw.json:\n\n{\n  \"channels\": {\n    \"feishu\": {\n      \"accounts\": {\n        \"main\": {\n          \"appId\": \"YOUR_APP_ID\",\n          \"appSecret\": \"YOUR_APP_SECRET\"\n        }\n      }\n    }\n  },\n  \"gateway\": {\n    \"enabled\": true,\n    \"port\": 18789,\n    \"token\": \"YOUR_GATEWAY_TOKEN\"\n  }\n}\n\nCallback server reads config automatically."
      },
      {
        "title": "Troubleshooting",
        "body": "Button clicks not working:\n\nCheck callback server is running\nVerify Feishu backend uses \"long-polling\" mode\nEnsure card.action.trigger event is subscribed\n\nGateway not receiving callbacks:\n\nStart Gateway: E:\\openclaw\\workspace\\scripts\\gateway.cmd\nCheck token in ~/.openclaw\\openclaw.json\n\nCard display issues:\n\nUse provided templates as base\nValidate JSON format\nCheck required fields"
      },
      {
        "title": "Security",
        "body": "⚠️ CRITICAL: Never pass user input directly to shell commands!\n\nThis skill includes comprehensive security guidelines. Please read references/security-best-practices.md before implementing callback handlers.\n\nKey security principles:\n\nAlways validate and sanitize user input\nUse Node.js built-in APIs instead of shell commands\nImplement proper permission checks\nPrevent command injection vulnerabilities\nUse event_id for deduplication"
      },
      {
        "title": "References",
        "body": "Security Best Practices - READ THIS FIRST!\nFeishu Card Documentation\nOpenClaw Docs"
      }
    ],
    "body": "Feishu Interactive Cards\nCore Principle\n\nWhen replying to Feishu and there is ANY uncertainty: send an interactive card instead of plain text.\n\nInteractive cards let users respond via buttons rather than typing, making interactions faster and clearer.\n\nWhen to Use\n\nMust use interactive cards:\n\nUser needs to make a choice (yes/no, multiple options)\nConfirmation required before action\nDisplaying todos or task lists\nCreating polls or surveys\nCollecting form input\nAny uncertain situation\n\nPlain text is OK:\n\nSimple notifications (no response needed)\nPure data display (no interaction)\nConfirmed command results\n\nExample:\n\nWrong: \"I deleted the file for you\" (direct execution)\nRight: Send card \"Confirm delete file?\" [Confirm] [Cancel]\nQuick Start\n1. Start Callback Server (Long-Polling Mode)\ncd E:\\openclaw\\workspace\\skills\\feishu-interactive-cards\\scripts\nnode card-callback-server.js\n\n\nFeatures:\n\nUses Feishu long-polling (no public IP needed)\nAuto-reconnects\nSends callbacks to OpenClaw Gateway automatically\n2. Send Interactive Card\n# Confirmation card\nnode scripts/send-card.js confirmation \"Confirm delete file?\" --chat-id oc_xxx\n\n# Todo list\nnode scripts/send-card.js todo --chat-id oc_xxx\n\n# Poll\nnode scripts/send-card.js poll \"Team activity\" --options \"Bowling,Movie,Dinner\" --chat-id oc_xxx\n\n# Custom card\nnode scripts/send-card.js custom --template examples/custom-card.json --chat-id oc_xxx\n\n3. Use in Agent\n\nWhen Agent needs to send Feishu messages:\n\n// Wrong: Send plain text\nawait message({ \n  action: \"send\", \n  channel: \"feishu\", \n  message: \"Confirm delete?\" \n});\n\n// Right: Send interactive card\nawait exec({\n  command: `node E:\\\\openclaw\\\\workspace\\\\skills\\\\feishu-interactive-cards\\\\scripts\\\\send-card.js confirmation \"Confirm delete file test.txt?\" --chat-id ${chatId}`\n});\n\nCard Templates\n\nSee examples/ directory for complete card templates:\n\nconfirmation-card.json - Confirmation dialogs\ntodo-card.json - Task lists with checkboxes\npoll-card.json - Polls and surveys\nform-card.json - Forms with input fields\n\nFor detailed card design patterns and best practices, see references/card-design-guide.md.\n\nCallback Handling\n\nCallback server automatically sends all card interactions to OpenClaw Gateway. For detailed integration guide, see references/gateway-integration.md.\n\nQuick example:\n\n// Handle confirmation\nif (callback.data.action.value.action === \"confirm\") {\n  const file = callback.data.action.value.file;\n  \n  // ⚠️ SECURITY: Validate and sanitize file path before use\n  // Use OpenClaw's built-in file operations instead of shell commands\n  const fs = require('fs').promises;\n  const path = require('path');\n  \n  try {\n    // Validate file path (prevent directory traversal)\n    const safePath = path.resolve(file);\n    if (!safePath.startsWith(process.cwd())) {\n      throw new Error('Invalid file path');\n    }\n    \n    // Use fs API instead of shell command\n    await fs.unlink(safePath);\n    \n    // Update card\n    await updateCard(callback.context.open_message_id, {\n      header: { title: \"Done\", template: \"green\" },\n      elements: [\n        { tag: \"div\", text: { content: `File ${path.basename(safePath)} deleted`, tag: \"lark_md\" } }\n      ]\n    });\n  } catch (error) {\n    // Handle error\n    await updateCard(callback.context.open_message_id, {\n      header: { title: \"Error\", template: \"red\" },\n      elements: [\n        { tag: \"div\", text: { content: `Failed to delete file: ${error.message}`, tag: \"lark_md\" } }\n      ]\n    });\n  }\n}\n\nBest Practices\nCard Design\nClear titles and content\nObvious button actions\nUse danger type for destructive operations\nCarry complete state in button value to avoid extra queries\nInteraction Flow\nUser request -> Agent decides -> Send card -> User clicks button \n-> Callback server -> Gateway -> Agent handles -> Update card/execute\n\nError Handling\nTimeout: Send reminder if user doesn't respond\nDuplicate clicks: Built-in deduplication (3s window)\nFailures: Update card to show error message\nPerformance\nAsync processing: Quick response, long tasks in background\nBatch operations: Combine related actions in one card\nConfiguration\n\nConfigure in ~/.openclaw/openclaw.json:\n\n{\n  \"channels\": {\n    \"feishu\": {\n      \"accounts\": {\n        \"main\": {\n          \"appId\": \"YOUR_APP_ID\",\n          \"appSecret\": \"YOUR_APP_SECRET\"\n        }\n      }\n    }\n  },\n  \"gateway\": {\n    \"enabled\": true,\n    \"port\": 18789,\n    \"token\": \"YOUR_GATEWAY_TOKEN\"\n  }\n}\n\n\nCallback server reads config automatically.\n\nTroubleshooting\n\nButton clicks not working:\n\nCheck callback server is running\nVerify Feishu backend uses \"long-polling\" mode\nEnsure card.action.trigger event is subscribed\n\nGateway not receiving callbacks:\n\nStart Gateway: E:\\openclaw\\workspace\\scripts\\gateway.cmd\nCheck token in ~/.openclaw\\openclaw.json\n\nCard display issues:\n\nUse provided templates as base\nValidate JSON format\nCheck required fields\nSecurity\n\n⚠️ CRITICAL: Never pass user input directly to shell commands!\n\nThis skill includes comprehensive security guidelines. Please read references/security-best-practices.md before implementing callback handlers.\n\nKey security principles:\n\nAlways validate and sanitize user input\nUse Node.js built-in APIs instead of shell commands\nImplement proper permission checks\nPrevent command injection vulnerabilities\nUse event_id for deduplication\nReferences\nSecurity Best Practices - READ THIS FIRST!\nFeishu Card Documentation\nOpenClaw Docs"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/leecyang/feishu-interactive-cards",
    "publisherUrl": "https://clawhub.ai/leecyang/feishu-interactive-cards",
    "owner": "leecyang",
    "version": "1.0.2",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/feishu-interactive-cards",
    "downloadUrl": "https://openagent3.xyz/downloads/feishu-interactive-cards",
    "agentUrl": "https://openagent3.xyz/skills/feishu-interactive-cards/agent",
    "manifestUrl": "https://openagent3.xyz/skills/feishu-interactive-cards/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/feishu-interactive-cards/agent.md"
  }
}