UNPKG

@coursebuilder/core

Version:

Core package for Course Builder

1 lines 12.9 kB
{"version":3,"sources":["../../src/providers/slack.ts"],"sourcesContent":["export interface ChatPostMessageResponse {\n\tok: boolean\n\tchannel: string\n\tts: string\n\tmessage: {\n\t\ttext: string\n\t\tusername: string\n\t\tbot_id?: string\n\t\tattachments?: MessageAttachment[]\n\t\ttype: string\n\t\tsubtype?: string\n\t}\n}\n\nexport interface MessageAttachment {\n\tfallback?: string\n\tcolor?: string\n\tpretext?: string\n\tauthor_name?: string\n\tauthor_link?: string\n\tauthor_icon?: string\n\tmrkdwn_in?: string[]\n\ttitle?: string\n\ttitle_link?: string\n\ttext?: string\n\tfields?: {\n\t\ttitle: string\n\t\tvalue: string\n\t\tshort?: boolean\n\t}[]\n\timage_url?: string\n\tthumb_url?: string\n\tfooter?: string\n\tfooter_icon?: string\n\tts?: number\n}\n\nexport interface PostEphemeralResponse {\n\tok: boolean\n\tmessage_ts: string\n}\n\nexport interface PostEphemeralOptions {\n\tchannel?: string\n\tuser: string\n\ttext?: string\n\ticon_emoji?: string\n\tusername?: string\n\tas_user?: boolean\n\tthread_ts?: string\n\tattachments?: MessageAttachment[]\n}\n\nexport interface NotificationProviderConfig {\n\tid: string\n\tname: string\n\ttype: 'notification'\n\toptions: NotificationProviderConsumerConfig\n\tapiKey?: string\n\tdefaultChannelId?: string\n\tsendNotification: (\n\t\toptions: NotificationOptions,\n\t) => Promise<ChatPostMessageResponse>\n\tcreateChannel: (\n\t\toptions: CreateChannelOptions,\n\t) => Promise<CreateChannelResponse>\n\tinviteToChannel: (\n\t\toptions: InviteToChannelOptions,\n\t) => Promise<InviteToChannelResponse>\n\tpostEphemeral: (\n\t\toptions: PostEphemeralOptions,\n\t) => Promise<PostEphemeralResponse>\n}\n\nexport type NotificationProviderConsumerConfig = Omit<\n\tPartial<NotificationProviderConfig>,\n\t'options' | 'type'\n> & {\n\tapiKey?: string\n\tdefaultChannelId?: string\n}\n\nexport type NotificationOptions = {\n\tattachments?: MessageAttachment[]\n\tchannel?: string\n\ticon_emoji?: string\n\tusername?: string\n\ttext?: string\n}\n\nexport interface CreateChannelResponse {\n\tok: boolean\n\tchannel: {\n\t\tid: string\n\t\tname: string\n\t\tis_channel: boolean\n\t\tcreated: number\n\t\tis_archived: boolean\n\t\tis_general: boolean\n\t\tunlinked: number\n\t\tcreator: string\n\t\tname_normalized: string\n\t\tis_shared: boolean\n\t\tis_org_shared: boolean\n\t\tis_member: boolean\n\t\tis_private: boolean\n\t\tis_mpim: boolean\n\t\tlast_read: string\n\t\tlatest: any\n\t\tunread_count: number\n\t\tunread_count_display: number\n\t\tmembers: string[]\n\t\ttopic: {\n\t\t\tvalue: string\n\t\t\tcreator: string\n\t\t\tlast_set: number\n\t\t}\n\t\tpurpose: {\n\t\t\tvalue: string\n\t\t\tcreator: string\n\t\t\tlast_set: number\n\t\t}\n\t}\n}\n\nexport interface CreateChannelOptions {\n\tname: string\n\tis_private?: boolean\n}\n\nexport interface InviteToChannelResponse {\n\tok: boolean\n\tchannel: {\n\t\tid: string\n\t\tname: string\n\t\tis_channel: boolean\n\t\tcreated: number\n\t\tcreator: string\n\t\tis_archived: boolean\n\t\tis_general: boolean\n\t\tname_normalized: string\n\t\tis_shared: boolean\n\t\tis_org_shared: boolean\n\t\tis_member: boolean\n\t\tis_private: boolean\n\t\tis_mpim: boolean\n\t\tis_read_only: boolean\n\t\tis_pending_ext_shared: boolean\n\t\tpending_shared: string[]\n\t\tunlinked: number\n\t}\n}\n\nexport interface InviteToChannelOptions {\n\t/**\n\t * The ID of the public or private channel to invite users to\n\t */\n\tchannel: string\n\t/**\n\t * A comma separated list of user IDs. Up to 1000 users may be listed.\n\t */\n\tusers: string | string[]\n\t/**\n\t * When set to true and multiple user IDs are provided, continue inviting the valid ones while disregarding invalid IDs\n\t */\n\tforce?: boolean\n}\n\nexport default function SlackProvider(\n\toptions: NotificationProviderConsumerConfig,\n): NotificationProviderConfig {\n\treturn {\n\t\tid: 'slack',\n\t\tname: 'Slack',\n\t\ttype: 'notification',\n\t\toptions,\n\t\t...options,\n\t\tsendNotification: async (sendOptions) => {\n\t\t\tif (!options.apiKey) {\n\t\t\t\tthrow new Error('No apiKey found for notification provider')\n\t\t\t}\n\t\t\tconst channel = sendOptions.channel || options.defaultChannelId\n\t\t\tif (!channel) {\n\t\t\t\tthrow new Error('No channel found')\n\t\t\t}\n\t\t\tconst {\n\t\t\t\tattachments,\n\t\t\t\ttext,\n\t\t\t\ticon_emoji = ':robot_face:',\n\t\t\t\tusername = 'Announce Bot',\n\t\t\t} = sendOptions\n\n\t\t\ttry {\n\t\t\t\tconst response = await fetch('https://slack.com/api/chat.postMessage', {\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${options.apiKey}`,\n\t\t\t\t\t\t'Content-Type': 'application/json; charset=utf-8',\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\ticon_emoji,\n\t\t\t\t\t\tusername,\n\t\t\t\t\t\tattachments,\n\t\t\t\t\t\tchannel,\n\t\t\t\t\t\ttext,\n\t\t\t\t\t}),\n\t\t\t\t})\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${response.statusText}`)\n\t\t\t\t}\n\n\t\t\t\treturn (await response.json()) as ChatPostMessageResponse\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e)\n\t\t\t\treturn Promise.reject(e)\n\t\t\t}\n\t\t},\n\t\tcreateChannel: async (createOptions) => {\n\t\t\tif (!options.apiKey) {\n\t\t\t\tthrow new Error('No apiKey found for notification provider')\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(\n\t\t\t\t\t'https://slack.com/api/conversations.create',\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${options.apiKey}`,\n\t\t\t\t\t\t\t'Content-Type': 'application/json; charset=utf-8',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: JSON.stringify(createOptions),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${response.statusText}`)\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\n\t\t\t\tif (!data.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${data.error}`)\n\t\t\t\t}\n\n\t\t\t\treturn data as CreateChannelResponse\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e)\n\t\t\t\treturn Promise.reject(e)\n\t\t\t}\n\t\t},\n\t\tinviteToChannel: async (inviteOptions) => {\n\t\t\tif (!options.apiKey) {\n\t\t\t\tthrow new Error('No apiKey found for notification provider')\n\t\t\t}\n\n\t\t\tconst users = Array.isArray(inviteOptions.users)\n\t\t\t\t? inviteOptions.users.join(',')\n\t\t\t\t: inviteOptions.users\n\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(\n\t\t\t\t\t'https://slack.com/api/conversations.invite',\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${options.apiKey}`,\n\t\t\t\t\t\t\t'Content-Type': 'application/json; charset=utf-8',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\tchannel: inviteOptions.channel,\n\t\t\t\t\t\t\tusers,\n\t\t\t\t\t\t\tforce: inviteOptions.force,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${response.statusText}`)\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\n\t\t\t\tif (!data.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${data.error}`)\n\t\t\t\t}\n\n\t\t\t\treturn data as InviteToChannelResponse\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e)\n\t\t\t\treturn Promise.reject(e)\n\t\t\t}\n\t\t},\n\t\tpostEphemeral: async (ephemeralOptions) => {\n\t\t\tif (!options.apiKey) {\n\t\t\t\tthrow new Error('No apiKey found for notification provider')\n\t\t\t}\n\t\t\tconst channel = ephemeralOptions.channel || options.defaultChannelId\n\t\t\tif (!channel) {\n\t\t\t\tthrow new Error('No channel found')\n\t\t\t}\n\n\t\t\tconst {\n\t\t\t\ttext,\n\t\t\t\ticon_emoji = ':eggo:',\n\t\t\t\tusername = 'eggo',\n\t\t\t\tuser,\n\t\t\t\tas_user,\n\t\t\t\tthread_ts,\n\t\t\t\tattachments,\n\t\t\t} = ephemeralOptions\n\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(\n\t\t\t\t\t'https://slack.com/api/chat.postEphemeral',\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${options.apiKey}`,\n\t\t\t\t\t\t\t'Content-Type': 'application/json; charset=utf-8',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\ticon_emoji,\n\t\t\t\t\t\t\tusername,\n\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\tuser,\n\t\t\t\t\t\t\tas_user,\n\t\t\t\t\t\t\tthread_ts,\n\t\t\t\t\t\t\tattachments,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${response.statusText}`)\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\n\t\t\t\tif (!data.ok) {\n\t\t\t\t\tthrow new Error(`Slack API error: ${data.error}`)\n\t\t\t\t}\n\n\t\t\t\treturn data as PostEphemeralResponse\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(e)\n\t\t\t\treturn Promise.reject(e)\n\t\t\t}\n\t\t},\n\t} as const\n}\n\nexport const mockSlackProvider: NotificationProviderConfig = {\n\tid: 'mock-slack' as const,\n\tname: 'Mock Slack',\n\ttype: 'notification',\n\toptions: {\n\t\tapiKey: 'mock-api-key',\n\t},\n\tapiKey: 'mock-api-key',\n\tsendNotification: async () => Promise.resolve({} as ChatPostMessageResponse),\n\tcreateChannel: async () => Promise.resolve({} as CreateChannelResponse),\n\tinviteToChannel: async () => Promise.resolve({} as InviteToChannelResponse),\n\tpostEphemeral: async () => Promise.resolve({} as PostEphemeralResponse),\n}\n"],"mappings":"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","names":["options","id","name","type","sendNotification","sendOptions","apiKey","Error","channel","defaultChannelId","attachments","text","icon_emoji","username","response","fetch","method","headers","Authorization","body","JSON","stringify","ok","statusText","json","e","console","log","Promise","reject","createChannel","createOptions","data","error","inviteToChannel","inviteOptions","users","Array","isArray","join","force","postEphemeral","ephemeralOptions","user","as_user","thread_ts","SlackProvider","mockSlackProvider","resolve"]}