Slack¶
ALMa talks to Slack in two directions, and both use the same app and the same token:
| Direction | What it does | The feature it serves |
|---|---|---|
| Outbound | ALMa posts digests of new papers to a channel or a DM | Alerts — see Setting up alerts |
| Inbound | You post a paper link from your phone; ALMa captures it | Inbox — see Capturing from your phone |
Steps 1–5 below are the setup, done once. Then do step 6, step 7, or both, depending on which directions you want.
What you are actually setting up¶
ALMa is not in the Slack App Directory — it runs on your machine, so there is nothing to install from a marketplace. Instead you register a small private app inside your own workspace.
Four things are involved, and keeping them straight makes every step obvious:
| Thing | What it is | Lives at |
|---|---|---|
| The app | A private integration you register. Owns the permissions and issues the token. Only your workspace can see it. | api.slack.com/apps |
| The bot user | The account the app creates inside your workspace — @ALMa in the member list. This is what you invite to a channel. |
Your Slack sidebar, under Apps |
| The bot token | A secret string starting xoxb-. ALMa sends it with every request to prove who it is. |
Copied once, pasted into ALMa Settings |
| Scopes | The permissions attached to that token. A token can only do what its scopes allow. | Set on the app, before you install |
Two rules cause almost every setup failure:
- Scopes are fixed at install time. Adding a scope afterwards does nothing until you reinstall. This page grants everything up front so you install exactly once.
- A bot can only read channels it has been added to. Installing the app grants it nothing by itself — you invite the bot to specific channels later.
Why a bot token and not your own account
Slack also issues user tokens, which act as you and can read everything you can, including your DMs. ALMa uses a bot token, which sees only the channels you explicitly add it to. That is also why capture uses a channel rather than a message-to-self: no bot can read your self-DM.
Step 1 — Create the app¶
- Go to api.slack.com/apps and sign in with the account you use for your workspace.
- Create New App → From scratch.
- App Name:
ALMa. Pick a workspace: yours. → Create App.
You land on the app's settings page. Nothing has reached your workspace yet — that is step 3.
Step 2 — Grant the permissions¶
Left sidebar → OAuth & Permissions → scroll to Scopes → Bot Token Scopes → Add an OAuth Scope, once per row you need.
Always add this one:
| Scope | What it lets ALMa do |
|---|---|
chat:write |
Post messages — alert digests, and the reply explaining a link it couldn't identify |
Add these too if you want capture (sending papers to yourself from your phone):
| Scope | What it lets ALMa do |
|---|---|
channels:read |
Look up a channel by name |
groups:read |
Same, for private channels |
groups:history |
Read messages in a private capture channel |
reactions:write |
Add the 📥 / 📚 / ❓ receipt to your message |
channels:history |
Read messages in a public capture channel — only if yours is public |
Add these if you want alerts sent to a person as a DM rather than a channel:
| Scope | What it lets ALMa do |
|---|---|
users:read |
Resolve a display name like Andrea Costantino |
im:write |
Open the DM to send into |
Add channels:read even for a private channel
ALMa resolves a channel name by listing public and private channels in one
call, so Slack demands both channels:read and groups:read. With only one,
the call fails missing_scope and capture silently finds nothing.
Prefer to grant less? Skip channels:read and give ALMa the channel ID
(C…, from Channel details → About → Channel ID) instead of the name —
an ID is used directly and never triggers a channel listing.
Step 3 — Install it into your workspace¶
This is the step that actually adds ALMa to Slack.
- Scroll to the top of OAuth & Permissions.
- Install to Workspace.
- Slack shows exactly what you granted → Allow.
@ALMa now exists in your workspace, in the sidebar under Apps.
Coming back later to add a scope?
Add it, then use Reinstall to Workspace on the same page. Until you reinstall, the new scope has no effect — the token stays valid and the call just keeps failing. Your token does not change when you reinstall, so there is nothing to re-paste into ALMa.
Step 4 — Switch the plugin on and give ALMa the token¶
-
At the top of OAuth & Permissions, copy the Bot User OAuth Token (starts
xoxb-).Treat this like a password
Anyone holding it can act as your bot. If it leaks, hit Regenerate on that page and paste the new one into ALMa.
-
In ALMa: Settings → Plugins → Slack, switch it on — the fields appear — paste the token into Bot token, and Save plugin settings.
ALMa keeps the token in its secret store (data/secrets.json, gitignored, mode
0600) — never in settings.json, never in .env — and shows only a masked
version afterwards. Leave the masked value in place when you edit other fields;
it keeps the stored token.
Step 5 — Check it works¶
Settings → Plugins → Slack → Test connection. ALMa queues a job (visible in
Activity as integrations.slack.test) that posts an "ALMa — Connection
Test" message through the same code path real digests use. The toast names the
resolved target on success, or the precise Slack error on failure.
The test only runs while the plugin is on. Off, it is refused outright — see what is true of every plugin.
Step 6 — Send digests to a channel or a DM¶
Send alerts to accepts any of:
- a channel name —
generalor#general; - a user display name —
Andrea Costantino, which resolves to a DM; - a Slack ID —
C0123…for a channel,U0123…for a user.
Resolution to an ID happens at send time and is cached for the lifetime of the
backend process, so a wrong name produces a precise channel_not_found in the
Activity row rather than a generic failure.
For a channel target, invite the bot to that channel first (/invite @ALMa) —
a bot cannot post where it is not a member.
Building the digests themselves is a separate job: → Setting up alerts
Step 7 — Capture papers from a channel¶
Create the capture channel and add the bot to that channel¶
Now in the Slack app itself (not the developer site):
- Click + beside Channels in the sidebar → Create a channel.
- Name:
alma-inbox. Visibility: Private. → Create. -
Open
#alma-inboxand send this message in the channel:/invite @ALMaUse your bot's actual name if you named the app something else — Slack autocompletes it as you type. If nothing autocompletes, the app is not installed — see step 3.
-
Slack confirms: "@ALMa was added to #alma-inbox".
That invite is the membership that matters. The bot can now read
#alma-inbox — and still nothing else: not your other channels, not your DMs.
Use a channel for nothing else
Every message here is treated as a capture attempt. Don't reuse a channel you chat in.
Tell ALMa which channel to read¶
Settings → Plugins → Slack → Capture papers from → type alma-inbox
(bare name, no #) → Save plugin settings.
Empty field = capture off.
Why this is separate from 'Send alerts to'
Send alerts to is where ALMa posts digests. Capture papers from
is what it reads. They can be the same channel — the poller skips any
message carrying a bot_id, so ALMa never re-reads its own digests. A
dedicated capture channel is still better: digests are long and frequent,
and they bury the links you send.
Prove it works¶
-
In Slack, post a paper link into
#alma-inbox:https://doi.org/10.1038/s41586-019-1666-5 -
In ALMa: Settings → Plugins → Slack → Check capture now — runs the check immediately instead of waiting up to 5 minutes.
- Expect the toast "Captured 1 paper". (With nothing new to capture you get "Connected to #alma-inbox" instead — that is also a success, and it confirms the token, scopes, channel and bot membership are all correct.)
- In Slack, your message now shows a 📥 reaction.
- Open Home — the paper is in the Inbox section.
From then on, just post links: ALMa checks every five minutes on its own. What to expect on your phone, what it recognises, and how to triage what lands is the feature guide: → Capturing from your phone
Troubleshooting¶
| What you saw | Cause | Fix |
|---|---|---|
Slack token not configured |
No token saved | Redo step 4 |
invalid_auth |
Token wrong, or regenerated in Slack | Re-copy it from OAuth & Permissions and save it again |
missing_scope |
A scope is absent, or the app wasn't reinstalled after you added one | Recheck step 2, then Reinstall to Workspace |
channel_not_found: '…' |
The resolver tried conversations.list then users.list and found no match |
Check the spelling, that the bot is in the channel, and that channels:read / groups:read / users:read are granted |
not_in_channel |
The bot isn't a member of the channel | /invite @ALMa in that channel |
Slack API rejected the test message |
Token and resolution are fine, but the bot cannot post to that target | Usually channel membership; for a user DM, check im:write |
| "No capture channel is configured" | Capture papers from is empty, or didn't save | Re-enter the bare channel name and save |
| ❓ instead of 📥 on your message | The link held no identifiable paper | Read ALMa's thread reply |
Related¶
- Setting up alerts — build the digests
- Capturing from your phone — use the inbound direction
- Plugins — what is true of every plugin