Skip to content

README.md

137 lines · 5.8 KB · Markdown
Raw

@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.

FieldPurpose
text / subject / title / htmlMessage. html is email-only.
dryRunPreview without sending and without writing configure.
channelsOptional subset: email, slack, discord, telegram.
configureMerge 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%3Aread

Paste 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.

  1. discord.com/developers/applications → New Application → Bot tab → copy the bot token.
  2. 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
  1. 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
  1. Store their destination channel snowflake via configure (see AGENTS.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.

  1. @BotFather → /newbot → copy the token.
  2. Message the bot (or add it to the target group).
  3. 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
  1. Store their numeric chatId via configure (see AGENTS.md).
Auth model
DestinationKindDefault identityHosts
EmailKody notify-self (email_send)Account emailnone
SlackOAuth user token via @kody/slackIntegration slackslack.com
DiscordBot token secretSecret discordBotTokendiscord.com
TelegramBot token secretSecret telegramBotTokenapi.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 configure write
  • 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.