Ever Gauzy connector
The connector brings task titles and status from Ever Gauzy into the chat context Ever Async resolves. It supports integration credentials with mappings managed in Gauzy, and the existing personal-token configuration. Both modes are read-only: Ever Async does not create or transition Gauzy tasks.
Connect from the dashboard
Sign in to Ever Async, create or select your tenant, and open Connections. An account can own multiple connections of the same provider. Tenant board members manage the connections; saved credentials are encrypted and are never returned by the API or shown again in the dashboard.
- Add a Slack or Discord connection. Slack needs the app signing secret and
installed bot token; Async discovers the workspace using
auth.test. Discord needs its guild ID, application public key, and installed bot token; Async verifies the application and its access to that guild. - Copy the returned connection callback base. Slack uses
/events,/commands, and/interactionsbeneath that base; Discord uses/interactions. Disabled connections accept signed setup challenges, while message processing, commands, and deliveries remain disabled. Enable the connection after completing platform setup. - In the intended Gauzy organization, configure the Ever Async integration,
select allowed projects, and map each chat user with its platform and
workspace, for example
slack,T0123WORKSPACE,U0123ABC. - Add a Gauzy connection in Async with the Gauzy API and app URLs, integration tenant ID, Gauzy tenant ID, organization ID, API key identifier and secret. Choose the chat connections allowed to use it. Async verifies the exact Gauzy tenant, organization and integration before saving.
The Async tenant comes from the authenticated dashboard session and verified connection record. It is distinct from the Gauzy tenant. Employee mappings and project selection stay in Gauzy and are read on every lookup. Rotation in the Connections form takes effect on subsequent requests without restarting Async. Disabling a connection also prevents pending reminders from using it after a restart. Provider login through SSO does not install a bot.
Ordinary Discord messages use a Gateway receiver for each enabled managed connection. Enable Message Content Intent in Discord's developer portal, then save or enable the connection again to refresh its verified capability. Verified applications in 100 or more servers need Discord's approval for that privileged intent. The bot needs access to the intended channels and permission to send messages and replies; private nudges also require the recipient to allow bot DMs. The Interactions callback handles commands and buttons separately.
A Discord application has one Interactions callback URL. Any saved connection for that application can provide the URL; verified requests route to the currently enabled connection for their server. Disabling the callback's own connection does not stop other enabled servers using that same application. Private nudge buttons retain their original author, server and message for 24 hours across restarts, and a retry cannot post the rewrite twice. Rotation or disabling the original connection invalidates its saved buttons.
A shared Slack application can likewise use one callback base for its installed workspaces. Async verifies both the callback connection's signature and the current target installation's signature, then uses the saved workspace binding to select the tenant. Multiple matching installations for one workspace are rejected; keep one enabled connection per application and workspace.
For API clients, omitted source_connection_ids means all verified chat
connections in the same Async tenant; an empty array means none; an explicit
list permits only those same-tenant connection IDs. Every query uses an
immutable snapshot, and every outbound action rechecks the saved enabled state.
Server preparation
Dashboard connections require authenticated access, persistent storage, and
EVERASYNC_CONNECTION_ENCRYPTION_KEY: a server-held, base64-encoded 32-byte
random key. Keep it in your deployment secret store and retain it with the
database backup; changing it without re-encrypting records makes existing
credentials unreadable. Every server replica must use the same key.
EVERASYNC_GAUZY_ALLOWED_ORIGINS is a comma-separated operator allowlist,
defaulting to https://api.gauzy.co. Add the exact origin of a self-hosted Gauzy
API before users pair it. The server checks this policy before any request
carrying a Gauzy credential and refuses redirects. Tenant forms cannot override
the Slack or Discord API origins. No live bot installation is implied by a
successful connection test; verify a message in the intended workspace too.
Dedicated self-hosted TOML setup
The Gauzy installation must include integration-ever-async and its integration
settings UI. An organization administrator configures the integration in Gauzy,
including the Ever Async server URL, chat-user to employee mappings, and the
projects whose tasks may be shared. The Async connector uses that saved mapping
and project selection on every lookup.
Existing dedicated installations can retain the static operator setup below. Use dashboard connections for a server shared by multiple customer tenants. The static server pairing is an operator setup step:
- Create the Ever Async integration in the intended Gauzy tenant and organization, then generate its API credentials. Save the key identifier and secret in the Async server's secret environment. Keep the one-time secret out of config files, logs, and Git.
- Record the Gauzy integration tenant ID, tenant ID, and organization ID.
- Identify the Async tenant ID, channel plugin ID, and platform
workspace ID for the existing chat installation. The Async tenant is the
tenant in the trusted workspace binding. For a dedicated self-hosted
installation without a binding, it is
default. It is a different ID from the Gauzy tenant.channel = "slack"means the platform plugin;workspaceis the Slack team ID, not a conversation/channel ID. - Configure the connector, restart the Async server to load it, and run
everasync doctorusing the same configuration and secret environment.
[connectors.gauzy]
integration_id = "gauzy-integration-tenant-uuid"
api_key_env = "GAUZY_ASYNC_API_KEY" # environment holds the key identifier
api_secret_env = "GAUZY_ASYNC_API_SECRET" # environment holds the secret
tenant_id = "gauzy-tenant-uuid"
organization_id = "gauzy-organization-uuid"
async_tenant_id = "async-tenant-id" # use default only for that self-hosted tenant
channel = "slack"
workspace = "T0123WORKSPACE"
base_url = "https://api.gauzy.co" # optional; use the matching Gauzy API
app_base_url = "https://app.gauzy.co" # optional; used for human task links
For self-hosted Gauzy, set base_url and app_base_url to its API and web app
roots. Use HTTPS outside a trusted local network. Base URLs must have a host,
with no embedded credentials, query, or fragment. Redirects are refused so
custom authentication headers cannot reach another origin.
This is one static connector paired with one verified Async workspace. Every resolution, including a pasted task link, compares the trusted Async tenant, channel, and workspace before making any HTTP request. A different workspace cannot use this connector even if its user IDs or default tenant match. The pipeline supplies the tenant from its stored workspace binding and replaces any tenant claimed in an inbound event.
Changing employee mappings or project selection in Gauzy does not require
editing or restarting Async. Rotating the key does: update the referenced
secret environment, restart the Async process, and rerun everasync doctor.
Revoked credentials stop working; the connector does not retry through a
personal token or a static mapping.
Configuring this connector does not install the Slack or Discord app. The channel installation and its event delivery must already be configured separately. A successful doctor check proves the Gauzy credential and scope handshake; it does not prove a live chat message has been enriched.
API contract
Integration requests carry these headers:
| Header | Value |
|---|---|
X-APP-ID | Integration API key identifier |
X-API-KEY | Integration API secret |
X-INTEGRATION-ID | Configured Gauzy integration tenant ID |
Before each resolution, and for everasync doctor, Async calls:
GET /api/integration/ever-async/connector/status
The response must identify the configured integration, Gauzy tenant, and organization, and confirm that the integration is enabled:
{
"integrationTenantId": "gauzy-integration-tenant-uuid",
"tenantId": "gauzy-tenant-uuid",
"organizationId": "gauzy-organization-uuid",
"isEnabled": true
}
A mismatch stops task lookup. Inferred references and linked tasks then use the same scoped tasks endpoint, with one selector:
GET /api/integration/ever-async/connector/tasks?chatUserId=U0123ABC&channel=slack&workspace=T0123WORKSPACE
GET /api/integration/ever-async/connector/tasks?taskId=task-uuid
{
"items": [
{
"id": "task-uuid",
"title": "Fix login redirect",
"status": "in-progress",
"taskNumber": 42,
"projectId": "project-uuid"
}
],
"total": 1
}
Gauzy enforces its current organization scope, mappings, and project selection
for each request. The project selection also applies to explicit links.
Missing mappings, excluded projects, and deleted tasks return an empty list.
An inferred lookup never falls back to a bare chat user ID: platform and
workspace are required because user IDs can collide across installations.
taskNumber may be a string or number; status may be a string or null.
Invalid, revoked, or mismatched credentials return 401; a disabled integration
returns 403. Non-success responses fail the resolution without falling back
to legacy endpoints. Credentials are redacted from connector debug output,
and task response bodies are not logged.
Resolution behavior
Posted links come first. With [policy] unfurl_links = true (the default),
URLs on the app_base_url host that identify a task are looked up. Accepted
forms include hash or plain /pages/tasks/.../<uuid> routes and explicit
taskId, task_id, or task query parameters. Other hosts and task dashboards
without an ID are left alone. A linked task keeps the posted URL and is shown
at 0.95 confidence, including when it is completed. A local user_map is
not needed for links; integration mode still requires the workspace pairing
and Gauzy's project selection.
Vague references, such as “my last task”, use the author's current Gauzy
mapping. Closed tasks (completed, done, closed, cancelled, canceled,
case-insensitive) are excluded from inferred candidates. Missing or unknown
statuses count as open. Tasks already resolved from links are not inferred
again.
Inferred candidates are ranked by recency and title-token overlap, capped at
0.80. Managed mappings identify the employee; they do not make a vague
message certain. The newest task starts at 0.5, older candidates lose 0.05
each down to 0.1, and title overlap adds up to 0.4. The confidence cap is
unchanged in integration mode.
Inferred results retain the tasks dashboard URL because task routes vary by
Gauzy workspace layout. Candidates sharing that URL are reduced to the best
match. With the default [policy] min_confidence = 0.7, sufficiently strong
matches can produce a context card; setting it above 0.8 suppresses inferred
Gauzy matches while allowing exact task links.
The pipeline allows six seconds for the entire connector resolution and records
timeouts as ever_async_connector_calls_total{connector="gauzy",outcome="timeout"}.
Legacy personal-token mode
Existing installations continue to work when integration credential settings are absent:
[connectors.gauzy]
token_env = "GAUZY_API_TOKEN"
tenant_id = "gauzy-tenant-uuid"
organization_id = "gauzy-organization-uuid"
base_url = "https://api.gauzy.co"
app_base_url = "https://app.gauzy.co"
# Recommended local scope; supply all three together.
async_tenant_id = "default"
channel = "slack"
workspace = "T0123WORKSPACE"
[connectors.gauzy.user_map]
U0123ABC = "gauzy-employee-uuid"
Legacy requests carry Authorization: Bearer ... and Tenant-Id. Inference
maps the chat author through user_map and requests ten tasks from
/api/tasks/pagination, filtered by organization and employee. An unmapped
author gets no inferred result. Posted task links use /api/tasks/{id} and
require no static employee mapping. They are constrained by the personal
credential's Gauzy permissions, without integration project selection.
The three local scope settings are optional for compatibility, but if any is provided all three are required. Use an unscoped legacy configuration only in a dedicated single-workspace installation. It is unsuitable for a shared server receiving other customers' chat workspaces. Adding the scope settings protects both inferred references and direct links before HTTP.
When any integration credential setting is present, integration configuration
must be complete. A leftover token_env or user_map does not authorize
fallback and is not used by integration mode.
Health check and troubleshooting
everasync doctor
Integration mode checks the authenticated status response and its exact scope.
Legacy mode probes the task pagination endpoint. A 401 usually means the
credential is invalid or has been rotated; a 403 can indicate a disabled
integration or denied access. A 404 often means the API is missing the Gauzy
plugin, or base_url points to the web app. Gauzy Cloud uses different hosts:
api.gauzy.co for the API and app.gauzy.co for the web app.
If doctor succeeds but no task appears, verify the Async tenant/channel/workspace pairing, the current employee mapping, the selected projects, and the message's confidence threshold. This sequence also applies after a credential rotation.
Ever Gauzy SSO is separate
This connector reads tasks using a service credential. Ever Gauzy
SSO signs people in to the Async dashboard using
[auth.providers.oauth.gauzy] and an OAuth client. The connector and SSO have
different credentials and configuration; either can be enabled independently.