Discord Chat Bridge Configuration
Overview
DiscordChatBridgeModule is a persisted configuration record for the inbound Discord interaction bridge. It is not an executable workflow step. Version 2.0.0 hides it from Workflow Studio discovery and fails closed with MODULE_CONFIGURATION_ONLY if an older task tries to execute it.
The supported runtime path is the signed HTTPS webhook at /v1/chat-bridges/discord/interactions. The bridge registry continues to locate existing records by the unchanged Java class and bean identity, so saved application, allowlist, IntegrationAccount, and target bindings remain inspectable.
Usage
- Create or retain an
ExecModulerecord whose class iscom.valkyrlabs.workflow.modules.social.DiscordChatBridgeModule. - Bind a READY Discord
IntegrationAccountand configure the application and target fields below. - Expose
https://<your-api-host>/v1/chat-bridges/discord/interactionsthrough the normal ValkyrAI deployment. - Register that exact HTTPS URL as the Discord application interaction endpoint.
- Keep the configuration record outside task execution chains.
Discord requests are accepted only after the bridge resolves a matching application binding and verifies the X-Signature-Ed25519 signature over the timestamp and raw body.
Inputs
Direct task inputs are ignored. Legacy application_id, target_runtime, target_instance_id, and prompt values are never dispatched by the module.
Outputs
Direct execution always returns:
{
"status": "error",
"error": {
"code": "MODULE_CONFIGURATION_ONLY",
"message": "DiscordChatBridgeModule configures the signed interaction webhook and cannot execute as a task",
"retryable": false,
"webhookPath": "/v1/chat-bridges/discord/interactions",
"requiredAction": "Register the HTTPS interaction endpoint in Discord and keep this record outside task chains"
}
}
The output never contains the prompt, public-key field, bot token, interaction token, target identifier, or provider response.
IntegrationAccount Requirements
Bind a READY Discord IntegrationAccount using the existing bridge contract:
| Field | Purpose |
|---|---|
accountId | Discord application id when application_id is not set. |
apiKey | Discord bot token for governed Discord operations that require it. |
password | Legacy fallback for the Discord Ed25519 public key. Prefer the explicit secure configuration field when available. |
Use least privilege and never place tokens or keys in workflow input, logs, URLs, or task output.
Configuration
| Field | Required | Description |
|---|---|---|
discordAccount | Yes | READY Discord IntegrationAccount. |
application_id | No | Discord application id; defaults to IntegrationAccount.accountId. |
discord_public_key | No | Secure Ed25519 public-key field; the account password is the legacy fallback. |
target_runtime | No | sagechat, valoride, codex, openclaw, swarm, or agent; defaults to sagechat. |
llm_service_id | Conditional | SageChat or Valor LlmDetails id; ExecModule.systemId is preferred. |
target_instance_id | Conditional | Target instance for remote runtimes such as Codex or OpenClaw. |
allowed_guild_ids | No | Comma-separated Discord guild allowlist. |
allowed_channel_ids | No | Comma-separated Discord channel allowlist. |
Operations
This record has no task operation. The controller owns three interaction phases:
- Verify the application binding, guild/channel allowlists, and Ed25519 request signature.
- Return Discord PING acknowledgements or a deferred interaction acknowledgement.
- Dispatch a bounded prompt through the configured governed target, then update the original Discord response.
Errors and Failure Modes
| Condition | Result | Recovery |
|---|---|---|
| Record added to a task chain | MODULE_CONFIGURATION_ONLY, not retryable | Remove it from the chain and configure the webhook endpoint. |
| No application binding | HTTP 401 from the webhook | Correct application_id or IntegrationAccount.accountId. |
| Invalid Discord signature | HTTP 401 from the webhook | Verify the registered Ed25519 public key and raw-body proxy behavior. |
| Invalid interaction JSON | HTTP 400 from the webhook | Send the original Discord interaction body unchanged. |
| Guild/channel outside allowlist | HTTP 401 from the webhook | Correct the allowlist only after authorization. |
| Target dispatch failure | Deferred response reports failure | Inspect sanitized server logs and the governed target receipt. |
Example
Configuration record:
{
"application_id": "123456789012345678",
"target_runtime": "codex",
"target_instance_id": "release-agent",
"allowed_guild_ids": "111111111111111111",
"allowed_channel_ids": "222222222222222222"
}
Expected result: Discord sends a signed interaction to the registered HTTPS route, ValkyrAI verifies it and dispatches through the configured target. Executing the record as a task produces only the fail-closed output shown above.
Notes
- Pagination does not apply; each Discord interaction is handled independently.
- Discord message content is bounded before the original response is updated.
- Interaction writes are not replayed automatically. Reconcile Discord state before retrying an ambiguous deferred response.
- The module execution itself performs no network, filesystem, elevated, or credential operation.
- The webhook controller and registry remain the only supported bridge path; hiding catalog discovery does not delete existing configuration records.