herald-dingtalk

command module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

README

herald-dingtalk

License Go Version Go Report Card

Multi-language Documentation

DingTalk notification adapter for Herald. Herald forwards verification codes over HTTP to this service; herald-dingtalk calls the DingTalk work notification API to deliver messages. All DingTalk credentials and business logic live in this project only—Herald does not hold any DingTalk credentials.

The HTTP server uses Fiber v3.5.0 and the matching v2 module lines of the Fiber-facing kit packages. Building from source requires Go 1.26.6 or later.

Core Features

  • Herald HTTP Provider contract: Implements the same HTTP send contract as Herald's external provider; request/response align with provider-kit HTTPSendRequest / HTTPSendResponse.
  • Optional API Key auth: When API_KEY is set, Herald must send X-API-Key; otherwise no auth required.
  • Idempotency: Coalesces concurrent requests with the same key and caches successful results within the TTL. Reusing a key with different send content returns 409 idempotency_conflict.
  • Graceful shutdown: On SIGINT or SIGTERM, server stops accepting new requests and allows up to 35 seconds for in-flight requests to finish.
  • Hardened service boundary: Constant-time API key verification, a bounded request body, HTTP timeouts, request IDs, security headers, and panic recovery.

Architecture

sequenceDiagram
  participant User
  participant Stargate
  participant Herald
  participant HeraldDingtalk as herald-dingtalk
  participant DingTalk

  User->>Stargate: Login (identifier)
  Stargate->>Herald: Create challenge (channel=dingtalk, destination=userid)
  Herald->>HeraldDingtalk: POST /v1/send (to=userid, body/code)
  HeraldDingtalk->>DingTalk: Work notification API
  DingTalk-->>User: DingTalk message
  HeraldDingtalk-->>Herald: ok, message_id
  Herald-->>Stargate: challenge_id, expires_in
  • Stargate: ForwardAuth / login orchestration.
  • Herald: OTP challenge creation and verification; calls herald-dingtalk for channel dingtalk.
  • herald-dingtalk: HTTP adapter; calls DingTalk work notification API; holds DingTalk credentials only here.

Protocol

  • POST /v1/resolve (optional)
    Exchange DingTalk OAuth2 auth_code for userid. Request: { "auth_code": "..." }. Response: { "ok": true, "userid": "..." } or error. See API.
  • POST /v1/send
    Request: channel (must be dingtalk when set), to (DingTalk userid, or 11-digit mobile when DINGTALK_LOOKUP_MODE=mobile), body (or params.code), idempotency_key, optional template/params/locale/subject/timeout_seconds (0–30).
    Response: { "ok": true, "message_id": "...", "provider": "dingtalk" } or { "ok": false, "error_code": "...", "error_message": "..." }.
  • GET /healthz: { "status": "healthy", "service": "herald-dingtalk" } (via health-kit).
  • GET /readyz: Returns 200 only when credentials are complete, DINGTALK_AGENT_ID is a positive integer, and lookup mode is supported; otherwise returns 503.

Configuration

Variable Description Default Required
PORT Listen port (with or without leading colon) :8083 No
API_KEY If set, Herald must send X-API-Key `` No
DINGTALK_APP_KEY DingTalk app key `` Yes (for send)
DINGTALK_APP_SECRET DingTalk app secret `` Yes (for send)
DINGTALK_AGENT_ID Positive base-10 Agent ID for work notification `` Yes (for send)
DINGTALK_LOOKUP_MODE Must be none (userid only) or mobile (userid or 11-digit mobile; requires Contact.User.mobile permission) none No
LOG_LEVEL Log level: trace, debug, info, warn, error info No
IDEMPOTENCY_TTL_SECONDS Idempotency cache TTL (seconds) 300 No
MAX_REQUEST_BODY_BYTES Maximum HTTP request body size; valid range is 1 byte–1 MiB 65536 No
MAX_CONCURRENT_REQUESTS Maximum in-flight /v1 requests per process; 0 disables the limit 32 No

Herald side

Configure Herald with HTTP provider for channel dingtalk:

  • HERALD_DINGTALK_API_URL = base URL of herald-dingtalk (e.g. http://herald-dingtalk:8083)
  • Optional: HERALD_DINGTALK_API_KEY = same as herald-dingtalk API_KEY

Herald does not hold any DingTalk credentials.

Quick Start

Build & run (binary)

Download a platform binary and checksums.txt from GitHub Releases. For example, after v1.0.0 is published:

curl -LO https://github.com/soulteary/herald-dingtalk/releases/download/v1.0.0/herald-dingtalk-linux-amd64
curl -LO https://github.com/soulteary/herald-dingtalk/releases/download/v1.0.0/checksums.txt
grep 'herald-dingtalk-linux-amd64$' checksums.txt | sha256sum -c -
chmod +x herald-dingtalk-linux-amd64
./herald-dingtalk-linux-amd64 --version
# 1.0.0

To build from source:

go build -o herald-dingtalk .
./herald-dingtalk

Print the embedded build version with ./herald-dingtalk --version.

With DingTalk credentials in env, POST /v1/send will send work notifications to the given userid.

Run with Docker
docker pull ghcr.io/soulteary/herald-dingtalk:v1.0.0
docker run -d --name herald-dingtalk -p 8083:8083 \
  -e DINGTALK_APP_KEY=your_app_key \
  -e DINGTALK_APP_SECRET=your_app_secret \
  -e DINGTALK_AGENT_ID=your_agent_id \
  ghcr.io/soulteary/herald-dingtalk:v1.0.0

Optional: add -e API_KEY=your_shared_secret and set HERALD_DINGTALK_API_KEY to the same value on Herald.

Documentation

Testing

go test ./...

Coverage:

go test -cover ./...
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
go tool cover -html=coverage.out

Coverage includes configuration validation, idempotency and concurrency behavior, DingTalk success and failure responses, request handlers, authentication, routing, observability, and graceful shutdown. CI enforces a 90% total statement coverage floor. Lint: golangci-lint run.

Operation

  • Graceful shutdown: On SIGINT or SIGTERM, the server stops accepting new requests and allows up to 35 seconds for in-flight requests to finish. Logs "shutting down" and any shutdown error.
  • Probes: Use /healthz for liveness and /readyz for readiness. Readiness is 503 until DingTalk credentials are configured.
  • HTTP boundary: Responses include an X-Request-ID and security headers. Bodies default to 64 KiB, reads to 10s, writes to 35s, and idle connections to 60s.
  • Logging: Structured JSON logs via logger-kit. Recipient identifiers, mobile numbers, user IDs, OAuth codes, API keys, and request bodies are not logged.
  • Container: The runtime image includes a Docker health check and runs as the unprivileged herald user.
  • DingTalk client safeguards: Concurrent token refreshes are coalesced, an explicitly rejected token is refreshed once, non-2xx responses are rejected, and response bodies are limited to 1 MiB.

License

See LICENSE for details.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL