export const EMAIL_DESTINATION = 'email'
export const SLACK_DESTINATION = 'slack'
export const DISCORD_DESTINATION = 'discord'
export const TELEGRAM_DESTINATION = 'telegram'
export const DESTINATIONS = [
EMAIL_DESTINATION,
SLACK_DESTINATION,
DISCORD_DESTINATION,
TELEGRAM_DESTINATION,
] as const
export type Destination = (typeof DESTINATIONS)[number]
export const SLACK_INTEGRATION = 'slack'
export const DISCORD_BOT_TOKEN_SECRET = 'discordBotToken'
export const TELEGRAM_BOT_TOKEN_SECRET = 'telegramBotToken'
export const SLACK_CHAT_WRITE_SCOPE = 'chat:write'
export const DISCORD_BOT_PERMISSIONS = 68608
const SLACK_SCOPES = [
'chat:write',
'channels:history',
'channels:read',
'groups:history',
'groups:read',
'im:history',
'im:read',
'mpim:history',
'mpim:read',
'users:read',
].join(',')
export function slackConnectUrl(integration = SLACK_INTEGRATION): string {
return 'https://kody.codes/connect/oauth?provider=' + encodeURIComponent(integration)
}
export function slackByoConnectUrl(integration = SLACK_INTEGRATION): string {
return [
'https://kody.codes/connect/oauth?provider=' + encodeURIComponent(integration),
'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',
'scopes=' + encodeURIComponent(SLACK_SCOPES),
'allowedHosts=slack.com',
'dashboardUrl=https%3A%2F%2Fapi.slack.com%2Fapps',
].join('&')
}
export function discordSecretUrl(secretName = DISCORD_BOT_TOKEN_SECRET): string {
return (
'https://kody.codes/account/secrets/new?name=' +
encodeURIComponent(secretName) +
'&description=Discord%20bot%20token&allowedHosts=discord.com&scope=user'
)
}
export function telegramSecretUrl(secretName = TELEGRAM_BOT_TOKEN_SECRET): string {
return (
'https://kody.codes/account/secrets/new?name=' +
encodeURIComponent(secretName) +
'&description=Telegram%20bot%20token%20from%20BotFather&allowedHosts=api.telegram.org&scope=user'
)
}
export function discordBotInstallUrl(): string {
return (
'https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot&permissions=' +
DISCORD_BOT_PERMISSIONS
)
}
export function secretPlaceholder(name: string): string {
return '{{secret:' + name + '|scope=user}}'
}
export const CONNECT = {
origin: 'https://kody.codes',
email: {
capability: 'email_send',
note: 'No extra destination. kody.email_send delivers to the signed-in account email.',
},
slack: {
integration: SLACK_INTEGRATION,
redirectUri: 'https://kody.codes/connect/oauth',
authorizeUrl: 'https://slack.com/oauth/v2_user/authorize',
tokenUrl: 'https://slack.com/api/oauth.v2.user.access',
requiredScope: SLACK_CHAT_WRITE_SCOPE,
url: slackConnectUrl(),
byoUrl: slackByoConnectUrl(),
},
discord: {
secretName: DISCORD_BOT_TOKEN_SECRET,
developerPortal: 'https://discord.com/developers/applications',
host: 'discord.com',
url: discordSecretUrl(),
installUrl: discordBotInstallUrl(),
},
telegram: {
secretName: TELEGRAM_BOT_TOKEN_SECRET,
botFather: 'https://t.me/BotFather',
host: 'api.telegram.org',
url: telegramSecretUrl(),
},
} as const
export function isDestination(value: unknown): value is Destination {
return (
typeof value === 'string' &&
(DESTINATIONS as readonly string[]).includes(value)
)
}
export function assertNever(value: never): never {
throw new Error('Unhandled notify destination: ' + String(value))
}