{
  "schemaVersion": "1.0",
  "item": {
    "slug": "questions-form",
    "name": "Questions Form",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/edonadei/questions-form",
    "canonicalUrl": "https://clawhub.ai/edonadei/questions-form",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/questions-form",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=questions-form",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "references/form-patterns.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-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/questions-form"
    },
    "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/questions-form",
    "agentPageUrl": "https://openagent3.xyz/skills/questions-form/agent",
    "manifestUrl": "https://openagent3.xyz/skills/questions-form/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/questions-form/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": "Questions Form",
        "body": "Present multiple clarifying questions as a Telegram inline-button form.\nAll questions appear at once; the user answers in any order, then submits."
      },
      {
        "title": "When to Use",
        "body": "You need 2 or more clarifying questions answered before proceeding\nQuestions have enumerable options (with optional free-text fallback)\nThe channel is Telegram\n\nDo not use this pattern for a single yes/no question — just send one message with buttons for that."
      },
      {
        "title": "Step 1: Compose the Form",
        "body": "Define each question internally as an object:\n\n{ id: \"type\",     text: \"What type of project?\", options: [\"Web App\", \"Mobile\", \"API\"] }\n{ id: \"timeline\", text: \"What is your timeline?\", options: [\"This week\", \"This month\", \"No rush\"] }\n{ id: \"budget\",   text: \"Budget range?\",          options: [\"< $1k\", \"$1k-5k\", \"$5k-10k\", \"> $10k\"] }\n\nInitialize internal tracking state:\n\nform_state = { type: null, timeline: null, budget: null }\nawaiting_freetext = null\nform_submitted = false"
      },
      {
        "title": "Step 2: Send the Header",
        "body": "Send a plain message (no buttons) as the form introduction:\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**I have a few questions before we proceed.**\\nPlease answer each one by tapping a button, then tap Submit when done.\"\n}"
      },
      {
        "title": "Step 3: Send Each Question",
        "body": "For each question, send a separate message with inline buttons.\nPut selectable options in rows of 2-3 buttons. Always put \"Other\" on its own last row.\n\nThe callback_data must follow this convention: form:<question_id>:<value>\n\nExample:\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**1. What type of project is this?**\",\n  \"buttons\": [\n    [\n      { \"text\": \"Web App\", \"callback_data\": \"form:type:web\" },\n      { \"text\": \"Mobile\", \"callback_data\": \"form:type:mobile\" },\n      { \"text\": \"API\", \"callback_data\": \"form:type:api\" }\n    ],\n    [\n      { \"text\": \"Other (type your answer)\", \"callback_data\": \"form:type:other\" }\n    ]\n  ]\n}\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**2. What is your timeline?**\",\n  \"buttons\": [\n    [\n      { \"text\": \"This week\", \"callback_data\": \"form:timeline:this_week\" },\n      { \"text\": \"This month\", \"callback_data\": \"form:timeline:this_month\" },\n      { \"text\": \"No rush\", \"callback_data\": \"form:timeline:no_rush\" }\n    ],\n    [\n      { \"text\": \"Other (type your answer)\", \"callback_data\": \"form:timeline:other\" }\n    ]\n  ]\n}\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**3. Budget range?**\",\n  \"buttons\": [\n    [\n      { \"text\": \"< $1k\", \"callback_data\": \"form:budget:lt_1k\" },\n      { \"text\": \"$1k-5k\", \"callback_data\": \"form:budget:1k_5k\" }\n    ],\n    [\n      { \"text\": \"$5k-10k\", \"callback_data\": \"form:budget:5k_10k\" },\n      { \"text\": \"> $10k\", \"callback_data\": \"form:budget:gt_10k\" }\n    ],\n    [\n      { \"text\": \"Other (type your answer)\", \"callback_data\": \"form:budget:other\" }\n    ]\n  ]\n}"
      },
      {
        "title": "Step 4: Send the Submit Button",
        "body": "After all questions, send the submit/cancel message:\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**When you've answered all questions above, tap Submit.**\",\n  \"buttons\": [\n    [{ \"text\": \"\\u2713 Submit All Answers\", \"callback_data\": \"form:submit\" }],\n    [{ \"text\": \"\\u2717 Cancel\", \"callback_data\": \"form:cancel\" }]\n  ]\n}"
      },
      {
        "title": "Step 5: Handle Callbacks",
        "body": "When you receive a callback starting with form::\n\nRegular option (form:<qid>:<value> where value is not other):\n\nRecord the answer: form_state[qid] = value\nAcknowledge: send \"Got it -- <question label>: **<chosen label>**\"\n\n\"Other\" option (form:<qid>:other):\n\nSend: \"Type your answer for: <question text>\"\nSet awaiting_freetext = qid\nThe next plain text message from the user is their free-text answer\nRecord: form_state[qid] = <user's text>\nAcknowledge: \"Got it -- <question label>: **<user's text>**\"\nClear awaiting_freetext\n\nSubmit (form:submit):\n\nCheck form_state for any null values\nIf incomplete: send \"You still need to answer: <list of unanswered questions>\"\nIf complete: set form_submitted = true and proceed with the collected answers\n\nCancel (form:cancel):\n\nDiscard form_state\nSend: \"Form cancelled. Let me know how you'd like to proceed.\""
      },
      {
        "title": "Step 6: Use the Answers",
        "body": "Once submitted, reference the collected answers as structured data and proceed:\n\nCollected: { type: \"mobile\", timeline: \"End of March\", budget: \"1k_5k\" }\n\nNow continue with the original task using these clarified requirements."
      },
      {
        "title": "Changing Answers",
        "body": "Users can click a different button for any question at any time before submitting.\nSimply overwrite the previous value and acknowledge the change:\n\n\"Updated -- <question>: **<new value>**\""
      },
      {
        "title": "Callback Data Convention",
        "body": "All form callbacks must use the form: prefix\nFormat: form:<question_id>:<value>\nKeep question IDs short (2-8 chars) — Telegram has a 64-byte callback_data limit\nKeep values short and use underscores instead of spaces\nThe agent identifies form callbacks by checking if the incoming message starts with form:"
      },
      {
        "title": "Button Layout Rules",
        "body": "Maximum 2-3 buttons per row for clean rendering\nKeep button labels under 20 characters\nUse Title Case for option labels\n\"Other\" button always says: \"Other (type your answer)\"\n\"Other\" button always goes on its own last row\nSubmit button includes checkmark: \"\\u2713 Submit All Answers\"\nCancel button includes X mark: \"\\u2717 Cancel\""
      },
      {
        "title": "Edge Cases and Advanced Patterns",
        "body": "See references/form-patterns.md for:\n\nHandling timeouts and abandoned forms\nDependent questions (show question B only after A is answered)\nLarge option sets (>6 options)\nMulti-select questions (toggle pattern)\nFree-text disambiguation\nResuming interrupted forms"
      }
    ],
    "body": "Questions Form\n\nPresent multiple clarifying questions as a Telegram inline-button form. All questions appear at once; the user answers in any order, then submits.\n\nWhen to Use\nYou need 2 or more clarifying questions answered before proceeding\nQuestions have enumerable options (with optional free-text fallback)\nThe channel is Telegram\n\nDo not use this pattern for a single yes/no question — just send one message with buttons for that.\n\nForm Protocol\nStep 1: Compose the Form\n\nDefine each question internally as an object:\n\n{ id: \"type\",     text: \"What type of project?\", options: [\"Web App\", \"Mobile\", \"API\"] }\n{ id: \"timeline\", text: \"What is your timeline?\", options: [\"This week\", \"This month\", \"No rush\"] }\n{ id: \"budget\",   text: \"Budget range?\",          options: [\"< $1k\", \"$1k-5k\", \"$5k-10k\", \"> $10k\"] }\n\n\nInitialize internal tracking state:\n\nform_state = { type: null, timeline: null, budget: null }\nawaiting_freetext = null\nform_submitted = false\n\nStep 2: Send the Header\n\nSend a plain message (no buttons) as the form introduction:\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**I have a few questions before we proceed.**\\nPlease answer each one by tapping a button, then tap Submit when done.\"\n}\n\nStep 3: Send Each Question\n\nFor each question, send a separate message with inline buttons. Put selectable options in rows of 2-3 buttons. Always put \"Other\" on its own last row.\n\nThe callback_data must follow this convention: form:<question_id>:<value>\n\nExample:\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**1. What type of project is this?**\",\n  \"buttons\": [\n    [\n      { \"text\": \"Web App\", \"callback_data\": \"form:type:web\" },\n      { \"text\": \"Mobile\", \"callback_data\": \"form:type:mobile\" },\n      { \"text\": \"API\", \"callback_data\": \"form:type:api\" }\n    ],\n    [\n      { \"text\": \"Other (type your answer)\", \"callback_data\": \"form:type:other\" }\n    ]\n  ]\n}\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**2. What is your timeline?**\",\n  \"buttons\": [\n    [\n      { \"text\": \"This week\", \"callback_data\": \"form:timeline:this_week\" },\n      { \"text\": \"This month\", \"callback_data\": \"form:timeline:this_month\" },\n      { \"text\": \"No rush\", \"callback_data\": \"form:timeline:no_rush\" }\n    ],\n    [\n      { \"text\": \"Other (type your answer)\", \"callback_data\": \"form:timeline:other\" }\n    ]\n  ]\n}\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**3. Budget range?**\",\n  \"buttons\": [\n    [\n      { \"text\": \"< $1k\", \"callback_data\": \"form:budget:lt_1k\" },\n      { \"text\": \"$1k-5k\", \"callback_data\": \"form:budget:1k_5k\" }\n    ],\n    [\n      { \"text\": \"$5k-10k\", \"callback_data\": \"form:budget:5k_10k\" },\n      { \"text\": \"> $10k\", \"callback_data\": \"form:budget:gt_10k\" }\n    ],\n    [\n      { \"text\": \"Other (type your answer)\", \"callback_data\": \"form:budget:other\" }\n    ]\n  ]\n}\n\nStep 4: Send the Submit Button\n\nAfter all questions, send the submit/cancel message:\n\n{\n  \"action\": \"send\",\n  \"channel\": \"telegram\",\n  \"message\": \"**When you've answered all questions above, tap Submit.**\",\n  \"buttons\": [\n    [{ \"text\": \"\\u2713 Submit All Answers\", \"callback_data\": \"form:submit\" }],\n    [{ \"text\": \"\\u2717 Cancel\", \"callback_data\": \"form:cancel\" }]\n  ]\n}\n\nStep 5: Handle Callbacks\n\nWhen you receive a callback starting with form::\n\nRegular option (form:<qid>:<value> where value is not other):\n\nRecord the answer: form_state[qid] = value\nAcknowledge: send \"Got it -- <question label>: **<chosen label>**\"\n\n\"Other\" option (form:<qid>:other):\n\nSend: \"Type your answer for: <question text>\"\nSet awaiting_freetext = qid\nThe next plain text message from the user is their free-text answer\nRecord: form_state[qid] = <user's text>\nAcknowledge: \"Got it -- <question label>: **<user's text>**\"\nClear awaiting_freetext\n\nSubmit (form:submit):\n\nCheck form_state for any null values\nIf incomplete: send \"You still need to answer: <list of unanswered questions>\"\nIf complete: set form_submitted = true and proceed with the collected answers\n\nCancel (form:cancel):\n\nDiscard form_state\nSend: \"Form cancelled. Let me know how you'd like to proceed.\"\nStep 6: Use the Answers\n\nOnce submitted, reference the collected answers as structured data and proceed:\n\nCollected: { type: \"mobile\", timeline: \"End of March\", budget: \"1k_5k\" }\n\n\nNow continue with the original task using these clarified requirements.\n\nChanging Answers\n\nUsers can click a different button for any question at any time before submitting. Simply overwrite the previous value and acknowledge the change:\n\n\"Updated -- <question>: **<new value>**\"\n\nCallback Data Convention\nAll form callbacks must use the form: prefix\nFormat: form:<question_id>:<value>\nKeep question IDs short (2-8 chars) — Telegram has a 64-byte callback_data limit\nKeep values short and use underscores instead of spaces\nThe agent identifies form callbacks by checking if the incoming message starts with form:\nButton Layout Rules\nMaximum 2-3 buttons per row for clean rendering\nKeep button labels under 20 characters\nUse Title Case for option labels\n\"Other\" button always says: \"Other (type your answer)\"\n\"Other\" button always goes on its own last row\nSubmit button includes checkmark: \"\\u2713 Submit All Answers\"\nCancel button includes X mark: \"\\u2717 Cancel\"\nEdge Cases and Advanced Patterns\n\nSee references/form-patterns.md for:\n\nHandling timeouts and abandoned forms\nDependent questions (show question B only after A is answered)\nLarge option sets (>6 options)\nMulti-select questions (toggle pattern)\nFree-text disambiguation\nResuming interrupted forms"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/edonadei/questions-form",
    "publisherUrl": "https://clawhub.ai/edonadei/questions-form",
    "owner": "edonadei",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/questions-form",
    "downloadUrl": "https://openagent3.xyz/downloads/questions-form",
    "agentUrl": "https://openagent3.xyz/skills/questions-form/agent",
    "manifestUrl": "https://openagent3.xyz/skills/questions-form/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/questions-form/agent.md"
  }
}