MiFaZhan b1b83d806a ci: 打 tag 时自动触发 Jenkins 构建镜像
新增 .gitea/workflows/trigger-jenkins.yml:
- 触发时机:推送 v* tag(main 日常提交不触发),也可手动 dispatch
- 动作:调用 Jenkins 任务 iotlcm-oss-build,参数 SERVICES=<仓库名>、VERSION=<tag>
- 凭据来自组织密钥 JENKINS_URL / JENKINS_USER / JENKINS_API_TOKEN
- 同一 ref 连续推送时取消旧任务
2026-10-30 09:36:31 +08:00
2026-10-22 14:21:47 +08:00
2026-10-22 14:21:47 +08:00
2026-10-22 14:21:47 +08:00
2026-10-22 14:21:47 +08:00

iotlcm-sms

独立短信 HTTP/gRPC 服务,支持阿里云和腾讯云短信。

启动

go mod tidy
go run .

默认监听 :8080,可通过 HTTP_ADDR 修改:

HTTP_ADDR=:9090 go run .

gRPC 默认监听 :11200,可通过 GRPC_ADDR 修改。HTTP 与 gRPC 使用同一套短信发送实现。

默认供应商配置

短信服务自身持有全局凭证与签名,调用方只需传模板 ID 和短信内容。默认配置按下面的顺序合并:

config.yaml 默认值  →  SMS_* 环境变量覆盖  →  调用方请求中显式提供的字段优先

配置文件查找顺序:SMS_CONFIG_FILE 指定路径 → ./config.yaml → ./config/config.yaml → /app/config/config.yaml。

# config.yaml(真实凭证只放服务器,不要提交 Git)
serviceType: "1"          # 1=阿里云,2=腾讯云
regionId: cn-hangzhou
accessKeyId: ""
accessKeySecret: ""
signName: "示例企业"

可用环境变量覆盖:SMS_SERVICE_TYPE、SMS_REGION_ID、SMS_ACCESS_KEY_ID、 SMS_ACCESS_KEY_SECRET、SMS_SDK_APP_ID、SMS_SIGN_NAME、SMS_TEMPLATE_ID。

仓库内提供 config.example.yaml 作为模板;.gitignore 已排除真实 config.yaml。 启动日志会打印实际加载的配置来源(file=... env=...),便于排查。

场景模板配置库(可选)

除全局凭证外,还支持按业务场景(scene)从数据库回填模板与签名:调用方只传 scene 和内容参数,无需关心具体模板 ID。连接参数与凭证同放 config.yaml:

# 场景模板配置库(表 t_sms_template_config);DSN 留空或省略 = 关闭该能力
sceneDbDsn: "user:pass@tcp(127.0.0.1:3306)/db_iotlcm?charset=utf8mb4&parseTime=true&loc=Local"
sceneDbCacheTtl: 60s   # 场景配置内存缓存时长,"改库即生效"的最长延迟

可用环境变量覆盖:SMS_DB_DSN、SMS_DB_CONFIG_CACHE_TTL。DSN 未配置时, 带 scene 的请求返回 400(短信场景未配置或已停用)。

生产环境使用 deploy/docker-compose.yml 容器化部署,HTTP 端口为 11190, gRPC 端口为 11200。

docker build --platform linux/amd64 -f build/Dockerfile \
  -t <your-registry>/iotlcm-sms:latest .
docker push <your-registry>/iotlcm-sms:latest

cd deploy
# 先在服务器放置真实 config.yaml(不入库)
docker compose pull
docker compose up -d

生产部署建议通过 IOTLCM_SMS_IMAGE 指定不可变版本标签:

IOTLCM_SMS_IMAGE=<your-registry>/iotlcm-sms:<commit> docker compose up -d

健康检查:

curl http://127.0.0.1:8080/healthz

发送短信

接口:POST /api/v1/sms/send

阿里云请求示例:

curl -X POST http://127.0.0.1:8080/api/v1/sms/send \
  -H 'Content-Type: application/json' \
  -d '{
    "config": {
      "serviceType": "1",
      "regionId": "cn-hangzhou",
      "accessKeyId": "your-access-key-id",
      "accessKeySecret": "your-access-key-secret",
      "signName": "your-sign-name",
      "templateId": "SMS_000000001"
    },
    "params": {
      "phoneNumber": "13800008000",
      "msgContent": "{\"code\":\"123456\"}"
    }
  }'

腾讯云请求示例:

curl -X POST http://127.0.0.1:8080/api/v1/sms/send \
  -H 'Content-Type: application/json' \
  -d '{
    "config": {
      "serviceType": "2",
      "sdkAppId": "1400000000",
      "accessKeyId": "your-secret-id",
      "accessKeySecret": "your-secret-key",
      "signName": "your-sign-name",
      "templateId": "000000"
    },
    "params": {
      "phoneNumber": "+8613800138000",
      "msgContent": "123456|5"
    }
  }'

serviceType 为 1 时使用阿里云,msgContent 应为模板参数 JSON。serviceType 为 2 时使用腾讯云,多个模板参数继续沿用原项目的 | 分隔格式。多个手机号使用英文逗号分隔,腾讯云号码应使用 E.164 格式。

成功响应:

{
  "code": 0,
  "message": "发送成功",
  "data": {
    "provider": "aliyun",
    "requestId": "provider-request-id"
  }
}

参数错误返回 HTTP 400,上游短信平台调用失败返回 HTTP 502。响应体中的 code 同步表示业务结果。

测试实例

运行不访问真实短信平台的 HTTP 接口测试:

go test ./...

运行示例客户端(先启动服务并替换示例中的测试凭证):

go run ./examples/http_client

也可以传入其他服务地址:

go run ./examples/http_client http://127.0.0.1:9090/api/v1/sms/send

gRPC 接口

迁移后的接口保持原服务 protobuf 兼容:

PbNotice.Notice/Send

请求中的 config 和 params 是 JSON 编码的 bytes,字段内容与 HTTP 接口一致。 响应结果放在 head.code 和 head.message 中;routerId、traceId 会原样返回。 protobuf 源文件位于 proto,生成的客户端和服务端代码位于 api/pb。

使用 Go 示例客户端发送请求:

go run ./examples/grpc_client examples/requests/aliyun.local.json
go run ./examples/grpc_client examples/requests/tencent.local.json 127.0.0.1:11200

服务注册了 gRPC reflection,可查看线上接口:

grpcurl -plaintext 127.0.0.1:11200 list
grpcurl -plaintext 127.0.0.1:11200 describe PbNotice.Notice

已保存的 HTTP 请求示例位于 examples/requests。其中 aliyun.json 和 tencent.json 使用环境变量占位符,可用于文档和版本管理;同目录的 *.local.json 是包含本机测试凭证的可直接重放请求,已被 .gitignore 排除。

curl -X POST http://127.0.0.1:8080/api/v1/sms/send \
  -H 'Content-Type: application/json' \
  --data-binary @examples/requests/aliyun.local.json

curl -X POST http://127.0.0.1:8080/api/v1/sms/send \
  -H 'Content-Type: application/json' \
  --data-binary @examples/requests/tencent.local.json
S
Description
iotLCM 物联网卡全生命周期管理平台(开源版,单仓多服务)
Readme Apache-2.0 38 MiB
Languages
Go 69.4%
Vue 15.2%
TypeScript 12%
PLpgSQL 2.4%
JavaScript 0.4%
Other 0.3%