import z from 'zod'; import { metadata } from '../interfaces/Metadata'; import { SlackEvent } from '../interfaces/slack.event'; import { serviceResponse } from '../interfaces/common'; export const slackTeam = z.object({ id: z.string(), name: z.string(), }); export const slackAuthedUser = z.object({ id: z.string(), scope: z.string(), accessToken: z.string(), }); export const slack = z.object({ _id: z.string(), access_token: z.string(), scope: z.string(), team: slackTeam, meta: metadata, authedUser: slackAuthedUser, appId: z.string().optional(), botId: z.string().optional(), }); export const slackChannel = z.object({ _id: z.string(), slackId: z.string(), name: z.string(), channelId: z.string(), webhookUrl: z.string().optional(), configurationUrl: z.string().optional(), meta: metadata, botId: z.string().optional(), }); export type Slack = z.infer; export type SlackTeam = z.infer; export type SlackAuthedUser = z.infer; export type SlackChannel = z.infer; export interface SlackService { create(params: CreateSlackRequest): Promise; getByAccessToken(params: GetSlackByAccessTokenRequest): Promise; registerSlackInstall(params: SlackOauthRedirectPayload): Promise; getOauthPayload(code: string): Promise; createChannel(params: CreateSlackChannelRequest): Promise; getSlackChannel(params: GetSlackChannelRequest): Promise; getSlackChannelPayload(params: SlackOauthRedirectPayload): IncomingWebhookPayload; sendWelcomeMessage(params: SlackMessageRequest): Promise; sendSlackMessage(request: SlackMessageRequest): Promise; registerSlackBot(request: SlackRegisterRequest): Promise; processSlackEvent(event: SlackEvent): Promise; } /** ****************************************************************************** * Create Slack ******************************************************************************* */ export const createSlackParams = z.object({ access_token: z.string(), scope: z.string(), team: slackTeam, meta: metadata, authedUser: slackAuthedUser, botId: z.string().optional(), appId: z.string().optional(), }); export const createSlackRequest = z.object({ params: createSlackParams, }); export const createSlackResponse = serviceResponse.merge(z.object({ slack: slack.optional(), })); export type CreateSlackParams = z.infer; export type CreateSlackRequest = z.infer; export type CreateSlackResponse = z.infer; /** ****************************************************************************** * Get Slack ******************************************************************************* */ export const getSlackParamsByAccessToken = z.object({ access_token: z.string(), }); export const getSlackByAccessTokenRequest = z.object({ params: getSlackParamsByAccessToken, }); export const getSlackResponse = serviceResponse.merge(z.object({ slack: slack.nullable().optional(), })); export type GetSlackParamsByAccessToken = z.infer; export type GetSlackByAccessTokenRequest = z.infer; export type GetSlackResponse = z.infer; /** ****************************************************************************** * Slack OAuth Redirect ******************************************************************************* */ export const enterpriseSchema = z.object({ name: z.string(), id: z.string(), }); export const authedUserSchema = z.object({ id: z.string(), scope: z.string(), access_token: z.string(), token_type: z.string(), }); export const incomingWebhook = z.object({ channel: z.string(), channel_id: z.string(), configuration_url: z.string(), url: z.string(), }); export const slackOauthRedirectPayload = z.object({ ok: z.boolean(), access_token: z.string(), token_type: z.string(), scope: z.string(), bot_user_id: z.string(), app_id: z.string(), team: slackTeam, enterprise: enterpriseSchema, authed_user: authedUserSchema, incoming_webhook: incomingWebhook.optional(), }); export type SlackOauthRedirectPayload = z.infer; export type IncomingWebhookPayload = z.infer; /** ****************************************************************************** * Create Slack Channel ******************************************************************************* */ export const createSlackChannelParams = z.object({ slackId: z.string(), name: z.string(), channelId: z.string(), webhookUrl: z.string().optional(), configurationUrl: z.string().optional(), meta: metadata, }); export const createSlackChannelRequest = z.object({ params: createSlackChannelParams, }); export const createSlackChannelResponse = serviceResponse.merge(z.object({ channel: slackChannel.optional(), })); export type CreateSlackChannelParams = z.infer; export type CreateSlackChannelRequest = z.infer; export type CreateSlackChannelResponse = z.infer; /** ****************************************************************************** * Get Slack Channel ******************************************************************************* */ export const getSlackChannelParams = z.object({ channelId: z.string().optional(), name: z.string().optional(), }); export const getSlackChannelRequest = z.object({ params: getSlackChannelParams, }); export const getSlackChannelResponse = serviceResponse.merge(z.object({ channel: slackChannel.nullable().optional(), })); export type GetSlackChannelParams = z.infer; export type GetSlackChannelRequest = z.infer; export type GetSlackChannelResponse = z.infer; /** ****************************************************************************** * Slack Message ******************************************************************************* */ export const slackMessageRequest = z.object({ channel: slackChannel, slack: slack.optional(), }); export const slackRegisterRequest = z.object({ botId: z.string(), channelId: z.string(), teamId: z.string().optional(), }); export const slackRegisterResponse = serviceResponse.merge(z.object({ botId: z.string().nullable().optional(), message: z.string().optional(), block: z.object({}).nullable().optional(), })); export type SlackRegisterResponse = z.infer; export type SlackRegisterRequest = z.infer; export type SlackMessageRequest = z.infer;