Connecting integrations
Each integration a person connects (Google, Jira, X, Trello, GitHub, Shopify and Telegram) needs an app registered with that service under your account. An app's callback URL names one server, so each server needs its own.
For each one: register the app, give it the callback URL below, put its
credentials in .env.selfhost, and run
docker compose --env-file .env.selfhost up -d. An integration whose
settings are missing is not offered.
In the URLs below, https://client.example.com stands for your server's
public address: FUNCTION_SCHEME://FUNCTION_DOMAIN under compose, otherwise
PUBLIC_API_URL. A provider must be able to reach it, so a server on
localhost can't complete these sign-ins.
| Service | Register at | Callback or URL to give it | Settings |
|---|---|---|---|
| Google (Gmail, Calendar, Drive) | Google Cloud console: an OAuth client of type Web application | https://client.example.com/api/google/auth/callback (Authorized redirect URI) | GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI |
| Jira | Atlassian developer console: an OAuth 2.0 (3LO) app | https://client.example.com/api/jira/auth/callback | JIRA_CLIENT_ID, JIRA_CLIENT_SECRET, JIRA_REDIRECT_URI |
| X | X developer portal: user authentication, OAuth 2.0, type Web App | https://client.example.com/api/twitter/auth/callback | TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET, TWITTER_REDIRECT_URI |
| Trello | Trello Power-Up admin: a Power-Up's API key and secret; add your server's origin to its allowed origins | https://client.example.com/api/trello/auth/callback-with-state | TRELLO_API_KEY, TRELLO_API_SECRET, TRELLO_REDIRECT_URI |
| GitHub (linking a space to a repository) | GitHub: a GitHub App | Setup URL https://client.example.com/api/webhooks/github-app/setup (GET); Webhook URL https://client.example.com/api/webhooks/github-app (POST) | GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_SLUG, GITHUB_APP_WEBHOOK_SECRET |
| Telegram bot | @BotFather in Telegram | none: each person pastes their bot's token into the client, and the server registers the bot's webhook itself | SERVER_BASE_URL (compose sets it) |
Every *_REDIRECT_URI is the callback URL in the same row, written exactly
as you registered it.
Notes by service
Google. Gmail and Drive scopes are restricted: until Google verifies your app, only the test users you list on its OAuth consent screen can connect, and verification is Google's review of your app.
GitHub. The server commits a linked space's files to the repository, so the
App needs repository Contents read and write. Subscribe its webhook to
Push, so commits made directly on GitHub flow back; GitHub sends the
installation events to every App. GITHUB_APP_PRIVATE_KEY is the App's private
key, either the PEM text or the PEM base64-encoded on one line.
GITHUB_APP_SLUG is the App's name in its URL (github.com/apps/<slug>).
GITHUB_APP_WEBHOOK_SECRET is the webhook secret you set on the App.
Telegram. The server registers each bot's webhook under SERVER_BASE_URL.
Compose sets it to the server's public address, PUBLIC_API_URL when you set
one, else FUNCTION_SCHEME://FUNCTION_DOMAIN. Telegram only calls webhooks over
https, so the address must be https. A server outside compose sets
SERVER_BASE_URL=https://client.example.com itself; without it, registering a
bot fails with Server configuration error: SERVER_BASE_URL not set.
Shopify. A merchant connects their own store with a custom app they
create in the Shopify Dev Dashboard, entering its Client ID and Client
Secret in the client. That needs nothing on the server. Running your own public
Shopify app (SHOPIFY_PARTNER_APP_ENABLED=true) is separate, and
.env.selfhost.example lists its settings and URLs, including the callback
https://client.example.com/api/shopify/auth/callback.
The OAuth state
Each connect carries a signed state. The key is derived from
ENCRYPTION_MASTER_KEY, so there is nothing to set. OAUTH_STATE_SECRET
gives it a key of its own if you prefer.