{
  "schemaVersion": "1.0",
  "item": {
    "slug": "openclaw-tg-canvas",
    "name": "TG Canvas Mini App",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/clvv/openclaw-tg-canvas",
    "canonicalUrl": "https://clawhub.ai/clvv/openclaw-tg-canvas",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/openclaw-tg-canvas",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=openclaw-tg-canvas",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "bin/tg-canvas.js",
      "miniapp/app.js",
      "miniapp/index.html",
      "miniapp/style.css"
    ],
    "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. Then review README.md for any prerequisites, environment setup, or post-install checks. 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. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-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/openclaw-tg-canvas"
    },
    "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/openclaw-tg-canvas",
    "agentPageUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas/agent",
    "manifestUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas/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. Then review README.md for any prerequisites, environment setup, or post-install checks. 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. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Security FAQ (answers for skill reviewers)",
        "body": "Q: Does the server auto-load ~/.openclaw/openclaw.json or any local credential file?\nNo. The server reads no local files for credentials. OPENCLAW_GATEWAY_TOKEN must be supplied explicitly via environment variable. The relevant code is the ENABLE_OPENCLAW_PROXY config block in server.js — verify it yourself.\n\nQ: What is the default for ENABLE_OPENCLAW_PROXY?\nOff. The code is const ENABLE_OPENCLAW_PROXY = process.env.ENABLE_OPENCLAW_PROXY === \"true\"; — it is only enabled if the string \"true\" is explicitly set in the environment. Omitting the variable leaves it disabled.\n\nQ: What are the terminal/PTY endpoints and how are they authenticated?\n\nEndpoint: GET /ws/terminal (WebSocket upgrade)\nAuth: JWT verified by verifyJwt() in the upgrade handler — same token issued by POST /auth after Telegram initData HMAC-SHA256 verification against BOT_TOKEN, restricted to ALLOWED_USER_IDS\nIf the JWT is missing or invalid the connection is rejected with 401 Unauthorized before a PTY is spawned\nPTY is killed immediately when the WebSocket closes\n\nThis is a server skill. It includes a Node.js HTTP/WebSocket server (server.js), a CLI (bin/tg-canvas.js), and a Telegram Mini App frontend (miniapp/). It is not instruction-only.\n\nTelegram Mini App Canvas renders agent-generated HTML or markdown inside a Telegram Mini App, with access limited to approved user IDs and authenticated via Telegram initData verification. It exposes a local push endpoint and a CLI command so agents can update the live canvas without manual UI steps."
      },
      {
        "title": "Prerequisites",
        "body": "Node.js 18+ (tested with Node 18/20/22)\ncloudflared for HTTPS tunnel (required by Telegram Mini Apps)\nTelegram bot token"
      },
      {
        "title": "Setup",
        "body": "Configure environment variables (see Configuration below) in your shell or a .env file.\nRun the bot setup script to configure the menu button:\nBOT_TOKEN=... MINIAPP_URL=https://xxxx.trycloudflare.com node scripts/setup-bot.js\n\n\nStart the server:\nnode server.js\n\n\nStart a Cloudflare tunnel to expose the Mini App over HTTPS:\ncloudflared tunnel --url http://localhost:3721"
      },
      {
        "title": "Pushing Content from the Agent",
        "body": "CLI:\ntg-canvas push --html \"<h1>Hello</h1>\"\ntg-canvas push --markdown \"# Hello\"\ntg-canvas push --a2ui @./a2ui.json\n\n\nHTTP API:\ncurl -X POST http://127.0.0.1:3721/push \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"html\":\"<h1>Hello</h1>\"}'"
      },
      {
        "title": "Security",
        "body": "What the Cloudflare tunnel exposes publicly:\n\nEndpointPublic?AuthGET /✅None (serves static Mini App HTML)POST /auth✅Telegram initData HMAC-SHA256 verification + ALLOWED_USER_IDS checkGET /state✅JWT requiredGET /ws✅JWT required (WebSocket upgrade)POST /push❌ loopback-onlyPUSH_TOKEN required + loopback checkPOST /clear❌ loopback-onlyPUSH_TOKEN required + loopback checkGET /health❌ loopback-onlyLoopback check only (read-only, low risk)GET/WS /oc/*✅ (when enabled)JWT required; only available when ENABLE_OPENCLAW_PROXY=true\n\n⚠️ Cloudflared loopback bypass: cloudflared (and other local tunnels) forward remote requests by making outbound TCP connections to localhost. This means all requests arriving via the tunnel appear to originate from 127.0.0.1 at the socket level — completely defeating the loopback-only IP check. PUSH_TOKEN is therefore required and is enforced at startup. The loopback check is retained as an additional layer but must not be relied on as the sole protection.\n\nRecommendations:\n\nSet PUSH_TOKEN — the server will refuse to start without it. Generate one with: openssl rand -hex 32\nUse a strong random JWT_SECRET (32+ bytes).\nKeep BOT_TOKEN, JWT_SECRET, and PUSH_TOKEN secret; rotate if compromised.\nThe Cloudflare tunnel exposes the Mini App publicly — the ALLOWED_USER_IDS check in /auth is the primary access control gate for the canvas.\nENABLE_OPENCLAW_PROXY is off by default. Only enable it if you need Control UI access through the Mini App and understand the implications (see below)."
      },
      {
        "title": "OpenClaw Control UI proxy (optional)",
        "body": "The server can optionally proxy /oc/* to a local OpenClaw gateway, enabling you to access the OpenClaw Control UI through the Mini App.\n\nThis feature is disabled by default. To enable:\n\nENABLE_OPENCLAW_PROXY=true\n\nWhen enabled, the server:\n\nProxies /oc/* HTTP and WebSocket requests to the local OpenClaw gateway.\nIf OPENCLAW_GATEWAY_TOKEN is set, injects it as Authorization: Bearer on proxied requests.\n\nThe server does not read any local files for credentials — OPENCLAW_GATEWAY_TOKEN must be supplied explicitly via environment variable if needed.\n\nWhen using /oc/* over a public origin, add that origin to OpenClaw gateway config:\n\n{\n  \"gateway\": {\n    \"controlUi\": {\n      \"allowedOrigins\": [\"https://your-canvas-url.example.com\"]\n    }\n  }\n}"
      },
      {
        "title": "Terminal (high-privilege feature)",
        "body": "The Mini App includes an interactive terminal backed by a server-side PTY.\n\n⚠️ This grants shell access to the machine running the server, as the process user. Anyone in ALLOWED_USER_IDS can open a bash session and run arbitrary commands. Only add users you trust with shell access to ALLOWED_USER_IDS.\n\nHow it works:\n\nAuthenticated users see a Terminal button in the Mini App topbar.\nTapping it opens xterm.js connected to /ws/terminal (JWT required).\nA PTY (bash) is spawned per WebSocket connection; killed when the connection closes.\nMobile toolbar provides Ctrl/Alt sticky modifiers, Esc, Tab, arrow keys.\n\nRuntime scope: node-pty spawns a bash process as the server process user. No additional env vars control this; auth is the only gate."
      },
      {
        "title": "Commands",
        "body": "tg-canvas push — push HTML/markdown/text/A2UI\ntg-canvas clear — clear the canvas\ntg-canvas health — check server health"
      },
      {
        "title": "Configuration",
        "body": "VariableRequiredDefaultDescriptionBOT_TOKENYes—Telegram bot token for API calls and initData verification.ALLOWED_USER_IDSYes—Comma-separated Telegram user IDs allowed to authenticate. Controls access to canvas, terminal, and proxy.JWT_SECRETYes—Secret for signing session JWTs. Use 32+ random bytes.PUSH_TOKENYes—Shared secret for /push and /clear. Server refuses to start without it. Generate: openssl rand -hex 32MINIAPP_URLYes (setup only)—HTTPS URL of the Mini App, used by scripts/setup-bot.js to configure the bot menu button.PORTNo3721HTTP server port.TG_CANVAS_URLNohttp://127.0.0.1:3721Base URL used by the tg-canvas CLI.ENABLE_OPENCLAW_PROXYNofalseSet to the string \"true\" to enable /oc/* proxy to a local OpenClaw gateway. Off by default. The server does not read any local files to obtain a token — OPENCLAW_GATEWAY_TOKEN must be set explicitly if auth is needed.OPENCLAW_GATEWAY_TOKENNo(unset)Auth token injected as Authorization: Bearer on proxied /oc/* requests. Only used when ENABLE_OPENCLAW_PROXY=true. Must be supplied explicitly; no automatic file loading occurs.OPENCLAW_PROXY_HOSTNo127.0.0.1Hostname of the local OpenClaw gateway (proxy only).OPENCLAW_PROXY_PORTNo18789Port of the local OpenClaw gateway (proxy only).JWT_TTL_SECONDSNo900Session token lifetime in seconds (default 15 min).INIT_DATA_MAX_AGE_SECONDSNo300Maximum age of Telegram initData (default 5 min)."
      }
    ],
    "body": "Security FAQ (answers for skill reviewers)\n\nQ: Does the server auto-load ~/.openclaw/openclaw.json or any local credential file? No. The server reads no local files for credentials. OPENCLAW_GATEWAY_TOKEN must be supplied explicitly via environment variable. The relevant code is the ENABLE_OPENCLAW_PROXY config block in server.js — verify it yourself.\n\nQ: What is the default for ENABLE_OPENCLAW_PROXY? Off. The code is const ENABLE_OPENCLAW_PROXY = process.env.ENABLE_OPENCLAW_PROXY === \"true\"; — it is only enabled if the string \"true\" is explicitly set in the environment. Omitting the variable leaves it disabled.\n\nQ: What are the terminal/PTY endpoints and how are they authenticated?\n\nEndpoint: GET /ws/terminal (WebSocket upgrade)\nAuth: JWT verified by verifyJwt() in the upgrade handler — same token issued by POST /auth after Telegram initData HMAC-SHA256 verification against BOT_TOKEN, restricted to ALLOWED_USER_IDS\nIf the JWT is missing or invalid the connection is rejected with 401 Unauthorized before a PTY is spawned\nPTY is killed immediately when the WebSocket closes\n\nThis is a server skill. It includes a Node.js HTTP/WebSocket server (server.js), a CLI (bin/tg-canvas.js), and a Telegram Mini App frontend (miniapp/). It is not instruction-only.\n\nTelegram Mini App Canvas renders agent-generated HTML or markdown inside a Telegram Mini App, with access limited to approved user IDs and authenticated via Telegram initData verification. It exposes a local push endpoint and a CLI command so agents can update the live canvas without manual UI steps.\n\nPrerequisites\nNode.js 18+ (tested with Node 18/20/22)\ncloudflared for HTTPS tunnel (required by Telegram Mini Apps)\nTelegram bot token\nSetup\nConfigure environment variables (see Configuration below) in your shell or a .env file.\nRun the bot setup script to configure the menu button:\nBOT_TOKEN=... MINIAPP_URL=https://xxxx.trycloudflare.com node scripts/setup-bot.js\n\nStart the server:\nnode server.js\n\nStart a Cloudflare tunnel to expose the Mini App over HTTPS:\ncloudflared tunnel --url http://localhost:3721\n\nPushing Content from the Agent\nCLI:\ntg-canvas push --html \"<h1>Hello</h1>\"\ntg-canvas push --markdown \"# Hello\"\ntg-canvas push --a2ui @./a2ui.json\n\nHTTP API:\ncurl -X POST http://127.0.0.1:3721/push \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"html\":\"<h1>Hello</h1>\"}'\n\nSecurity\n\nWhat the Cloudflare tunnel exposes publicly:\n\nEndpoint\tPublic?\tAuth\nGET /\t✅\tNone (serves static Mini App HTML)\nPOST /auth\t✅\tTelegram initData HMAC-SHA256 verification + ALLOWED_USER_IDS check\nGET /state\t✅\tJWT required\nGET /ws\t✅\tJWT required (WebSocket upgrade)\nPOST /push\t❌ loopback-only\tPUSH_TOKEN required + loopback check\nPOST /clear\t❌ loopback-only\tPUSH_TOKEN required + loopback check\nGET /health\t❌ loopback-only\tLoopback check only (read-only, low risk)\nGET/WS /oc/*\t✅ (when enabled)\tJWT required; only available when ENABLE_OPENCLAW_PROXY=true\n\n⚠️ Cloudflared loopback bypass: cloudflared (and other local tunnels) forward remote requests by making outbound TCP connections to localhost. This means all requests arriving via the tunnel appear to originate from 127.0.0.1 at the socket level — completely defeating the loopback-only IP check. PUSH_TOKEN is therefore required and is enforced at startup. The loopback check is retained as an additional layer but must not be relied on as the sole protection.\n\nRecommendations:\n\nSet PUSH_TOKEN — the server will refuse to start without it. Generate one with: openssl rand -hex 32\nUse a strong random JWT_SECRET (32+ bytes).\nKeep BOT_TOKEN, JWT_SECRET, and PUSH_TOKEN secret; rotate if compromised.\nThe Cloudflare tunnel exposes the Mini App publicly — the ALLOWED_USER_IDS check in /auth is the primary access control gate for the canvas.\nENABLE_OPENCLAW_PROXY is off by default. Only enable it if you need Control UI access through the Mini App and understand the implications (see below).\nOpenClaw Control UI proxy (optional)\n\nThe server can optionally proxy /oc/* to a local OpenClaw gateway, enabling you to access the OpenClaw Control UI through the Mini App.\n\nThis feature is disabled by default. To enable:\n\nENABLE_OPENCLAW_PROXY=true\n\n\nWhen enabled, the server:\n\nProxies /oc/* HTTP and WebSocket requests to the local OpenClaw gateway.\nIf OPENCLAW_GATEWAY_TOKEN is set, injects it as Authorization: Bearer on proxied requests.\n\nThe server does not read any local files for credentials — OPENCLAW_GATEWAY_TOKEN must be supplied explicitly via environment variable if needed.\n\nWhen using /oc/* over a public origin, add that origin to OpenClaw gateway config:\n\n{\n  \"gateway\": {\n    \"controlUi\": {\n      \"allowedOrigins\": [\"https://your-canvas-url.example.com\"]\n    }\n  }\n}\n\nTerminal (high-privilege feature)\n\nThe Mini App includes an interactive terminal backed by a server-side PTY.\n\n⚠️ This grants shell access to the machine running the server, as the process user. Anyone in ALLOWED_USER_IDS can open a bash session and run arbitrary commands. Only add users you trust with shell access to ALLOWED_USER_IDS.\n\nHow it works:\n\nAuthenticated users see a Terminal button in the Mini App topbar.\nTapping it opens xterm.js connected to /ws/terminal (JWT required).\nA PTY (bash) is spawned per WebSocket connection; killed when the connection closes.\nMobile toolbar provides Ctrl/Alt sticky modifiers, Esc, Tab, arrow keys.\n\nRuntime scope: node-pty spawns a bash process as the server process user. No additional env vars control this; auth is the only gate.\n\nCommands\ntg-canvas push — push HTML/markdown/text/A2UI\ntg-canvas clear — clear the canvas\ntg-canvas health — check server health\nConfiguration\nVariable\tRequired\tDefault\tDescription\nBOT_TOKEN\tYes\t—\tTelegram bot token for API calls and initData verification.\nALLOWED_USER_IDS\tYes\t—\tComma-separated Telegram user IDs allowed to authenticate. Controls access to canvas, terminal, and proxy.\nJWT_SECRET\tYes\t—\tSecret for signing session JWTs. Use 32+ random bytes.\nPUSH_TOKEN\tYes\t—\tShared secret for /push and /clear. Server refuses to start without it. Generate: openssl rand -hex 32\nMINIAPP_URL\tYes (setup only)\t—\tHTTPS URL of the Mini App, used by scripts/setup-bot.js to configure the bot menu button.\nPORT\tNo\t3721\tHTTP server port.\nTG_CANVAS_URL\tNo\thttp://127.0.0.1:3721\tBase URL used by the tg-canvas CLI.\nENABLE_OPENCLAW_PROXY\tNo\tfalse\tSet to the string \"true\" to enable /oc/* proxy to a local OpenClaw gateway. Off by default. The server does not read any local files to obtain a token — OPENCLAW_GATEWAY_TOKEN must be set explicitly if auth is needed.\nOPENCLAW_GATEWAY_TOKEN\tNo\t(unset)\tAuth token injected as Authorization: Bearer on proxied /oc/* requests. Only used when ENABLE_OPENCLAW_PROXY=true. Must be supplied explicitly; no automatic file loading occurs.\nOPENCLAW_PROXY_HOST\tNo\t127.0.0.1\tHostname of the local OpenClaw gateway (proxy only).\nOPENCLAW_PROXY_PORT\tNo\t18789\tPort of the local OpenClaw gateway (proxy only).\nJWT_TTL_SECONDS\tNo\t900\tSession token lifetime in seconds (default 15 min).\nINIT_DATA_MAX_AGE_SECONDS\tNo\t300\tMaximum age of Telegram initData (default 5 min)."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/clvv/openclaw-tg-canvas",
    "publisherUrl": "https://clawhub.ai/clvv/openclaw-tg-canvas",
    "owner": "clvv",
    "version": "0.2.6",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas",
    "downloadUrl": "https://openagent3.xyz/downloads/openclaw-tg-canvas",
    "agentUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas/agent",
    "manifestUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/openclaw-tg-canvas/agent.md"
  }
}