自动化"联系我们":纯前端接入飞书群机器人消息通知实践
1. 背景与目标
在官网"联系我们"页面里,用户线索如果不能第一时间触达业务群,常见问题就是响应慢、跟进晚、丢线索。
本文聚焦一个纯前端项目里的可落地方案:
- 用户提交联系表单
- 前端完成校验与消息组装
- 直接调用飞书群机器人 Webhook
- 群内实时收到线索通知
本文不涉及后端接口实现。
2. 功能效果展示


用户体验路径:
- 用户在 Contact 页面填写姓名、邮箱、电话、咨询方向、需求描述
- 点击提交后立即进行前端校验
- 校验通过后直接请求飞书群机器人 Webhook
- 发送成功跳转
/contact-success,发送失败展示错误提示
3. 技术选型与方案说明(纯前端)
3.1 本文方案
当前项目采用的是:前端直连飞书群机器人 Webhook。
优点:
- 接入成本低
- 链路短,联调快
- 适合官网线索通知这类轻量场景
边界:
- Webhook 相关配置在前端侧存在暴露风险
- 风控能力有限(需依赖飞书机器人安全设置)
3.2 接入前置条件(你必须先完成)
- 企业先为开发人员开通飞书开发者权限。
- 登录飞书开放平台创建应用,并为应用添加能力:机器人。
- 按飞书官方教程在目标群创建群机器人,获取 Webhook 链接。
本项目中,代码保存的是
FEISHU_WEBHOOK_KEY,由代码拼接成完整 URL:
https://open.feishu.cn/open-apis/bot/v2/hook/<REDACTED>
4. 项目结构与关键文件说明
本次链路相关文件:
text
lada/
├─ src/components/Contact/ContactForm.vue
├─ src/config/feishu.js
├─ src/config/apiKey.js # 本地密钥文件(被 .gitignore 忽略)
└─ .gitignore
关键职责:
| 文件 | 作用 |
|---|---|
lada/src/components/Contact/ContactForm.vue |
表单渲染、字段校验、提交、错误提示、调用飞书发送逻辑 |
lada/src/config/feishu.js |
飞书配置、消息模板函数、消息体构造工具 |
lada/src/config/apiKey.js |
存放高德与飞书 key(本地文件,未纳入版本控制) |
lada/.gitignore |
明确忽略 /src/config/apiKey.js |
代码扫描结论:
- 项目内未发现
/api/contact、/message/notify、/feishu/webhook等后端实现 - 当前是纯前端直连飞书群机器人 Webhook
5. 核心链路解析(含 Mermaid 图)
5.1 调用链路清单
| 环节 | 实现 |
|---|---|
| 触发点 | 用户点击提交按钮,触发表单 @submit.prevent="handleSubmit" |
| 前端模块与函数 | ContactForm.vue:handleSubmit() -> validateForm() -> sendToFeishu() |
| 网络请求路径与方法 | POST https://example.com/open-apis/bot/v2/hook/<REDACTED> |
| 后端路由与处理函数 | 无(纯前端) |
| 飞书消息发送实现 | feishu.js:formatContactMessage() + buildMessage() |
| 成功分支 | 返回 code === 0 后,约 1 秒跳转 /contact-success |
| 失败分支 | catch 异常,设置 messageStatus 并显示"提交失败"文案 |
5.2 总体架构图
POST
用户浏览器
ContactForm.vue
validateForm
sendToFeishu
FeishuUtils.formatContactMessage
apiKey.js: FEISHU_WEBHOOK_KEY=
Feishu Group Bot Webhook
飞书群
5.3 时序图
飞书群 飞书群机器人Webhook FeishuUtils ContactForm.vue 飞书群 飞书群机器人Webhook FeishuUtils ContactForm.vue alt [code == 0] [网络异常或 code != 0] alt [校验失败] [校验通过] 用户 点击提交 validateForm() 展示字段错误 formatContactMessage(formData, source) text content POST JSON (timeout=10s) { code: 0, msg: "ok" } 推送消息 跳转 /contact-success error/timeout 显示提交失败 用户
5.4 流程图(成功/失败/重试/兜底)
失败
通过
code=0
异常/超时/code!=0
是
否
用户点击提交
前端校验
展示字段错误并结束
组装飞书文本消息
axios POST 到 webhook
跳转成功页
展示失败提示
用户是否重试提交
人工兜底跟进线索
6. 前端实现详解(ContactForm.vue)
6.1 字段与校验规则
当前表单字段:
nameemailphonesubjectmessage
校验逻辑:
- 所有字段必填(
trim()) email用正则校验格式- 任一失败即中断提交并显示本地化错误文案
6.2 提交流程关键代码(节选)
js
// ContactForm.vue (节选)
// 1) 阻止默认提交 2) 前端校验 3) 调飞书 4) 成功跳转/失败提示
async handleSubmit(event) {
event.preventDefault()
if (!this.validateForm()) return
this.isSubmitting = true
this.messageStatus = null
try {
await this.sendToFeishu()
setTimeout(() => this.$router.push('/contact-success'), 1000)
} catch (error) {
console.error('Error sending message:', error) // 当前仅前端日志
this.messageStatus = { type: 'error', text: this.getFormMessage('error') }
this.isSubmitting = false
}
}
6.3 请求发送关键代码(节选)
js
// ContactForm.vue (节选)
// 组装消息并直接 POST 到飞书群机器人 Webhook
async sendToFeishu() {
const webhookUrl = FEISHU_CONFIG.WEBHOOK_URL
const sourceLabel = this.formCopy.source || 'Website'
const messageContent = FeishuUtils.formatContactMessage(this.formData, sourceLabel)
const message = FeishuUtils.buildMessage(messageContent)
const response = await axios.post(webhookUrl, message, FEISHU_CONFIG.API_CONFIG)
if (response.data.code !== 0) {
throw new Error(`Feishu API error: ${response.data.msg}`)
}
return response.data
}
实现特点:
- 有 loading 状态:
isSubmitting - 有错误提示:
messageStatus - 无后端参与,链路全在前端
- 失败日志主要依赖浏览器控制台
7. 飞书消息模块详解(feishu.js)
7.1 模块职责
lada/src/config/feishu.js 主要负责:
- 使用
FEISHU_WEBHOOK_KEY拼接群机器人 webhook URL - 提供消息模板函数(生成通知正文)
- 把表单数据转为飞书
text消息体
7.2 核心代码(脱敏节选)
js
// feishu.js (脱敏节选)
export const FEISHU_CONFIG = {
WEBHOOK_URL: 'https://example.com/open-apis/bot/v2/hook/<REDACTED>',
API_CONFIG: {
timeout: 10000,
headers: { 'Content-Type': 'application/json' }
}
}
export const FeishuUtils = {
// 用模板 + 表单数据生成文本
formatContactMessage(formData, source) {
const template = '来源:{source} 姓名:{name} 邮箱:{email} 电话:{phone} 方向:{subject} 需求:{message}'
return template
.replace('{source}', source)
.replace('{name}', formData.name)
.replace('{email}', formData.email)
.replace('{phone}', formData.phone)
.replace('{subject}', formData.subject)
.replace('{message}', formData.message)
},
// 构造飞书 text 消息格式
buildMessage(content) {
return {
msg_type: 'text',
content: { text: content }
}
}
}
7.3 消息结构说明
| 字段 | 说明 |
|---|---|
msg_type |
消息类型,当前为 text |
content.text |
文本正文,来自模板替换 |
{name} {email} {phone} {subject} {message} {source} {timestamp} |
模板占位符 |
模板定义位置:
lada/src/config/feishu.js(MESSAGE_TEMPLATE与formatContactMessage)
8. 安全与脱敏设计(纯前端场景)
8.1 纯前端直连的风险与现实边界
由于没有后端,Webhook 相关配置无法做到服务端级别的隔离,因此要明确:
- 前端方案更偏"快速接入"而非"高安全隔离"
- 不适合高敏感、高对抗场景
8.2 当前可执行的安全措施
- 不把真实密钥提交仓库:项目已通过
.gitignore忽略src/config/apiKey.js。 - 飞书群机器人开启安全策略(按飞书教程可配置项执行):
- 关键词校验
- IP 白名单(若网络出口固定时)
- 签名校验(若业务允许在前端使用该模式)
- 前端最小化暴露:仅保留必要字段,不在日志打印完整用户隐私。
- 脱敏规范:文档、截图、示例代码全部使用
<REDACTED>与假数据。
8.3 必须强调
如果代码里出现真实值,请务必改为部署注入,不要提交到仓库。
9. 部署与配置指南(纯前端)
9.1 飞书侧配置步骤
- 企业管理员为开发人员开通飞书开发者权限。
- 在飞书开放平台创建应用。
- 给应用添加"机器人"能力。
- 按飞书官方教程在目标群创建群机器人并拿到 webhook 链接。
9.2 项目侧配置
本项目使用 src/config/apiKey.js 存放 key(本地文件,不入库):
js
// src/config/apiKey.js(示例,已脱敏)
export const API_KEY = {
AMAP_KEY: '<REDACTED>',
FEISHU_WEBHOOK_KEY: '<REDACTED>'
}
说明:
FEISHU_WEBHOOK_KEY对应 webhook 链接里.../hook/后面的部分。
10. 联调与验证
10.1 本地验证步骤
- 启动前端:
npm run serve - 配置
src/config/apiKey.js(使用测试环境密钥) - 使用假数据提交表单:
张三 / test@example.com / 138****0000 - 浏览器 Network 检查:请求 URL、HTTP 状态、响应体
- 群内确认是否收到通知消息
10.2 请求消息示例(发送到飞书)
json
{
"msg_type": "text",
"content": {
"text": "🎯 新的咨询表单提交\n\n🌐 来源: 官网\n👤 联系人: 张三\n📧 电子邮箱: test@example.com\n📞 联系电话: 138****0000\n🎯 咨询方向: 产品咨询\n\n📋 详细需求:\n希望了解 AI 解决方案\n\n⏰ 提交时间: 2026/02/12 10:00:00"
}
}
10.3 验证通过标准
- 正常提交:页面跳转成功页,群里收到消息
- 校验失败:前端提示明确,不发请求
- 发送失败:前端提示失败,开发者可在 Network/Console 中定位
11. 常见问题排查
| 问题现象 | 常见原因 | 处理建议 |
|---|---|---|
| 400 Bad Request | 消息结构错误、缺字段、JSON 格式不对 | 校验 msg_type 与 content.text,打印请求体 |
| 401/403 | Webhook 无效、群机器人权限或安全策略不匹配 | 检查 webhook 是否完整、机器人是否可用 |
| 签名相关错误 | 签名配置开启但请求未按规则生成 | 对齐飞书机器人签名配置与实现 |
| 未收到群消息 | 机器人未添加到目标群、群权限限制 | 确认机器人在群内且可发言 |
| 提交一直转圈 | 异常分支未正确回收状态 | 确保 catch 分支恢复 isSubmitting |
| 模板占位符未替换 | 模板字符串或占位符拼写错误 | 对照 formatContactMessage 的占位符命名校验 |
12. 可扩展优化
- 消息卡片化:从 text 升级为 interactive card,字段更结构化。
- 客户端重试:增加指数退避重试与"稍后重试"按钮。
- 发送前防刷:接入前端验证码、人机校验。
- 埋点监控:记录提交成功率、失败码分布、重试率。
- 多群路由策略:按业务线把不同咨询方向发送到不同飞书群机器人。
- 表单字段扩展:增加公司、预算、期望上线时间等业务字段。