@kody/notify
Fan out a short notification to your email, Slack, Discord, or Telegram from saved channel config.
README.md
137 lines · 5.8 KB · Markdown@kody/notify
Intent
Give every Kody account a single fanout export that notifies the signed-in
user across the destinations they connected: Kody email (email_send to
their account inbox), Slack (via @kody/slack user-token helpers), Discord
(bot token + their channel), and Telegram (bot token + their chat). Channel
config lives in this package's packageStorage(). Success means a forked
copy can dry-run, then send, without anyone hard-coding Kent or official
Kody destinations.
Live @kody/notify storage is the platform package bucket, not the caller's.
Fork first (or computed import(specifier) of the user's copy) before saving channels.
What it does
One export fans out a short message to every enabled destination. Email is on by default (no secret). Slack, Discord, and Telegram stay off until the fork owner enables them and stores their channel or chat id.
| Field | Purpose |
|---|---|
text / subject / title / html | Message. html is email-only. |
dryRun | Preview without sending and without writing configure. |
channels | Optional subset: email, slack, discord, telegram. |
configure | Merge destination config into packageStorage. |
Prerequisites / setup
Do not ask the user to paste tokens into chat. Hand them the prefilled URL,
wait until they confirm it is saved, then store their destination ids with
configure + dryRun: true first. Never copy channel, guild, or chat ids
from Kent, @kody, or another account.
1. Fork so storage is theirs
Install/fork this listing into the user's account. Then invoke their
notify (resolve the installed export specifier). Configuring the live
@kody/notify package writes the platform bucket.
2. Email (no secret)
Kody email_send already delivers to the signed-in account email. Tell the
user: "Email is already connected — notifies go to your Kody inbox. Say if
you want it off."
3. Slack (OAuth user token via @kody/slack)
This package depends on @kody/slack. Need a user-token connection
(not a bot token) with scope chat:write.
Create a Slack app, register redirect URI exactly
https://kody.codes/connect/oauth, add User Token Scopes
chat:write (plus the read scopes @kody/slack uses), then open:
https://kody.codes/connect/oauth?provider=slack&authorizeUrl=https%3A%2F%2Fslack.com%2Foauth%2Fv2_user%2Fauthorize&tokenUrl=https%3A%2F%2Fslack.com%2Fapi%2Foauth.v2.user.access&apiBaseUrl=https%3A%2F%2Fslack.com%2Fapi&flow=confidential&tokenExchangeStyle=form&scopeSeparator=%2C&allowedHosts=slack.com&dashboardUrl=https%3A%2F%2Fapi.slack.com%2Fapps&scopes=chat%3Awrite%2Cchannels%3Ahistory%2Cchannels%3Aread%2Cgroups%3Ahistory%2Cgroups%3Aread%2Cim%3Ahistory%2Cim%3Aread%2Cmpim%3Ahistory%2Cmpim%3Aread%2Cusers%3AreadPaste Client ID / Client Secret into the Kody form, not into chat. After
connect, ask them which conversation to notify and save that id via
configure (see AGENTS.md).
Second workspace: change provider= to slack-work and pass
integration: 'slack-work'. Reconnect with
https://kody.codes/connect/oauth?provider=<integration>.
4. Discord (bot token)
User OAuth cannot post in servers. Posting requires a bot.
- discord.com/developers/applications → New Application → Bot tab → copy the bot token.
- Invite the bot into their server with View Channel, Send Messages,
Read Message History (permissions
68608):
https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot&permissions=68608- Save the token (never paste it into chat). Approve host
discord.com:
https://kody.codes/account/secrets/new?name=discordBotToken&description=Discord%20bot%20token&allowedHosts=discord.com&scope=user- Store their destination channel snowflake via
configure(seeAGENTS.md).
Second bot: save another secret (name=discordBotTokenWork) with the same
allowedHosts=discord.com, then pass that secretName.
5. Telegram (bot token)
Telegram Login OAuth (oauth.telegram.org) is identity only and cannot send
messages. Sending uses the Bot API.
- @BotFather →
/newbot→ copy the token. - Message the bot (or add it to the target group).
- Save the token. Approve host
api.telegram.org:
https://kody.codes/account/secrets/new?name=telegramBotToken&description=Telegram%20bot%20token%20from%20BotFather&allowedHosts=api.telegram.org&scope=user- Store their numeric
chatIdviaconfigure(seeAGENTS.md).
Auth model
| Destination | Kind | Default identity | Hosts |
|---|---|---|---|
Kody notify-self (email_send) | Account email | none | |
| Slack | OAuth user token via @kody/slack | Integration slack | slack.com |
| Discord | Bot token secret | Secret discordBotToken | discord.com |
| Telegram | Bot token secret | Secret telegramBotToken | api.telegram.org |
Multi-account: set configure.slack.integration,
configure.discord.secretName, or configure.telegram.secretName. Do not
hard-code personal aliases. Never paste tokens into chat.
Agents: see AGENTS.md for fork invoke, configure dry-runs,
smoke checks, and troubleshooting.
Done when
- User forked (or invokes their installed copy) before any
configurewrite - Email path dry-runs without sending
- Slack/Discord/Telegram only enabled after their channel/chat ids are saved
- Live send requires explicit user confirmation of text and destinations
Out of scope
This package does not run a Discord gateway, manage the official Kody
Discord server, or pin a personal “send me a message” channel. Use
@kody/slack (and @kody/discord / @kody/telegram when listed) for
richer provider APIs.