mattermost-push-proxy-router/AGENTS.md
Felipe M. 8789af2997
feat: include Go runtime and process metrics on /metrics
Register prometheus Go and process collectors alongside the router
metrics so /metrics exposes standard go_* and process_* series.
2026-07-27 08:39:11 +02:00

3.6 KiB

AGENTS.md - Mattermost Push Proxy Router

Project Summary

Stateless Go HTTP router that sits in front of Mattermost push notification backends. It implements the /api/v1/send_push and /api/v1/ack protocol used by Mattermost servers, routing traffic by mobile client platform prefix.

Problem It Solves

Mattermost exposes a single server-wide PushNotificationServer URL. On mixed deployments (official mobile app + custom client like Bubbles), one proxy cannot serve both: official apps need HPNS keys, custom apps need their own APNs key/topic. This router forwards:

  • Custom prefixes (e.g. apple_bubbles) → your stock mattermost-push-proxy
  • Official prefixes (e.g. apple_rn, android_rn) → HPNS relay

Tech Stack

  • Backend: Go 1.26+ (github.com/BurntSushi/toml for config)
  • Protocol: Mattermost push proxy API (POST /api/v1/send_push, POST /api/v1/ack)
  • Deployment: Single binary, Docker, GoReleaser

Project Structure

main.go       — CLI entry point
server.go     — HTTP server and route handlers
router.go     — Platform extraction from push payloads
proxy.go      — Upstream forwarding
config.go     — Environment-based configuration
Makefile      — Build/test/lint targets

Build & Run

make build
CONFIG_FILE=config/router.toml ./mattermost-push-proxy-router
make test

Default port: 8066 (from config listen, overridable via PORT).

Routing Logic

Device IDs are registered as platform:token (e.g. apple_bubbles:<hex>). The Mattermost server splits this into JSON fields before POSTing to the push service:

  • platform → prefix used for routing
  • device_id → bare APNs/FCM token

The router reads platform (with -vN version suffix stripped) and matches it against configured routes.

Configuration

Routes are defined in a TOML file referenced by CONFIG_FILE:

listen = ":8066"

[[routes]]
prefixes = ["apple_bubbles"]
url = "http://bubbles-proxy:8067"

[[routes]]
prefixes = ["apple_rn", "android_rn"]
url = "https://push.mattermost.com"
Variable Description
CONFIG_FILE Path to router TOML config (required)
PORT Override listen port
REQUEST_TIMEOUT_SEC Upstream HTTP timeout

Architecture

Mattermost server
  └─ PushNotificationServer
       └─ [this router :8066]
            ├─ apple_bubbles:*  → custom mattermost-push-proxy (:8067)
            └─ apple_rn:* / android_rn:* → HPNS (push.mattermost.com)

Key Conventions

  • Config via TOML file (CONFIG_FILE); HTTP/API handling uses stdlib only
  • Responses follow push-proxy shape: {"status":"OK"}, {"status":"FAIL","error":"..."}
  • Unknown platforms return FAIL (same as stock proxy dropping unmatched types)

Metrics

Prometheus metrics are exposed at GET /metrics:

Metric Labels Description
router_requests_total path, platform Requests routed to a backend
router_routing_errors_total reason Requests rejected before forwarding (read_body, invalid_json, missing_platform, unknown_platform)
router_upstream_requests_total platform, outcome Upstream responses (success, fail, error)
router_upstream_duration_seconds platform Upstream request latency histogram

Standard Go runtime and process metrics (go_*, process_*) are included automatically.