Knowledge

独立开发者的零成本用户反馈方案

独立开发者的零成本用户反馈方案

用 Tally + Cloudflare Worker + GitHub Issues 搭建零成本全球用户反馈系统,从用户提交到研发工单全程自动化。


引言

用户反馈是独立开发者产品迭代的生命线,但搭建反馈系统往往面临三大难题:

  1. 成本压力:专业反馈工具免费版额度极低,付费版成本不菲
  2. 全球覆盖:国内工具海外用户打不开,海外工具国内用户访问慢
  3. 研发脱节:反馈数据沉淀在第三方平台,需要手动同步到 GitHub 工单

我在 DouXia 项目中落地了一套零成本、全球覆盖、与研发流程无缝打通的方案。


方案对比

当前常见方案

方案 成本 国内访问 海外访问 研发协同
付费反馈工具 一般 一般
Google Forms 免费 不可用 极佳
腾讯兔小巢 免费版 100 条/月 极佳 不可用
完全自建 服务器成本 自托管 自托管 最好

推荐方案

本文方案组合三个免费工具,形成生产级反馈流水线:


架构总览

App 反馈按钮 → Tally 表单(WebView)→ Webhook → Cloudflare Worker → GitHub Issues

核心组件

  1. Tally 表单:自定义反馈收集,支持隐藏字段传递设备元数据
  2. Cloudflare Worker:轻量 Serverless 函数,接收 Webhook 并创建 GitHub Issue
  3. GitHub Issues:反馈数据结构化沉淀,与 Bug 修复、需求迭代无缝打通

设计原则


代码实现

App 端集成

const feedbackId = generateUUID()
const params = new URLSearchParams({
  device_id: hashDeviceInfo(),
  os_type: getOS(),
  app_type: 'desktop',
  feedback_id: feedbackId
})
const url = `https://tally.so/r/your-form-id?${params.toString()}`
openWebView(url)

Cloudflare Worker

Lookup 路由 (/lookup):

addEventListener('fetch', event => {
  const url = new URL(event.request.url)
  const feedbackId = url.searchParams.get('feedback_id')
  const html = `
    <h1>反馈提交成功!</h1>
    <p>您的反馈 ID:${feedbackId}</p>
    <a href="https://github.com/repo/issues?q=FeedbackID:${feedbackId}">
      查看处理进度
    </a>
  `
  event.respondWith(new Response(html, { headers: { 'Content-Type': 'text/html' } }))
})

Webhook 路由 (/webhook):

async function handleWebhook(request) {
  const data = await request.json()
  await fetch(`https://api.github.com/repos/repo/issues`, {
    method: 'POST',
    headers: {
      'Authorization': `token ${GITHUB_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      title: `Feedback: ${data.feedback_id}`,
      body: `设备类型: ${data.os_type}\n描述: ${data.description}`
    })
  })
  return new Response('OK', { status: 200 })
}

关键技术要点

异步竞态问题

问题:Tally 的 Webhook 是异步请求,页面跳转速度远快于 GitHub Issue 创建速度。

解决方案:使用静态 GitHub 搜索链接,用户点击时 Issue 必然已创建完成。

隐藏字段传参规则

问题:Tally 隐藏字段仅在页面首次加载时读取 URL 参数,刷新后参数丢失。

解决方案:WebView 禁用刷新手势,Worker 读取 Referer 请求头作为兜底。

Webhook 返回值限制

问题:Webhook 返回的 302 或 JSON 无法影响 Tally 的行为。

解决方案:使用 Tally 内置的提交后跳转功能。


效果对比

指标 实施前 实施后
开发时间 2+ 天 1-2 小时
月成本 $50+ $0
反馈响应 数小时 实时
全球覆盖 部分 完全

复现步骤

  1. 注册 Tally 账号,创建反馈表单
  2. 配置 Cloudflare Worker,部署 /lookup/webhook 路由
  3. 设置 Worker 环境变量:GITHUB_TOKENGITHUB_REPO
  4. 在 Tally 表单中配置 Webhook 和提交后跳转地址
  5. 在 App 中添加反馈按钮,打开携带设备参数的 Tally 链接

总结

这套零成本反馈方案解决了独立开发者面临的三大难题:成本、全球覆盖、研发集成。方案已在 DouXia 项目中稳定运行,建议独立开发者从这个最小配置开始尝试。

📖 Read in English

← Back to all articles