openilink-app-command-service

March 27, 2026 · View on GitHub

OpenILink Hub App that proxies slash commands to an upstream command API (currently bhwa233-api).

What it does

  • Forwards /<command> <text> to POST /command on the upstream API
  • Supports text, image, video, and file replies (sync and async)
  • On startup and after each OAuth install, syncs available commands to Hub as tools via PUT /bot/v1/app/tools
  • Uses sync/async pattern: replies within 5s are returned synchronously, slower commands fall back to async push via Bot API

Examples:

  • /hp — command help
  • /gold — real-time gold price
  • /s 600519 — stock info
  • /a 你好鸡哥 — ask a question
  • /gi 夜晚城市霓虹街道 — Gemini image generation

Install on Hub

1. Create the App

In Hub Dashboard -> Apps -> Create App:

FieldValue
NameCommand Service
Slugcommand-service
Scopesmessage:write, tools:write
Eventscommand
Webhook URLhttps://<your-domain>/hub/webhook
OAuth Setup URLhttps://<your-domain>/oauth/setup
OAuth Redirect URLhttps://<your-domain>/oauth/callback

Tools will be auto-synced after installation — no need to add them manually.

2. Verify Webhook URL

Click "Verify URL" in the dashboard. The service will respond to the url_verification challenge automatically.

3. Install to a Bot

Click "Install" on a Bot. Hub will open an OAuth popup:

  1. Hub redirects to /oauth/setup with hub, app_id, bot_id, state, return_url
  2. Service generates PKCE challenge and redirects to Hub's authorize endpoint
  3. Hub redirects back to /oauth/callback with a temporary code
  4. Service exchanges code + code_verifier for app_token and webhook_secret
  5. Credentials are stored in SQLite, popup closes automatically

After install, tools are automatically synced to Hub from the upstream /command/hp endpoint.

4. Reauthorize (if you add scopes later)

If you add new scopes to the App (e.g. tools:write), existing installations need reauthorization:

POST /api/apps/{id}/installations/{iid}/reauthorize

Environment

VariableDefaultDescription
PORT8081Listen port
HUB_URLhttps://hub.openilink.comHub origin
BASE_URLPublic base URL of this service
DB_PATH/data/command-service.dbSQLite database path
APP_IDApp ID (optional, Hub passes it via OAuth)
COMMAND_API_BASE_URLhttps://bhwa233-api.vercel.app/apiUpstream command API
COMMAND_API_TIMEOUT_MS120000Upstream timeout (ms)
SYNC_DEADLINE_MS5000Max wait before falling back to async

Routes

MethodPathDescription
POST/hub/webhookHub event webhook
GET/oauth/setupOAuth PKCE setup (entry point)
GET/oauth/callbackOAuth PKCE callback (code exchange)
GET/healthHealth check

Local development

export DB_PATH=./dev.db
go run .

Docker

docker compose up -d --build

SQLite data is persisted in a Docker volume (command-service-data -> /data/).