visitor_api.md 4.7 KB

Visitor 联系人信息上报 API 文档

1. 概述

Visitor 接口用于第三方系统向本平台上报联系人信息(姓名、手机、邮箱)。平台通过请求的 Referer 头自动匹配对应监控域名,将联系人信息存储到该域名下,并向传入的手机号发送短信验证码。

基础 URLhttp://<host>:<port>(开发环境默认 http://localhost:8000


2. 接口详情

2.1 上报联系人信息

POST /api/public/visitor
Content-Type: application/json

请求头

类型 必填 说明
Referer string 请求来源页面的完整 URL,用于提取域名匹配

请求体

字段 类型 必填 说明
name string 联系人姓名
phone string 联系电话(传入后会收到验证码短信)
email string 电子邮箱

处理流程

POST /api/public/visitor
  → 从 Referer 头提取域名
  → 在 monitored_domains 表中匹配 domain(需 is_active=true)
  → 获取该记录的 domain_id
  → 在 visitor_info 表中 upsert 联系人信息(同 domain_id 则更新,否则新建)
  → 生成 6 位数字验证码,通过阿里云短信发送至传入的 phone
  → 返回保存结果及验证码

curl 示例

curl -X POST "http://localhost:8000/api/public/visitor" \
  -H "Content-Type: application/json" \
  -H "Referer: https://example.com/dashboard" \
  -d '{
    "name": "张三",
    "phone": "13800138000",
    "email": "zhangsan@example.com"
  }'

2.2 响应

保存成功

{
  "success": true,
  "message": "联系人信息已保存",
  "domain": "example.com",
  "code": "843291"
}

返回的 code 为 6 位数字验证码。如未传入 phone 字段,则 codenull

缺少或无效 Referer

{
  "success": false,
  "message": "缺少或无效的 Referer 头"
}

未找到匹配的域名

{
  "success": false,
  "message": "未找到匹配的域名"
}

2.3 调用示例

前端(浏览器自动携带 Referer)

const res = await fetch('/api/public/visitor', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: '张三',
    phone: '13800138000',
    email: 'zhangsan@example.com',
  }),
});
const data = await res.json();
console.log(`验证码: ${data.code}`);

Python 后端

import requests

resp = requests.post(
    "https://license-server.example.com/api/public/visitor",
    headers={"Referer": "https://example.com/dashboard"},
    json={
        "name": "张三",
        "phone": "13800138000",
        "email": "zhangsan@example.com",
    },
)
print(resp.json())

Node.js

const resp = await fetch("https://license-server.example.com/api/public/visitor", {
  method: "POST",
  headers: { "Referer": "https://example.com/dashboard", "Content-Type": "application/json" },
  body: JSON.stringify({ name: "张三", phone: "13800138000", email: "zhangsan@example.com" }),
});
console.log(await resp.json());

curl

curl -X POST \
  -H "Referer: https://example.com/dashboard" \
  -H "Content-Type: application/json" \
  -d '{"name":"张三","phone":"13800138000","email":"zhangsan@example.com"}' \
  "https://license-server.example.com/api/public/visitor"

3. 数据表

visitor_info

联系人信息表,与 monitored_domains 一对一关联。同一域名多次请求会覆盖更新已有记录。

字段 类型 说明
id SERIAL PK 主键
domain_id INT (UNIQUE) 关联的域名 ID
name VARCHAR(100) 联系人姓名
phone VARCHAR(50) 联系电话
email VARCHAR(200) 电子邮箱
created_at TIMESTAMPTZ 创建时间
updated_at TIMESTAMPTZ 更新时间

4. 常见问题

Q: 同一域名多次请求会怎样? A: 覆盖更新已有联系人信息,不会新增记录。domain_id 有唯一约束保证不会重复。

Q: 需要认证吗? A: 不需要。POST /api/public/visitor 是公开接口,第三方系统可直接调用。

Q: 不传手机号会发短信吗? A: 不会。仅当 phone 字段有值时才发送短信验证码,但联系人信息仍会正常保存。

Q: 验证码是什么用途? A: 验证码通过短信发送到联系人手机,同时在响应中返回给调用方,方便第三方系统做二次校验。

Q: 域名匹配支持哪些格式? A: 支持纯域名(example.com)、带端口(example.com:8080)、带协议(http://example.com / https://example.com)。