Skip to main content

Getting started

Use the hosted dashboard​

Running a new deployment or seeing no sign-in provider? Start with Register apps and enable signup. The current hosted rollout still needs provider registration and a real first signup.

  1. Open the Ever Async dashboard and sign in with an available provider. The first sign-in creates your initial tenant. Use the tenant menu to switch teams or Create tenant for a separate team.
  2. Open Connections. Members with the board role can Add Slack or Add Discord, using credentials for their own chat apps. Saving verifies the identity and starts the connection disabled.
  3. Copy the saved connection's callback URLs into the chat application's setup, then enable it. You can connect several Slack workspaces and Discord servers at the same time. Discord channel messages require Message Content Intent and the bot's channel permissions; without that intent it supports interactions only. See the connection guide for setup and shared-app URLs.
  4. To bring in task context, create the Ever Async integration in your Gauzy organization, then use Pair Gauzy in Connections. Choose which verified chat connections may use that pairing.

See Manage connections for fields, callback URLs, credential rotation, and tenant access. Gauzy requires the Ever Async integration plugin in the selected Gauzy deployment; see the Gauzy guide.

Run your own server​

The steps below configure a dedicated installation from a local everasync.toml: init → set the environment → serve → point Slack at it. No separate queue or AI key is required. A self-hosted deployment can also enable dashboard connection management with authenticated sessions and secure connection storage; see Manage connections.

Prerequisites​

  • A build of the everasync binary — see Self-hosting for the source, Docker and compose paths. From source it is one command:

    cargo build --release   # produces ./target/release/everasync
  • A public HTTPS URL that reaches the server. Slack refuses plain HTTP and refuses to talk to localhost. For local development a tunnel is enough (cloudflared tunnel --url http://localhost:8100, ngrok, tailscale funnel).

1. everasync init​

everasync init

This writes a fully commented everasync.toml into the current directory with every section present and the optional ones commented out. It refuses to overwrite an existing file — pass --force if that is what you want.

Trim it down to the minimum you actually need:

[server]
bind = "0.0.0.0:8100"

[storage]
driver = "sqlite"
path = "everasync.db"

[channels.slack]
signing_secret_env = "SLACK_SIGNING_SECRET"
bot_token_env = "SLACK_BOT_TOKEN"

That is a complete, working configuration. Everything else has a default.

2. Set the environment variables​

Look at the config again: it names SLACK_SIGNING_SECRET, it does not contain it. Credentials in the static TOML configuration use *_env indirection: the file stores the name of an environment variable, and its value lives in the environment. Dashboard-managed connections store their credentials encrypted on the server instead. See the secret indirection rule.

Get the two Slack values from Slack setup, then:

export SLACK_SIGNING_SECRET=...       # Basic Information → Signing Secret
export SLACK_BOT_TOKEN=xoxb-... # OAuth & Permissions → Bot User OAuth Token
Missing variables fail loudly

If everasync.toml names a variable that is not set, startup fails with config error: environment variable `SLACK_SIGNING_SECRET` is not set — not with a server that quietly rejects every webhook.

3. everasync serve​

everasync serve                      # reads ./everasync.toml
everasync serve --config /etc/everasync.toml

The server listens on [server] bind (default 0.0.0.0:8100) and exposes:

RoutePurposeNeeds a credential?
POST /ingress/{channel}webhook intake, per channel pluginnever — the platform's own signature is the check
GET /healthzliveness — returns oknever
GET /api/v1/auth/modewhat, if anything, is being enforcednever
GET /metricsPrometheus countersyes, viewer — once you turn auth on
GET /api/v1/statusevery registered pluginviewer
GET · PUT /api/v1/charter · /api/v1/policies/…read / change behaviourviewer · operator
POST /api/v1/digest/senddeliver a digest to real peopleboard

Check it locally before wiring Slack:

curl -s localhost:8100/healthz          # → ok
curl -s localhost:8100/api/v1/status # → {"plugins":[{"id":"slack",...}]}
Nothing above asks for a credential yet

[auth] mode defaults to local_trusted: every caller is treated as a board principal, which is why those two curls just work. That is correct on a laptop and on a private network, and wrong the moment this port is reachable from the internet — /api/v1 is writable, and one anonymous PUT can silence the bot or rewrite your charter.

Turning it on is one config block, with three providers to choose from: static API tokens (token), local password users (local), or browser SSO against Slack, Discord, GitHub, Google and Ever Gauzy (oauth). Read Security & authentication before you publish a hostname, and Setting up SSO if you want sign-in buttons.

If status shows an empty plugins array, your [channels.slack] section is missing or misspelled — a section that is absent silently disables its plugin.

warning
Windows: os error 10013 on bind

Ports 8080–8579 commonly sit inside a Hyper-V/WinNAT excluded port range, which includes the default 8100. List them with netsh interface ipv4 show excludedportrange protocol=tcp and pick a [server] bind port outside the reserved ranges.

4. Point Slack at it​

Create the Slack app from the manifest in Slack setup, which sets two URLs:

Event Subscriptions   https://<your-host>/ingress/slack/events
/async slash command https://<your-host>/ingress/slack/commands

When Slack validates the events URL it sends a url_verification challenge. The server must already be running — Ever Async echoes the challenge automatically, and Slack only accepts the URL if it gets that echo back.

Then, in a channel you want covered:

/invite @EverAsync
/async status

Ever Async is per-channel opt-in: it only ever sees channels the bot is a member of. /async status replying with the current policy confirms the whole round trip — HTTPS ingress, signature verification, and the bot token.

5. See it work​

Post this in that channel, from an account that is not the bot:

Hi, can I get some help?

Nothing happens publicly. About 150 seconds later you and only you see an ephemeral message explaining that the message does not yet say what you need. Reply in the thread with the detail before the window closes and the nudge is cancelled — self-correction always wins.

Now try the other path. Open a pull request on GitHub, add the GitHub connector, and post:

I finished the PR, can someone review it?

This time there is no nudge — there is a thread reply with the pull request, its title and its status. The message became actionable without anyone being told off.

Verify the whole install​

everasync doctor

doctor loads the config, assembles every plugin exactly as serve does, then health-checks each channel and connector concurrently and exits non-zero if any check fails. Use it in CI and after every credential rotation — see Operations.

Next​