The OAuth redirect endpoint: turns Slack's ?code=… callback into a stored
installation.
Mount it at the app's Redirect URL, give it a 1-arity :install callback,
and the code exchange is handled for you — your callback just persists the
result:
forward "/slack/oauth/callback", to: Slink.OAuth.Plug,
init_opts: [
client_id: "1234.5678",
client_secret: fn -> System.fetch_env!("SLACK_CLIENT_SECRET") end,
install: fn %Slink.OAuth.Install{} = install ->
MyApp.Installs.put(install.team_id, install.bot_token)
end
]Options:
:client_id(required) and:client_secret(required) — the app's client credentials (Basic Information page). The secret may be a 0-arity function, resolved per request (see the Phoenix compile-time pitfall inSlink.EventsApi.Plug).:install(required) — called with theSlink.OAuth.Installafter a successful exchange. Return:okto finish the flow;{:error, reason}(or a raise) responds 500 without claiming success.:redirect_uri— must match the authorize URL's, when one was used.:redirect_to— where to send the installer's browser after success (302). Defaults to a minimal "app installed" page.:verify_state— a 1-arity function receiving the redirect'sstateparam (ornil); returnfalseto reject the callback (403). Pair it withauthorize_url/1's:stateto tie installs to a real session — without it, anyone can complete an install they initiated against your endpoint, which is usually harmless but worth closing on public apps.
The installer clicking "Cancel" on the consent screen arrives here as
?error=access_denied; that's answered with a friendly page, no callback.