{
  "schemaVersion": "1.0",
  "item": {
    "slug": "lark-bot-listener",
    "name": "Pywayne Lark Bot Listener",
    "source": "tencent",
    "type": "skill",
    "category": "通讯协作",
    "sourceUrl": "https://clawhub.ai/wangyendt/lark-bot-listener",
    "canonicalUrl": "https://clawhub.ai/wangyendt/lark-bot-listener",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/lark-bot-listener",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=lark-bot-listener",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "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-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.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/lark-bot-listener"
    },
    "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/lark-bot-listener",
    "agentPageUrl": "https://openagent3.xyz/skills/lark-bot-listener/agent",
    "manifestUrl": "https://openagent3.xyz/skills/lark-bot-listener/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/lark-bot-listener/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": "Pywayne Lark Bot Listener",
        "body": "飞书消息监听器，通过 WebSocket 实时接收和处理飞书消息。"
      },
      {
        "title": "Quick Start",
        "body": "from pywayne.lark_bot_listener import LarkBotListener\n\n# 初始化监听器\nlistener = LarkBotListener(\n    app_id=\"your_app_id\",\n    app_secret=\"your_app_secret\",\n    message_expiry_time=60  # 消息去重过期时间（秒）\n)\n\n# 处理文本消息\n@listener.text_handler()\nasync def handle_text(text: str):\n    print(f\"收到消息: {text}\")\n\n# 启动监听\nlistener.run()"
      },
      {
        "title": "text_handler",
        "body": "文本消息处理装饰器，直接传递文本内容。\n\n@listener.text_handler(group_only=False, user_only=False)\nasync def handle_text(text: str, chat_id: str, is_group: bool, group_name: str, user_name: str):\n    print(f\"收到来自 {user_name} 的消息: {text}\")\n    listener.send_message(chat_id, f\"已收到：{text}\")\n\n参数说明（除 text 外均为可选）：\n\n参数类型说明textstr文本内容（必需）chat_idstr会话 IDis_groupbool是否群组消息group_namestr群组名称（私聊时为空）user_namestr发送消息的用户姓名\n\n装饰器参数：\n\ngroup_only=True: 只处理群组消息\nuser_only=True: 只处理私聊消息"
      },
      {
        "title": "image_handler",
        "body": "图片消息处理装饰器，自动下载图片到临时文件并清理。\n\nfrom pathlib import Path\nimport cv2\nimport tempfile\n\n@listener.image_handler()\nasync def handle_image(image_path: Path, user_name: str) -> Path:\n    # 处理图片\n    img = cv2.imread(str(image_path))\n    # ...处理逻辑...\n    # 返回新图片路径会自动发送回去，返回 None 则不发送\n    return image_path\n\n参数说明（除 image_path 外均为可选）：\n\n参数类型说明image_pathPath临时图片文件路径（必需）chat_idstr会话 IDis_groupbool是否群组消息group_namestr群组名称user_namestr发送消息的用户姓名\n\n返回值：\n\n返回 Path: 自动上传并发送新图片\n返回 None: 不发送任何图片"
      },
      {
        "title": "file_handler",
        "body": "文件消息处理装饰器，自动下载文件到临时文件并清理。\n\n@listener.file_handler()\nasync def handle_file(file_path: Path, user_name: str) -> Path:\n    # 处理文件\n    with open(file_path, 'r') as f:\n        content = f.read()\n    # ...处理逻辑...\n    return file_path  # 返回文件路径会自动发送回去\n\n参数说明（除 file_path 外均为可选）：\n\n参数类型说明file_pathPath临时文件路径（必需）chat_idstr会话 IDis_groupbool是否群组消息group_namestr群组名称user_namestr发送消息的用户姓名"
      },
      {
        "title": "listen - 通用消息监听器",
        "body": "用于监听任意类型消息（包括富文本 post）。\n\n@listener.listen(message_type=\"post\")\nasync def handle_post(ctx: MessageContext):\n    print(f\"收到富文本消息: {ctx.content}\")\n\nMessageContext 属性：\n\n属性类型说明chat_idstr会话 IDuser_idstr用户 IDmessage_typestr消息类型contentstr消息内容（文本消息为字符串，其他类型为 JSON 字符串）is_groupbool是否群组消息chat_typestr会话类型message_idstr消息 ID"
      },
      {
        "title": "send_message - 发送消息",
        "body": "发送 Markdown 格式的消息到飞书。\n\nlistener.send_message(chat_id, \"**这是加粗文本**\")\nlistener.send_message(chat_id, \"普通文本\\n[链接](https://example.com)\")"
      },
      {
        "title": "完整示例",
        "body": "from pywayne.lark_bot_listener import LarkBotListener\nfrom pathlib import Path\n\nlistener = LarkBotListener(\n    app_id=\"your_app_id\",\n    app_secret=\"your_app_secret\"\n)\n\n# 文本消息 - AI 回复示例\n@listener.text_handler()\nasync def handle_text(text: str, chat_id: str, user_name: str):\n    # 处理逻辑...\n    listener.send_message(chat_id, f\"收到来自 {user_name} 的消息\")\n\n# 图片消息 - 自动下载和清理\n@listener.image_handler()\nasync def handle_image(image_path: Path):\n    # image_path 是临时文件，处理完会自动清理\n    print(f\"处理图片: {image_path}\")\n\n# 文件消息 - 自动下载和清理\n@listener.file_handler(group_only=True)\nasync def handle_file(file_path: Path, group_name: str):\n    print(f\"收到文件: {file_path} 来自 {group_name}\")\n\n# 富文本消息\n@listener.listen(message_type=\"post\")\nasync def handle_post(ctx: MessageContext):\n    import json\n    post_content = json.loads(ctx.content)\n    print(f\"收到富文本: {post_content}\")\n\n# 启动监听\nlistener.run()"
      },
      {
        "title": "注意事项",
        "body": "异步处理: 所有处理函数使用 async/await 语法\n消息去重: 每个处理函数独立去重，默认 60 秒过期\n临时文件: 图片和文件下载到 系统临时目录/lark_bot_temp，处理完自动清理\n错误隔离: 每个处理函数异常独立捕获，不影响其他函数\n多注册: 同一消息可被多个处理函数处理"
      }
    ],
    "body": "Pywayne Lark Bot Listener\n\n飞书消息监听器，通过 WebSocket 实时接收和处理飞书消息。\n\nQuick Start\nfrom pywayne.lark_bot_listener import LarkBotListener\n\n# 初始化监听器\nlistener = LarkBotListener(\n    app_id=\"your_app_id\",\n    app_secret=\"your_app_secret\",\n    message_expiry_time=60  # 消息去重过期时间（秒）\n)\n\n# 处理文本消息\n@listener.text_handler()\nasync def handle_text(text: str):\n    print(f\"收到消息: {text}\")\n\n# 启动监听\nlistener.run()\n\nDecorators - 消息处理装饰器\ntext_handler\n\n文本消息处理装饰器，直接传递文本内容。\n\n@listener.text_handler(group_only=False, user_only=False)\nasync def handle_text(text: str, chat_id: str, is_group: bool, group_name: str, user_name: str):\n    print(f\"收到来自 {user_name} 的消息: {text}\")\n    listener.send_message(chat_id, f\"已收到：{text}\")\n\n\n参数说明（除 text 外均为可选）：\n\n参数\t类型\t说明\ntext\tstr\t文本内容（必需）\nchat_id\tstr\t会话 ID\nis_group\tbool\t是否群组消息\ngroup_name\tstr\t群组名称（私聊时为空）\nuser_name\tstr\t发送消息的用户姓名\n\n装饰器参数：\n\ngroup_only=True: 只处理群组消息\nuser_only=True: 只处理私聊消息\nimage_handler\n\n图片消息处理装饰器，自动下载图片到临时文件并清理。\n\nfrom pathlib import Path\nimport cv2\nimport tempfile\n\n@listener.image_handler()\nasync def handle_image(image_path: Path, user_name: str) -> Path:\n    # 处理图片\n    img = cv2.imread(str(image_path))\n    # ...处理逻辑...\n    # 返回新图片路径会自动发送回去，返回 None 则不发送\n    return image_path\n\n\n参数说明（除 image_path 外均为可选）：\n\n参数\t类型\t说明\nimage_path\tPath\t临时图片文件路径（必需）\nchat_id\tstr\t会话 ID\nis_group\tbool\t是否群组消息\ngroup_name\tstr\t群组名称\nuser_name\tstr\t发送消息的用户姓名\n\n返回值：\n\n返回 Path: 自动上传并发送新图片\n返回 None: 不发送任何图片\nfile_handler\n\n文件消息处理装饰器，自动下载文件到临时文件并清理。\n\n@listener.file_handler()\nasync def handle_file(file_path: Path, user_name: str) -> Path:\n    # 处理文件\n    with open(file_path, 'r') as f:\n        content = f.read()\n    # ...处理逻辑...\n    return file_path  # 返回文件路径会自动发送回去\n\n\n参数说明（除 file_path 外均为可选）：\n\n参数\t类型\t说明\nfile_path\tPath\t临时文件路径（必需）\nchat_id\tstr\t会话 ID\nis_group\tbool\t是否群组消息\ngroup_name\tstr\t群组名称\nuser_name\tstr\t发送消息的用户姓名\nlisten - 通用消息监听器\n\n用于监听任意类型消息（包括富文本 post）。\n\n@listener.listen(message_type=\"post\")\nasync def handle_post(ctx: MessageContext):\n    print(f\"收到富文本消息: {ctx.content}\")\n\n\nMessageContext 属性：\n\n属性\t类型\t说明\nchat_id\tstr\t会话 ID\nuser_id\tstr\t用户 ID\nmessage_type\tstr\t消息类型\ncontent\tstr\t消息内容（文本消息为字符串，其他类型为 JSON 字符串）\nis_group\tbool\t是否群组消息\nchat_type\tstr\t会话类型\nmessage_id\tstr\t消息 ID\nsend_message - 发送消息\n\n发送 Markdown 格式的消息到飞书。\n\nlistener.send_message(chat_id, \"**这是加粗文本**\")\nlistener.send_message(chat_id, \"普通文本\\n[链接](https://example.com)\")\n\n完整示例\nfrom pywayne.lark_bot_listener import LarkBotListener\nfrom pathlib import Path\n\nlistener = LarkBotListener(\n    app_id=\"your_app_id\",\n    app_secret=\"your_app_secret\"\n)\n\n# 文本消息 - AI 回复示例\n@listener.text_handler()\nasync def handle_text(text: str, chat_id: str, user_name: str):\n    # 处理逻辑...\n    listener.send_message(chat_id, f\"收到来自 {user_name} 的消息\")\n\n# 图片消息 - 自动下载和清理\n@listener.image_handler()\nasync def handle_image(image_path: Path):\n    # image_path 是临时文件，处理完会自动清理\n    print(f\"处理图片: {image_path}\")\n\n# 文件消息 - 自动下载和清理\n@listener.file_handler(group_only=True)\nasync def handle_file(file_path: Path, group_name: str):\n    print(f\"收到文件: {file_path} 来自 {group_name}\")\n\n# 富文本消息\n@listener.listen(message_type=\"post\")\nasync def handle_post(ctx: MessageContext):\n    import json\n    post_content = json.loads(ctx.content)\n    print(f\"收到富文本: {post_content}\")\n\n# 启动监听\nlistener.run()\n\n注意事项\n异步处理: 所有处理函数使用 async/await 语法\n消息去重: 每个处理函数独立去重，默认 60 秒过期\n临时文件: 图片和文件下载到 系统临时目录/lark_bot_temp，处理完自动清理\n错误隔离: 每个处理函数异常独立捕获，不影响其他函数\n多注册: 同一消息可被多个处理函数处理"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wangyendt/lark-bot-listener",
    "publisherUrl": "https://clawhub.ai/wangyendt/lark-bot-listener",
    "owner": "wangyendt",
    "version": "0.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/lark-bot-listener",
    "downloadUrl": "https://openagent3.xyz/downloads/lark-bot-listener",
    "agentUrl": "https://openagent3.xyz/skills/lark-bot-listener/agent",
    "manifestUrl": "https://openagent3.xyz/skills/lark-bot-listener/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/lark-bot-listener/agent.md"
  }
}