From 2077591b65d9f518e3064740248214af151b7040 Mon Sep 17 00:00:00 2001 From: LittleC Date: Thu, 13 Jul 2023 21:40:26 +0800 Subject: [PATCH] feat(slack): generated internal api --- adapters/slack/src/bot.ts | 49 +- adapters/slack/src/message.ts | 3 +- adapters/slack/src/types/admin.ts | 909 ++++++++++++++++++++++ adapters/slack/src/types/api.ts | 30 + adapters/slack/src/types/apps.ts | 175 +++++ adapters/slack/src/types/auth.ts | 50 ++ adapters/slack/src/types/bots.ts | 42 + adapters/slack/src/types/calls.ts | 112 +++ adapters/slack/src/types/chat.ts | 255 ++++++ adapters/slack/src/types/conversations.ts | 343 ++++++++ adapters/slack/src/types/definition.ts | 530 +++++++++++++ adapters/slack/src/types/dialog.ts | 30 + adapters/slack/src/types/dnd.ts | 96 +++ adapters/slack/src/types/emoji.ts | 28 + adapters/slack/src/types/files.ts | 246 ++++++ adapters/slack/src/types/index.ts | 28 + adapters/slack/src/types/internal.ts | 57 ++ adapters/slack/src/types/migration.ts | 36 + adapters/slack/src/types/oauth.ts | 68 ++ adapters/slack/src/types/pins.ts | 57 ++ adapters/slack/src/types/reactions.ts | 96 +++ adapters/slack/src/types/reminders.ts | 89 +++ adapters/slack/src/types/rtm.ts | 40 + adapters/slack/src/types/search.ts | 34 + adapters/slack/src/types/stars.ts | 73 ++ adapters/slack/src/types/team.ts | 123 +++ adapters/slack/src/types/usergroups.ts | 136 ++++ adapters/slack/src/types/users.ts | 222 ++++++ adapters/slack/src/types/views.ts | 78 ++ adapters/slack/src/types/workflows.ts | 63 ++ adapters/slack/src/utils.ts | 16 +- 31 files changed, 4083 insertions(+), 31 deletions(-) create mode 100644 adapters/slack/src/types/admin.ts create mode 100644 adapters/slack/src/types/api.ts create mode 100644 adapters/slack/src/types/apps.ts create mode 100644 adapters/slack/src/types/auth.ts create mode 100644 adapters/slack/src/types/bots.ts create mode 100644 adapters/slack/src/types/calls.ts create mode 100644 adapters/slack/src/types/chat.ts create mode 100644 adapters/slack/src/types/conversations.ts create mode 100644 adapters/slack/src/types/definition.ts create mode 100644 adapters/slack/src/types/dialog.ts create mode 100644 adapters/slack/src/types/dnd.ts create mode 100644 adapters/slack/src/types/emoji.ts create mode 100644 adapters/slack/src/types/files.ts create mode 100644 adapters/slack/src/types/internal.ts create mode 100644 adapters/slack/src/types/migration.ts create mode 100644 adapters/slack/src/types/oauth.ts create mode 100644 adapters/slack/src/types/pins.ts create mode 100644 adapters/slack/src/types/reactions.ts create mode 100644 adapters/slack/src/types/reminders.ts create mode 100644 adapters/slack/src/types/rtm.ts create mode 100644 adapters/slack/src/types/search.ts create mode 100644 adapters/slack/src/types/stars.ts create mode 100644 adapters/slack/src/types/team.ts create mode 100644 adapters/slack/src/types/usergroups.ts create mode 100644 adapters/slack/src/types/users.ts create mode 100644 adapters/slack/src/types/views.ts create mode 100644 adapters/slack/src/types/workflows.ts diff --git a/adapters/slack/src/bot.ts b/adapters/slack/src/bot.ts index 79809eca..5be04326 100644 --- a/adapters/slack/src/bot.ts +++ b/adapters/slack/src/bot.ts @@ -6,18 +6,18 @@ import { SlackMessageEncoder } from './message' import { GenericMessageEvent, SlackChannel, SlackTeam, SlackUser } from './types' import FormData from 'form-data' import * as WebApi from 'seratch-slack-types/web-api' +import { Internal, Token } from './types/internal' export class SlackBot extends Bot { static MessageEncoder = SlackMessageEncoder public http: Quester + public internal: Internal constructor(ctx: Context, config: T) { super(ctx, config) - this.http = ctx.http.extend({ - headers: { - // 'Authorization': `Bearer ${config.token}`, - }, - }).extend(config) + this.http = ctx.http.extend(config) + + this.internal = new Internal(this, this.http) if (config.protocol === 'ws') { ctx.plugin(WsClient, this) @@ -41,7 +41,7 @@ export class SlackBot extends Bot('POST', '/auth.test') + const data = await this.internal.authTest(Token.BOT) return { userId: data.user_id, avatar: null, @@ -51,18 +51,20 @@ export class SlackBot extends Bot { - return this.request('POST', '/chat.delete', { channel: channelId, ts: messageId }) + await this.internal.chatDelete(Token.BOT, { + channel: channelId, + ts: Number(messageId), + }) } async getMessage(channelId: string, messageId: string): Promise { - const msg = await this.request<{ - messages: GenericMessageEvent[] - }>('POST', '/conversations.history', { + const msg = await this.internal.conversationsHistory(Token.BOT, { channel: channelId, - oldest: messageId, + oldest: Number(messageId), limit: 1, inclusive: true, }) + // @ts-ignore return adaptMessage(this, msg.messages[0]) } @@ -73,7 +75,7 @@ export class SlackBot extends Bot adaptMessage(this, v)) + return Promise.all(msg.messages.map(v => adaptMessage(this, v))) } async getUser(userId: string, guildId?: string): Promise { @@ -128,19 +130,18 @@ export class SlackBot extends Bot { // "channels:write,groups:write,mpim:write,im:write", - const { channel } = await this.request<{ - channel: { - id: string - } - }>('POST', '/conversations.open', { + const { channel } = await this.internal.conversationsOpen(Token.BOT, { users: channelId, }) + // @ts-ignore return this.sendMessage(channel.id, content, undefined, options) } async getReactions(channelId: string, messageId: string, emoji: string): Promise { - const { message } = await this.request('POST', '/reactions.get', `channel=${channelId}×tamp=${messageId}&emoji=${emoji}`, { - 'content-type': 'application/x-www-form-urlencoded', + const { message } = await this.internal.reactionsGet(Token.BOT, { + channel: channelId, + timestamp: messageId, + full: true, }) return message.reactions.find(v => v.name === emoji)?.users.map(v => ({ userId: v, @@ -149,7 +150,7 @@ export class SlackBot extends Bot { // reactions.write - return this.request('POST', '/reactions.add', { + await this.internal.reactionsAdd(Token.BOT, { channel: channelId, timestamp: messageId, name: emoji, @@ -157,12 +158,14 @@ export class SlackBot extends Bot { - const { message } = await this.request('POST', '/reactions.get', `channel=${channelId}×tamp=${messageId}&full=true`, { - 'content-type': 'application/x-www-form-urlencoded', + const { message } = await this.internal.reactionsGet(Token.BOT, { + channel: channelId, + timestamp: messageId, + full: true, }) for (const reaction of message.reactions) { if (!emoji || reaction.name === emoji) { - await this.request('POST', '/reactions.remove', { + await this.internal.reactionsRemove(Token.BOT, { channel: channelId, timestamp: messageId, name: reaction.name, diff --git a/adapters/slack/src/message.ts b/adapters/slack/src/message.ts index a0b2eec4..21165bbc 100644 --- a/adapters/slack/src/message.ts +++ b/adapters/slack/src/message.ts @@ -28,7 +28,7 @@ export class SlackMessageEncoder extends MessageEncoder { results: Session[] = [] async flush() { if (!this.buffer.length) return - const r = await this.bot.request('POST', '/chat.postMessage', { + const r = await this.bot.internal.chatPostMessage(this.bot.config.botToken, { channel: this.channelId, ...this.addition, thread_ts: this.thread_ts, @@ -36,6 +36,7 @@ export class SlackMessageEncoder extends MessageEncoder { }) const session = this.bot.session() await adaptMessage(this.bot, r.message, session) + session.channelId = this.channelId session.app.emit(session, 'send', session) this.results.push(session) this.buffer = '' diff --git a/adapters/slack/src/types/admin.ts b/adapters/slack/src/types/admin.ts new file mode 100644 index 00000000..a4ae0306 --- /dev/null +++ b/adapters/slack/src/types/admin.ts @@ -0,0 +1,909 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/admin.apps.approve': { + POST: { 'adminAppsApprove': true }, + }, + '/admin.apps.approved.list': { + GET: { 'adminAppsApprovedList': false }, + }, + '/admin.apps.requests.list': { + GET: { 'adminAppsRequestsList': false }, + }, + '/admin.apps.restrict': { + POST: { 'adminAppsRestrict': true }, + }, + '/admin.apps.restricted.list': { + GET: { 'adminAppsRestrictedList': false }, + }, + '/admin.conversations.archive': { + POST: { 'adminConversationsArchive': true }, + }, + '/admin.conversations.convertToPrivate': { + POST: { 'adminConversationsConvertToPrivate': true }, + }, + '/admin.conversations.create': { + POST: { 'adminConversationsCreate': true }, + }, + '/admin.conversations.delete': { + POST: { 'adminConversationsDelete': true }, + }, + '/admin.conversations.disconnectShared': { + POST: { 'adminConversationsDisconnectShared': true }, + }, + '/admin.conversations.ekm.listOriginalConnectedChannelInfo': { + GET: { 'adminConversationsEkmListOriginalConnectedChannelInfo': false }, + }, + '/admin.conversations.getConversationPrefs': { + GET: { 'adminConversationsGetConversationPrefs': true }, + }, + '/admin.conversations.getTeams': { + GET: { 'adminConversationsGetTeams': true }, + }, + '/admin.conversations.invite': { + POST: { 'adminConversationsInvite': true }, + }, + '/admin.conversations.rename': { + POST: { 'adminConversationsRename': true }, + }, + '/admin.conversations.restrictAccess.addGroup': { + POST: { 'adminConversationsRestrictAccessAddGroup': false }, + }, + '/admin.conversations.restrictAccess.listGroups': { + GET: { 'adminConversationsRestrictAccessListGroups': false }, + }, + '/admin.conversations.restrictAccess.removeGroup': { + POST: { 'adminConversationsRestrictAccessRemoveGroup': false }, + }, + '/admin.conversations.search': { + GET: { 'adminConversationsSearch': true }, + }, + '/admin.conversations.setConversationPrefs': { + POST: { 'adminConversationsSetConversationPrefs': true }, + }, + '/admin.conversations.setTeams': { + POST: { 'adminConversationsSetTeams': true }, + }, + '/admin.conversations.unarchive': { + POST: { 'adminConversationsUnarchive': true }, + }, + '/admin.emoji.add': { + POST: { 'adminEmojiAdd': false }, + }, + '/admin.emoji.addAlias': { + POST: { 'adminEmojiAddAlias': false }, + }, + '/admin.emoji.list': { + GET: { 'adminEmojiList': false }, + }, + '/admin.emoji.remove': { + POST: { 'adminEmojiRemove': false }, + }, + '/admin.emoji.rename': { + POST: { 'adminEmojiRename': false }, + }, + '/admin.inviteRequests.approve': { + POST: { 'adminInviteRequestsApprove': true }, + }, + '/admin.inviteRequests.approved.list': { + GET: { 'adminInviteRequestsApprovedList': true }, + }, + '/admin.inviteRequests.denied.list': { + GET: { 'adminInviteRequestsDeniedList': true }, + }, + '/admin.inviteRequests.deny': { + POST: { 'adminInviteRequestsDeny': true }, + }, + '/admin.inviteRequests.list': { + GET: { 'adminInviteRequestsList': true }, + }, + '/admin.teams.admins.list': { + GET: { 'adminTeamsAdminsList': false }, + }, + '/admin.teams.create': { + POST: { 'adminTeamsCreate': true }, + }, + '/admin.teams.list': { + GET: { 'adminTeamsList': true }, + }, + '/admin.teams.owners.list': { + GET: { 'adminTeamsOwnersList': false }, + }, + '/admin.teams.settings.info': { + GET: { 'adminTeamsSettingsInfo': true }, + }, + '/admin.teams.settings.setDefaultChannels': { + POST: { 'adminTeamsSettingsSetDefaultChannels': false }, + }, + '/admin.teams.settings.setDescription': { + POST: { 'adminTeamsSettingsSetDescription': true }, + }, + '/admin.teams.settings.setDiscoverability': { + POST: { 'adminTeamsSettingsSetDiscoverability': true }, + }, + '/admin.teams.settings.setIcon': { + POST: { 'adminTeamsSettingsSetIcon': false }, + }, + '/admin.teams.settings.setName': { + POST: { 'adminTeamsSettingsSetName': true }, + }, + '/admin.usergroups.addChannels': { + POST: { 'adminUsergroupsAddChannels': true }, + }, + '/admin.usergroups.addTeams': { + POST: { 'adminUsergroupsAddTeams': true }, + }, + '/admin.usergroups.listChannels': { + GET: { 'adminUsergroupsListChannels': true }, + }, + '/admin.usergroups.removeChannels': { + POST: { 'adminUsergroupsRemoveChannels': true }, + }, + '/admin.users.assign': { + POST: { 'adminUsersAssign': true }, + }, + '/admin.users.invite': { + POST: { 'adminUsersInvite': true }, + }, + '/admin.users.list': { + GET: { 'adminUsersList': true }, + }, + '/admin.users.remove': { + POST: { 'adminUsersRemove': true }, + }, + '/admin.users.session.invalidate': { + POST: { 'adminUsersSessionInvalidate': true }, + }, + '/admin.users.session.reset': { + POST: { 'adminUsersSessionReset': true }, + }, + '/admin.users.setAdmin': { + POST: { 'adminUsersSetAdmin': true }, + }, + '/admin.users.setExpiration': { + POST: { 'adminUsersSetExpiration': true }, + }, + '/admin.users.setOwner': { + POST: { 'adminUsersSetOwner': true }, + }, + '/admin.users.setRegular': { + POST: { 'adminUsersSetRegular': true }, + }, +}) + +export namespace Admin { + export namespace Params { + export interface AppsApprove { + app_id?: string + request_id?: string + team_id?: string + } + export interface AppsApprovedList { + limit?: number + cursor?: string + team_id?: string + enterprise_id?: string + } + export interface AppsRequestsList { + limit?: number + cursor?: string + team_id?: string + } + export interface AppsRestrict { + app_id?: string + request_id?: string + team_id?: string + } + export interface AppsRestrictedList { + limit?: number + cursor?: string + team_id?: string + enterprise_id?: string + } + export interface ConversationsArchive { + channel_id: string + } + export interface ConversationsConvertToPrivate { + channel_id: string + } + export interface ConversationsCreate { + name: string + description?: string + is_private: boolean + org_wide?: boolean + team_id?: string + } + export interface ConversationsDelete { + channel_id: string + } + export interface ConversationsDisconnectShared { + channel_id: string + leaving_team_ids?: string + } + export interface ConversationsEkmListOriginalConnectedChannelInfo { + channel_ids?: string + team_ids?: string + limit?: number + cursor?: string + } + export interface ConversationsGetConversationPrefs { + channel_id: string + } + export interface ConversationsGetTeams { + channel_id: string + cursor?: string + limit?: number + } + export interface ConversationsInvite { + user_ids: string + channel_id: string + } + export interface ConversationsRename { + channel_id: string + name: string + } + export interface ConversationsRestrictAccessAddGroup { + team_id?: string + group_id: string + channel_id: string + } + export interface ConversationsRestrictAccessListGroups { + channel_id: string + team_id?: string + } + export interface ConversationsRestrictAccessRemoveGroup { + team_id: string + group_id: string + channel_id: string + } + export interface ConversationsSearch { + team_ids?: string + query?: string + limit?: number + cursor?: string + search_channel_types?: string + sort?: string + sort_dir?: string + } + export interface ConversationsSetConversationPrefs { + channel_id: string + prefs: string + } + export interface ConversationsSetTeams { + channel_id: string + team_id?: string + target_team_ids?: string + org_channel?: boolean + } + export interface ConversationsUnarchive { + channel_id: string + } + export interface EmojiAdd { + name: string + url: string + } + export interface EmojiAddAlias { + name: string + alias_for: string + } + export interface EmojiList { + cursor?: string + limit?: number + } + export interface EmojiRemove { + name: string + } + export interface EmojiRename { + name: string + new_name: string + } + export interface InviteRequestsApprove { + team_id?: string + invite_request_id: string + } + export interface InviteRequestsApprovedList { + team_id?: string + cursor?: string + limit?: number + } + export interface InviteRequestsDeniedList { + team_id?: string + cursor?: string + limit?: number + } + export interface InviteRequestsDeny { + team_id?: string + invite_request_id: string + } + export interface InviteRequestsList { + team_id?: string + cursor?: string + limit?: number + } + export interface TeamsAdminsList { + limit?: number + cursor?: string + team_id: string + } + export interface TeamsCreate { + team_domain: string + team_name: string + team_description?: string + team_discoverability?: string + } + export interface TeamsList { + limit?: number + cursor?: string + } + export interface TeamsOwnersList { + team_id: string + limit?: number + cursor?: string + } + export interface TeamsSettingsInfo { + team_id: string + } + export interface TeamsSettingsSetDefaultChannels { + team_id: string + channel_ids: string + } + export interface TeamsSettingsSetDescription { + team_id: string + description: string + } + export interface TeamsSettingsSetDiscoverability { + team_id: string + discoverability: string + } + export interface TeamsSettingsSetIcon { + image_url: string + team_id: string + } + export interface TeamsSettingsSetName { + team_id: string + name: string + } + export interface UsergroupsAddChannels { + usergroup_id: string + team_id?: string + channel_ids: string + } + export interface UsergroupsAddTeams { + usergroup_id: string + team_ids: string + auto_provision?: boolean + } + export interface UsergroupsListChannels { + usergroup_id: string + team_id?: string + include_num_members?: boolean + } + export interface UsergroupsRemoveChannels { + usergroup_id: string + channel_ids: string + } + export interface UsersAssign { + team_id: string + user_id: string + is_restricted?: boolean + is_ultra_restricted?: boolean + channel_ids?: string + } + export interface UsersInvite { + team_id: string + email: string + channel_ids: string + custom_message?: string + real_name?: string + resend?: boolean + is_restricted?: boolean + is_ultra_restricted?: boolean + guest_expiration_ts?: string + } + export interface UsersList { + team_id: string + cursor?: string + limit?: number + } + export interface UsersRemove { + team_id: string + user_id: string + } + export interface UsersSessionInvalidate { + team_id: string + session_id: number + } + export interface UsersSessionReset { + user_id: string + mobile_only?: boolean + web_only?: boolean + } + export interface UsersSetAdmin { + team_id: string + user_id: string + } + export interface UsersSetExpiration { + team_id: string + user_id: string + expiration_ts: number + } + export interface UsersSetOwner { + team_id: string + user_id: string + } + export interface UsersSetRegular { + team_id: string + user_id: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Approve an app for installation on a workspace. + * @see https://api.slack.com/methods/admin.apps.approve + */ + adminAppsApprove(token: TokenInput, params: Admin.Params.AppsApprove): Promise<{ + ok: boolean + }> + + /** + * List approved apps for an org or workspace. + * @see https://api.slack.com/methods/admin.apps.approved.list + */ + adminAppsApprovedList(token: TokenInput, params: Admin.Params.AppsApprovedList): Promise<{ + ok: boolean + }> + + /** + * List app requests for a team/workspace. + * @see https://api.slack.com/methods/admin.apps.requests.list + */ + adminAppsRequestsList(token: TokenInput, params: Admin.Params.AppsRequestsList): Promise<{ + ok: boolean + }> + + /** + * Restrict an app for installation on a workspace. + * @see https://api.slack.com/methods/admin.apps.restrict + */ + adminAppsRestrict(token: TokenInput, params: Admin.Params.AppsRestrict): Promise<{ + ok: boolean + }> + + /** + * List restricted apps for an org or workspace. + * @see https://api.slack.com/methods/admin.apps.restricted.list + */ + adminAppsRestrictedList(token: TokenInput, params: Admin.Params.AppsRestrictedList): Promise<{ + ok: boolean + }> + + /** + * Archive a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.archive + */ + adminConversationsArchive(token: TokenInput, params: Admin.Params.ConversationsArchive): Promise<{ + ok: boolean + }> + + /** + * Convert a public channel to a private channel. + * @see https://api.slack.com/methods/admin.conversations.convertToPrivate + */ + adminConversationsConvertToPrivate(token: TokenInput, params: Admin.Params.ConversationsConvertToPrivate): Promise<{ + ok: boolean + }> + + /** + * Create a public or private channel-based conversation. + * @see https://api.slack.com/methods/admin.conversations.create + */ + adminConversationsCreate(token: TokenInput, params: Admin.Params.ConversationsCreate): Promise<{ + channel_id?: string + ok: boolean + }> + + /** + * Delete a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.delete + */ + adminConversationsDelete(token: TokenInput, params: Admin.Params.ConversationsDelete): Promise<{ + ok: boolean + }> + + /** + * Disconnect a connected channel from one or more workspaces. + * @see https://api.slack.com/methods/admin.conversations.disconnectShared + */ + adminConversationsDisconnectShared(token: TokenInput, params: Admin.Params.ConversationsDisconnectShared): Promise<{ + ok: boolean + }> + + /** + * List all disconnected channels—i.e., channels that were once connected to other workspaces and then disconnected—and the corresponding original channel IDs for key revocation with EKM. + * @see https://api.slack.com/methods/admin.conversations.ekm.listOriginalConnectedChannelInfo + */ + adminConversationsEkmListOriginalConnectedChannelInfo(token: TokenInput, params: Admin.Params.ConversationsEkmListOriginalConnectedChannelInfo): Promise<{ + ok: boolean + }> + + /** + * Get conversation preferences for a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.getConversationPrefs + */ + adminConversationsGetConversationPrefs(token: TokenInput, params: Admin.Params.ConversationsGetConversationPrefs): Promise<{ + ok: boolean + prefs?: { + can_thread: { + type: string[] + user: string[] + } + who_can_post: { + type: string[] + user: string[] + } + } + }> + + /** + * Get all the workspaces a given public or private channel is connected to within this Enterprise org. + * @see https://api.slack.com/methods/admin.conversations.getTeams + */ + adminConversationsGetTeams(token: TokenInput, params: Admin.Params.ConversationsGetTeams): Promise<{ + ok: boolean + response_metadata?: { + next_cursor: string + } + team_ids: string[] + }> + + /** + * Invite a user to a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.invite + */ + adminConversationsInvite(token: TokenInput, params: Admin.Params.ConversationsInvite): Promise<{ + ok: boolean + }> + + /** + * Rename a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.rename + */ + adminConversationsRename(token: TokenInput, params: Admin.Params.ConversationsRename): Promise<{ + ok: boolean + }> + + /** + * Add an allowlist of IDP groups for accessing a channel + * @see https://api.slack.com/methods/admin.conversations.restrictAccess.addGroup + */ + adminConversationsRestrictAccessAddGroup(token: TokenInput, params: Admin.Params.ConversationsRestrictAccessAddGroup): Promise<{ + ok: boolean + }> + + /** + * List all IDP Groups linked to a channel + * @see https://api.slack.com/methods/admin.conversations.restrictAccess.listGroups + */ + adminConversationsRestrictAccessListGroups(token: TokenInput, params: Admin.Params.ConversationsRestrictAccessListGroups): Promise<{ + ok: boolean + }> + + /** + * Remove a linked IDP group linked from a private channel + * @see https://api.slack.com/methods/admin.conversations.restrictAccess.removeGroup + */ + adminConversationsRestrictAccessRemoveGroup(token: TokenInput, params: Admin.Params.ConversationsRestrictAccessRemoveGroup): Promise<{ + ok: boolean + }> + + /** + * Search for public or private channels in an Enterprise organization. + * @see https://api.slack.com/methods/admin.conversations.search + */ + adminConversationsSearch(token: TokenInput, params: Admin.Params.ConversationsSearch): Promise<{ + channels: Definitions.Channel[] + next_cursor: string + }> + + /** + * Set the posting permissions for a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.setConversationPrefs + */ + adminConversationsSetConversationPrefs(token: TokenInput, params: Admin.Params.ConversationsSetConversationPrefs): Promise<{ + ok: boolean + }> + + /** + * Set the workspaces in an Enterprise grid org that connect to a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.setTeams + */ + adminConversationsSetTeams(token: TokenInput, params: Admin.Params.ConversationsSetTeams): Promise<{ + ok: boolean + }> + + /** + * Unarchive a public or private channel. + * @see https://api.slack.com/methods/admin.conversations.unarchive + */ + adminConversationsUnarchive(token: TokenInput, params: Admin.Params.ConversationsUnarchive): Promise<{ + ok: boolean + }> + + /** + * Add an emoji. + * @see https://api.slack.com/methods/admin.emoji.add + */ + adminEmojiAdd(token: TokenInput, params: Admin.Params.EmojiAdd): Promise<{ + ok: boolean + }> + + /** + * Add an emoji alias. + * @see https://api.slack.com/methods/admin.emoji.addAlias + */ + adminEmojiAddAlias(token: TokenInput, params: Admin.Params.EmojiAddAlias): Promise<{ + ok: boolean + }> + + /** + * List emoji for an Enterprise Grid organization. + * @see https://api.slack.com/methods/admin.emoji.list + */ + adminEmojiList(token: TokenInput, params: Admin.Params.EmojiList): Promise<{ + ok: boolean + }> + + /** + * Remove an emoji across an Enterprise Grid organization + * @see https://api.slack.com/methods/admin.emoji.remove + */ + adminEmojiRemove(token: TokenInput, params: Admin.Params.EmojiRemove): Promise<{ + ok: boolean + }> + + /** + * Rename an emoji. + * @see https://api.slack.com/methods/admin.emoji.rename + */ + adminEmojiRename(token: TokenInput, params: Admin.Params.EmojiRename): Promise<{ + ok: boolean + }> + + /** + * Approve a workspace invite request. + * @see https://api.slack.com/methods/admin.inviteRequests.approve + */ + adminInviteRequestsApprove(token: TokenInput, params: Admin.Params.InviteRequestsApprove): Promise<{ + ok: boolean + }> + + /** + * List all approved workspace invite requests. + * @see https://api.slack.com/methods/admin.inviteRequests.approved.list + */ + adminInviteRequestsApprovedList(token: TokenInput, params: Admin.Params.InviteRequestsApprovedList): Promise<{ + ok: boolean + }> + + /** + * List all denied workspace invite requests. + * @see https://api.slack.com/methods/admin.inviteRequests.denied.list + */ + adminInviteRequestsDeniedList(token: TokenInput, params: Admin.Params.InviteRequestsDeniedList): Promise<{ + ok: boolean + }> + + /** + * Deny a workspace invite request. + * @see https://api.slack.com/methods/admin.inviteRequests.deny + */ + adminInviteRequestsDeny(token: TokenInput, params: Admin.Params.InviteRequestsDeny): Promise<{ + ok: boolean + }> + + /** + * List all pending workspace invite requests. + * @see https://api.slack.com/methods/admin.inviteRequests.list + */ + adminInviteRequestsList(token: TokenInput, params: Admin.Params.InviteRequestsList): Promise<{ + ok: boolean + }> + + /** + * List all of the admins on a given workspace. + * @see https://api.slack.com/methods/admin.teams.admins.list + */ + adminTeamsAdminsList(token: TokenInput, params: Admin.Params.TeamsAdminsList): Promise<{ + ok: boolean + }> + + /** + * Create an Enterprise team. + * @see https://api.slack.com/methods/admin.teams.create + */ + adminTeamsCreate(token: TokenInput, params: Admin.Params.TeamsCreate): Promise<{ + ok: boolean + }> + + /** + * List all teams on an Enterprise organization + * @see https://api.slack.com/methods/admin.teams.list + */ + adminTeamsList(token: TokenInput, params: Admin.Params.TeamsList): Promise<{ + ok: boolean + }> + + /** + * List all of the owners on a given workspace. + * @see https://api.slack.com/methods/admin.teams.owners.list + */ + adminTeamsOwnersList(token: TokenInput, params: Admin.Params.TeamsOwnersList): Promise<{ + ok: boolean + }> + + /** + * Fetch information about settings in a workspace + * @see https://api.slack.com/methods/admin.teams.settings.info + */ + adminTeamsSettingsInfo(token: TokenInput, params: Admin.Params.TeamsSettingsInfo): Promise<{ + ok: boolean + }> + + /** + * Set the default channels of a workspace. + * @see https://api.slack.com/methods/admin.teams.settings.setDefaultChannels + */ + adminTeamsSettingsSetDefaultChannels(token: TokenInput, params: Admin.Params.TeamsSettingsSetDefaultChannels): Promise<{ + ok: boolean + }> + + /** + * Set the description of a given workspace. + * @see https://api.slack.com/methods/admin.teams.settings.setDescription + */ + adminTeamsSettingsSetDescription(token: TokenInput, params: Admin.Params.TeamsSettingsSetDescription): Promise<{ + ok: boolean + }> + + /** + * An API method that allows admins to set the discoverability of a given workspace + * @see https://api.slack.com/methods/admin.teams.settings.setDiscoverability + */ + adminTeamsSettingsSetDiscoverability(token: TokenInput, params: Admin.Params.TeamsSettingsSetDiscoverability): Promise<{ + ok: boolean + }> + + /** + * Sets the icon of a workspace. + * @see https://api.slack.com/methods/admin.teams.settings.setIcon + */ + adminTeamsSettingsSetIcon(token: TokenInput, params: Admin.Params.TeamsSettingsSetIcon): Promise<{ + ok: boolean + }> + + /** + * Set the name of a given workspace. + * @see https://api.slack.com/methods/admin.teams.settings.setName + */ + adminTeamsSettingsSetName(token: TokenInput, params: Admin.Params.TeamsSettingsSetName): Promise<{ + ok: boolean + }> + + /** + * Add one or more default channels to an IDP group. + * @see https://api.slack.com/methods/admin.usergroups.addChannels + */ + adminUsergroupsAddChannels(token: TokenInput, params: Admin.Params.UsergroupsAddChannels): Promise<{ + ok: boolean + }> + + /** + * Associate one or more default workspaces with an organization-wide IDP group. + * @see https://api.slack.com/methods/admin.usergroups.addTeams + */ + adminUsergroupsAddTeams(token: TokenInput, params: Admin.Params.UsergroupsAddTeams): Promise<{ + ok: boolean + }> + + /** + * List the channels linked to an org-level IDP group (user group). + * @see https://api.slack.com/methods/admin.usergroups.listChannels + */ + adminUsergroupsListChannels(token: TokenInput, params: Admin.Params.UsergroupsListChannels): Promise<{ + ok: boolean + }> + + /** + * Remove one or more default channels from an org-level IDP group (user group). + * @see https://api.slack.com/methods/admin.usergroups.removeChannels + */ + adminUsergroupsRemoveChannels(token: TokenInput, params: Admin.Params.UsergroupsRemoveChannels): Promise<{ + ok: boolean + }> + + /** + * Add an Enterprise user to a workspace. + * @see https://api.slack.com/methods/admin.users.assign + */ + adminUsersAssign(token: TokenInput, params: Admin.Params.UsersAssign): Promise<{ + ok: boolean + }> + + /** + * Invite a user to a workspace. + * @see https://api.slack.com/methods/admin.users.invite + */ + adminUsersInvite(token: TokenInput, params: Admin.Params.UsersInvite): Promise<{ + ok: boolean + }> + + /** + * List users on a workspace + * @see https://api.slack.com/methods/admin.users.list + */ + adminUsersList(token: TokenInput, params: Admin.Params.UsersList): Promise<{ + ok: boolean + }> + + /** + * Remove a user from a workspace. + * @see https://api.slack.com/methods/admin.users.remove + */ + adminUsersRemove(token: TokenInput, params: Admin.Params.UsersRemove): Promise<{ + ok: boolean + }> + + /** + * Invalidate a single session for a user by session_id + * @see https://api.slack.com/methods/admin.users.session.invalidate + */ + adminUsersSessionInvalidate(token: TokenInput, params: Admin.Params.UsersSessionInvalidate): Promise<{ + ok: boolean + }> + + /** + * Wipes all valid sessions on all devices for a given user + * @see https://api.slack.com/methods/admin.users.session.reset + */ + adminUsersSessionReset(token: TokenInput, params: Admin.Params.UsersSessionReset): Promise<{ + ok: boolean + }> + + /** + * Set an existing guest, regular user, or owner to be an admin user. + * @see https://api.slack.com/methods/admin.users.setAdmin + */ + adminUsersSetAdmin(token: TokenInput, params: Admin.Params.UsersSetAdmin): Promise<{ + ok: boolean + }> + + /** + * Set an expiration for a guest user + * @see https://api.slack.com/methods/admin.users.setExpiration + */ + adminUsersSetExpiration(token: TokenInput, params: Admin.Params.UsersSetExpiration): Promise<{ + ok: boolean + }> + + /** + * Set an existing guest, regular user, or admin user to be a workspace owner. + * @see https://api.slack.com/methods/admin.users.setOwner + */ + adminUsersSetOwner(token: TokenInput, params: Admin.Params.UsersSetOwner): Promise<{ + ok: boolean + }> + + /** + * Set an existing guest user, admin user, or owner to be a regular user. + * @see https://api.slack.com/methods/admin.users.setRegular + */ + adminUsersSetRegular(token: TokenInput, params: Admin.Params.UsersSetRegular): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/api.ts b/adapters/slack/src/types/api.ts new file mode 100644 index 00000000..ec90be44 --- /dev/null +++ b/adapters/slack/src/types/api.ts @@ -0,0 +1,30 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/api.test': { + GET: { 'apiTest': true }, + }, +}) + +export namespace Api { + export namespace Params { + export interface Test { + error?: string + foo?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Checks API calling code. + * @see https://api.slack.com/methods/api.test + */ + apiTest(token: TokenInput, params: Api.Params.Test): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/apps.ts b/adapters/slack/src/types/apps.ts new file mode 100644 index 00000000..6b57b49d --- /dev/null +++ b/adapters/slack/src/types/apps.ts @@ -0,0 +1,175 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/apps.event.authorizations.list': { + GET: { 'appsEventAuthorizationsList': true }, + }, + '/apps.permissions.info': { + GET: { 'appsPermissionsInfo': false }, + }, + '/apps.permissions.request': { + GET: { 'appsPermissionsRequest': false }, + }, + '/apps.permissions.resources.list': { + GET: { 'appsPermissionsResourcesList': false }, + }, + '/apps.permissions.scopes.list': { + GET: { 'appsPermissionsScopesList': false }, + }, + '/apps.permissions.users.list': { + GET: { 'appsPermissionsUsersList': false }, + }, + '/apps.permissions.users.request': { + GET: { 'appsPermissionsUsersRequest': false }, + }, + '/apps.uninstall': { + GET: { 'appsUninstall': false }, + }, +}) + +export namespace Apps { + export namespace Params { + export interface EventAuthorizationsList { + event_context: string + cursor?: string + limit?: number + } + export interface PermissionsInfo { + } + export interface PermissionsRequest { + scopes: string + trigger_id: string + } + export interface PermissionsResourcesList { + cursor?: string + limit?: number + } + export interface PermissionsScopesList { + } + export interface PermissionsUsersList { + cursor?: string + limit?: number + } + export interface PermissionsUsersRequest { + scopes: string + trigger_id: string + user: string + } + export interface Uninstall { + client_id?: string + client_secret?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Get a list of authorizations for the given event context. Each authorization represents an app installation that the event is visible to. + * @see https://api.slack.com/methods/apps.event.authorizations.list + */ + appsEventAuthorizationsList(token: TokenInput, params: Apps.Params.EventAuthorizationsList): Promise<{ + ok: boolean + }> + + /** + * Returns list of permissions this app has on a team. + * @see https://api.slack.com/methods/apps.permissions.info + */ + appsPermissionsInfo(token: TokenInput): Promise<{ + info: { + app_home: { + resources: Definitions.Resources + scopes: Definitions.Scopes + } + channel: { + resources: Definitions.Resources + scopes: Definitions.Scopes + } + group: { + resources: Definitions.Resources + scopes: Definitions.Scopes + } + im: { + resources: Definitions.Resources + scopes: Definitions.Scopes + } + mpim: { + resources: Definitions.Resources + scopes: Definitions.Scopes + } + team: { + resources: Definitions.Resources + scopes: Definitions.Scopes + } + } + ok: boolean + }> + + /** + * Allows an app to request additional scopes + * @see https://api.slack.com/methods/apps.permissions.request + */ + appsPermissionsRequest(token: TokenInput, params: Apps.Params.PermissionsRequest): Promise<{ + ok: boolean + }> + + /** + * Returns list of resource grants this app has on a team. + * @see https://api.slack.com/methods/apps.permissions.resources.list + */ + appsPermissionsResourcesList(token: TokenInput, params: Apps.Params.PermissionsResourcesList): Promise<{ + ok: boolean + resources: { + id: string + type: string + }[] + response_metadata?: { + next_cursor: string + } + }> + + /** + * Returns list of scopes this app has on a team. + * @see https://api.slack.com/methods/apps.permissions.scopes.list + */ + appsPermissionsScopesList(token: TokenInput): Promise<{ + ok: boolean + scopes: { + app_home: Definitions.Scopes + channel: Definitions.Scopes + group: Definitions.Scopes + im: Definitions.Scopes + mpim: Definitions.Scopes + team: Definitions.Scopes + user: Definitions.Scopes + } + }> + + /** + * Returns list of user grants and corresponding scopes this app has on a team. + * @see https://api.slack.com/methods/apps.permissions.users.list + */ + appsPermissionsUsersList(token: TokenInput, params: Apps.Params.PermissionsUsersList): Promise<{ + ok: boolean + }> + + /** + * Enables an app to trigger a permissions modal to grant an app access to a user access scope. + * @see https://api.slack.com/methods/apps.permissions.users.request + */ + appsPermissionsUsersRequest(token: TokenInput, params: Apps.Params.PermissionsUsersRequest): Promise<{ + ok: boolean + }> + + /** + * Uninstalls your app from a workspace. + * @see https://api.slack.com/methods/apps.uninstall + */ + appsUninstall(token: TokenInput, params: Apps.Params.Uninstall): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/auth.ts b/adapters/slack/src/types/auth.ts new file mode 100644 index 00000000..f651725c --- /dev/null +++ b/adapters/slack/src/types/auth.ts @@ -0,0 +1,50 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/auth.revoke': { + GET: { 'authRevoke': false }, + }, + '/auth.test': { + GET: { 'authTest': true }, + }, +}) + +export namespace Auth { + export namespace Params { + export interface Revoke { + test?: boolean + } + export interface Test { + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Revokes a token. + * @see https://api.slack.com/methods/auth.revoke + */ + authRevoke(token: TokenInput, params: Auth.Params.Revoke): Promise<{ + ok: boolean + revoked: boolean + }> + + /** + * Checks authentication & identity. + * @see https://api.slack.com/methods/auth.test + */ + authTest(token: TokenInput): Promise<{ + bot_id?: string + is_enterprise_install?: boolean + ok: boolean + team: string + team_id: string + url: string + user: string + user_id: string + }> + + } +} diff --git a/adapters/slack/src/types/bots.ts b/adapters/slack/src/types/bots.ts new file mode 100644 index 00000000..fc3a3c4f --- /dev/null +++ b/adapters/slack/src/types/bots.ts @@ -0,0 +1,42 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/bots.info': { + GET: { 'botsInfo': false }, + }, +}) + +export namespace Bots { + export namespace Params { + export interface Info { + bot?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Gets information about a bot user. + * @see https://api.slack.com/methods/bots.info + */ + botsInfo(token: TokenInput, params: Bots.Params.Info): Promise<{ + bot: { + app_id: string + deleted: boolean + icons: { + image_36: string + image_48: string + image_72: string + } + id: string + name: string + updated: number + user_id: string + } + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/calls.ts b/adapters/slack/src/types/calls.ts new file mode 100644 index 00000000..e9a0316d --- /dev/null +++ b/adapters/slack/src/types/calls.ts @@ -0,0 +1,112 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/calls.add': { + POST: { 'callsAdd': true }, + }, + '/calls.end': { + POST: { 'callsEnd': true }, + }, + '/calls.info': { + GET: { 'callsInfo': true }, + }, + '/calls.participants.add': { + POST: { 'callsParticipantsAdd': true }, + }, + '/calls.participants.remove': { + POST: { 'callsParticipantsRemove': true }, + }, + '/calls.update': { + POST: { 'callsUpdate': true }, + }, +}) + +export namespace Calls { + export namespace Params { + export interface Add { + external_unique_id: string + external_display_id?: string + join_url: string + desktop_app_join_url?: string + date_start?: number + title?: string + created_by?: string + users?: string + } + export interface End { + id: string + duration?: number + } + export interface Info { + id: string + } + export interface ParticipantsAdd { + id: string + users: string + } + export interface ParticipantsRemove { + id: string + users: string + } + export interface Update { + id: string + title?: string + join_url?: string + desktop_app_join_url?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Registers a new Call. + * @see https://api.slack.com/methods/calls.add + */ + callsAdd(token: TokenInput, params: Calls.Params.Add): Promise<{ + ok: boolean + }> + + /** + * Ends a Call. + * @see https://api.slack.com/methods/calls.end + */ + callsEnd(token: TokenInput, params: Calls.Params.End): Promise<{ + ok: boolean + }> + + /** + * Returns information about a Call. + * @see https://api.slack.com/methods/calls.info + */ + callsInfo(token: TokenInput, params: Calls.Params.Info): Promise<{ + ok: boolean + }> + + /** + * Registers new participants added to a Call. + * @see https://api.slack.com/methods/calls.participants.add + */ + callsParticipantsAdd(token: TokenInput, params: Calls.Params.ParticipantsAdd): Promise<{ + ok: boolean + }> + + /** + * Registers participants removed from a Call. + * @see https://api.slack.com/methods/calls.participants.remove + */ + callsParticipantsRemove(token: TokenInput, params: Calls.Params.ParticipantsRemove): Promise<{ + ok: boolean + }> + + /** + * Updates information about a Call. + * @see https://api.slack.com/methods/calls.update + */ + callsUpdate(token: TokenInput, params: Calls.Params.Update): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/chat.ts b/adapters/slack/src/types/chat.ts new file mode 100644 index 00000000..efe486a9 --- /dev/null +++ b/adapters/slack/src/types/chat.ts @@ -0,0 +1,255 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/chat.delete': { + POST: { 'chatDelete': true }, + }, + '/chat.deleteScheduledMessage': { + POST: { 'chatDeleteScheduledMessage': true }, + }, + '/chat.getPermalink': { + GET: { 'chatGetPermalink': false }, + }, + '/chat.meMessage': { + POST: { 'chatMeMessage': true }, + }, + '/chat.postEphemeral': { + POST: { 'chatPostEphemeral': true }, + }, + '/chat.postMessage': { + POST: { 'chatPostMessage': true }, + }, + '/chat.scheduleMessage': { + POST: { 'chatScheduleMessage': true }, + }, + '/chat.scheduledMessages.list': { + GET: { 'chatScheduledMessagesList': true }, + }, + '/chat.unfurl': { + POST: { 'chatUnfurl': true }, + }, + '/chat.update': { + POST: { 'chatUpdate': true }, + }, +}) + +export namespace Chat { + export namespace Params { + export interface Delete { + ts?: number + channel?: string + as_user?: boolean + } + export interface DeleteScheduledMessage { + as_user?: boolean + channel: string + scheduled_message_id: string + } + export interface GetPermalink { + channel: string + message_ts: string + } + export interface MeMessage { + channel?: string + text?: string + } + export interface PostEphemeral { + as_user?: boolean + attachments?: string + blocks?: string + channel: string + icon_emoji?: string + icon_url?: string + link_names?: boolean + parse?: string + text?: string + thread_ts?: string + user: string + username?: string + } + export interface PostMessage { + as_user?: string + attachments?: string + blocks?: string + channel: string + icon_emoji?: string + icon_url?: string + link_names?: boolean + mrkdwn?: boolean + parse?: string + reply_broadcast?: boolean + text?: string + thread_ts?: string + unfurl_links?: boolean + unfurl_media?: boolean + username?: string + } + export interface ScheduleMessage { + channel?: string + text?: string + post_at?: string + parse?: string + as_user?: boolean + link_names?: boolean + attachments?: string + blocks?: string + unfurl_links?: boolean + unfurl_media?: boolean + thread_ts?: number + reply_broadcast?: boolean + } + export interface ScheduledMessagesList { + channel?: string + latest?: number + oldest?: number + limit?: number + cursor?: string + } + export interface Unfurl { + channel: string + ts: string + unfurls?: string + user_auth_message?: string + user_auth_required?: boolean + user_auth_url?: string + } + export interface Update { + as_user?: string + attachments?: string + blocks?: string + channel: string + link_names?: string + parse?: string + text?: string + ts: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Deletes a message. + * @see https://api.slack.com/methods/chat.delete + */ + chatDelete(token: TokenInput, params: Chat.Params.Delete): Promise<{ + channel: string + ok: boolean + ts: string + }> + + /** + * Deletes a pending scheduled message from the queue. + * @see https://api.slack.com/methods/chat.deleteScheduledMessage + */ + chatDeleteScheduledMessage(token: TokenInput, params: Chat.Params.DeleteScheduledMessage): Promise<{ + ok: boolean + }> + + /** + * Retrieve a permalink URL for a specific extant message + * @see https://api.slack.com/methods/chat.getPermalink + */ + chatGetPermalink(token: TokenInput, params: Chat.Params.GetPermalink): Promise<{ + channel: string + ok: boolean + permalink: string + }> + + /** + * Share a me message into a channel. + * @see https://api.slack.com/methods/chat.meMessage + */ + chatMeMessage(token: TokenInput, params: Chat.Params.MeMessage): Promise<{ + channel?: string + ok: boolean + ts?: string + }> + + /** + * Sends an ephemeral message to a user in a channel. + * @see https://api.slack.com/methods/chat.postEphemeral + */ + chatPostEphemeral(token: TokenInput, params: Chat.Params.PostEphemeral): Promise<{ + message_ts: string + ok: boolean + }> + + /** + * Sends a message to a channel. + * @see https://api.slack.com/methods/chat.postMessage + */ + chatPostMessage(token: TokenInput, params: Chat.Params.PostMessage): Promise<{ + channel: string + message: Definitions.Message + ok: boolean + ts: string + }> + + /** + * Schedules a message to be sent to a channel. + * @see https://api.slack.com/methods/chat.scheduleMessage + */ + chatScheduleMessage(token: TokenInput, params: Chat.Params.ScheduleMessage): Promise<{ + channel: string + message: { + bot_id: string + bot_profile: Definitions.BotProfile + team: string + text: string + type: string + user: string + username: string + } + ok: boolean + post_at: number + scheduled_message_id: string + }> + + /** + * Returns a list of scheduled messages. + * @see https://api.slack.com/methods/chat.scheduledMessages.list + */ + chatScheduledMessagesList(token: TokenInput, params: Chat.Params.ScheduledMessagesList): Promise<{ + ok: boolean + response_metadata: { + next_cursor: string + } + scheduled_messages: { + channel_id: string + date_created: number + id: string + post_at: number + text: string + }[] + }> + + /** + * Provide custom unfurl behavior for user-posted URLs + * @see https://api.slack.com/methods/chat.unfurl + */ + chatUnfurl(token: TokenInput, params: Chat.Params.Unfurl): Promise<{ + ok: boolean + }> + + /** + * Updates a message. + * @see https://api.slack.com/methods/chat.update + */ + chatUpdate(token: TokenInput, params: Chat.Params.Update): Promise<{ + channel: string + message: { + attachments: { + }[] + blocks: { + } + text: string + } + ok: boolean + text: string + ts: string + }> + + } +} diff --git a/adapters/slack/src/types/conversations.ts b/adapters/slack/src/types/conversations.ts new file mode 100644 index 00000000..52b7b09b --- /dev/null +++ b/adapters/slack/src/types/conversations.ts @@ -0,0 +1,343 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/conversations.archive': { + POST: { 'conversationsArchive': true }, + }, + '/conversations.close': { + POST: { 'conversationsClose': true }, + }, + '/conversations.create': { + POST: { 'conversationsCreate': true }, + }, + '/conversations.history': { + GET: { 'conversationsHistory': true }, + }, + '/conversations.info': { + GET: { 'conversationsInfo': false }, + }, + '/conversations.invite': { + POST: { 'conversationsInvite': true }, + }, + '/conversations.join': { + POST: { 'conversationsJoin': true }, + }, + '/conversations.kick': { + POST: { 'conversationsKick': true }, + }, + '/conversations.leave': { + POST: { 'conversationsLeave': true }, + }, + '/conversations.list': { + GET: { 'conversationsList': false }, + }, + '/conversations.mark': { + POST: { 'conversationsMark': true }, + }, + '/conversations.members': { + GET: { 'conversationsMembers': false }, + }, + '/conversations.open': { + POST: { 'conversationsOpen': true }, + }, + '/conversations.rename': { + POST: { 'conversationsRename': true }, + }, + '/conversations.replies': { + GET: { 'conversationsReplies': false }, + }, + '/conversations.setPurpose': { + POST: { 'conversationsSetPurpose': true }, + }, + '/conversations.setTopic': { + POST: { 'conversationsSetTopic': true }, + }, + '/conversations.unarchive': { + POST: { 'conversationsUnarchive': true }, + }, +}) + +export namespace Conversations { + export namespace Params { + export interface Archive { + channel?: string + } + export interface Close { + channel?: string + } + export interface Create { + name?: string + is_private?: boolean + } + export interface History { + channel?: string + latest?: number + oldest?: number + inclusive?: boolean + limit?: number + cursor?: string + } + export interface Info { + channel?: string + include_locale?: boolean + include_num_members?: boolean + } + export interface Invite { + channel?: string + users?: string + } + export interface Join { + channel?: string + } + export interface Kick { + channel?: string + user?: string + } + export interface Leave { + channel?: string + } + export interface List { + exclude_archived?: boolean + types?: string + limit?: number + cursor?: string + } + export interface Mark { + channel?: string + ts?: number + } + export interface Members { + channel?: string + limit?: number + cursor?: string + } + export interface Open { + channel?: string + users?: string + return_im?: boolean + } + export interface Rename { + channel?: string + name?: string + } + export interface Replies { + channel?: string + ts?: number + latest?: number + oldest?: number + inclusive?: boolean + limit?: number + cursor?: string + } + export interface SetPurpose { + channel?: string + purpose?: string + } + export interface SetTopic { + channel?: string + topic?: string + } + export interface Unarchive { + channel?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Archives a conversation. + * @see https://api.slack.com/methods/conversations.archive + */ + conversationsArchive(token: TokenInput, params: Conversations.Params.Archive): Promise<{ + ok: boolean + }> + + /** + * Closes a direct message or multi-person direct message. + * @see https://api.slack.com/methods/conversations.close + */ + conversationsClose(token: TokenInput, params: Conversations.Params.Close): Promise<{ + already_closed?: boolean + no_op?: boolean + ok: boolean + }> + + /** + * Initiates a public or private channel-based conversation + * @see https://api.slack.com/methods/conversations.create + */ + conversationsCreate(token: TokenInput, params: Conversations.Params.Create): Promise<{ + channel: Definitions.Conversation + ok: boolean + }> + + /** + * Fetches a conversation's history of messages and events. + * @see https://api.slack.com/methods/conversations.history + */ + conversationsHistory(token: TokenInput, params: Conversations.Params.History): Promise<{ + channel_actions_count: number + channel_actions_ts: number + has_more: boolean + messages: Definitions.Message[] + ok: boolean + pin_count: number + }> + + /** + * Retrieve information about a conversation. + * @see https://api.slack.com/methods/conversations.info + */ + conversationsInfo(token: TokenInput, params: Conversations.Params.Info): Promise<{ + channel: Definitions.Conversation + ok: boolean + }> + + /** + * Invites users to a channel. + * @see https://api.slack.com/methods/conversations.invite + */ + conversationsInvite(token: TokenInput, params: Conversations.Params.Invite): Promise<{ + channel: Definitions.Conversation + ok: boolean + }> + + /** + * Joins an existing conversation. + * @see https://api.slack.com/methods/conversations.join + */ + conversationsJoin(token: TokenInput, params: Conversations.Params.Join): Promise<{ + channel: Definitions.Conversation + ok: boolean + response_metadata?: { + warnings: string[] + } + warning?: string + }> + + /** + * Removes a user from a conversation. + * @see https://api.slack.com/methods/conversations.kick + */ + conversationsKick(token: TokenInput, params: Conversations.Params.Kick): Promise<{ + ok: boolean + }> + + /** + * Leaves a conversation. + * @see https://api.slack.com/methods/conversations.leave + */ + conversationsLeave(token: TokenInput, params: Conversations.Params.Leave): Promise<{ + not_in_channel?: boolean + ok: boolean + }> + + /** + * Lists all channels in a Slack team. + * @see https://api.slack.com/methods/conversations.list + */ + conversationsList(token: TokenInput, params: Conversations.Params.List): Promise<{ + channels: Definitions.Conversation[] + ok: boolean + response_metadata?: { + next_cursor: string + } + }> + + /** + * Sets the read cursor in a channel. + * @see https://api.slack.com/methods/conversations.mark + */ + conversationsMark(token: TokenInput, params: Conversations.Params.Mark): Promise<{ + ok: boolean + }> + + /** + * Retrieve members of a conversation. + * @see https://api.slack.com/methods/conversations.members + */ + conversationsMembers(token: TokenInput, params: Conversations.Params.Members): Promise<{ + members: string[] + ok: boolean + response_metadata: { + next_cursor: string + } + }> + + /** + * Opens or resumes a direct message or multi-person direct message. + * @see https://api.slack.com/methods/conversations.open + */ + conversationsOpen(token: TokenInput, params: Conversations.Params.Open): Promise<{ + already_open?: boolean + channel: Definitions.Conversation + no_op?: boolean + ok: boolean + }> + + /** + * Renames a conversation. + * @see https://api.slack.com/methods/conversations.rename + */ + conversationsRename(token: TokenInput, params: Conversations.Params.Rename): Promise<{ + channel: Definitions.Conversation + ok: boolean + }> + + /** + * Retrieve a thread of messages posted to a conversation + * @see https://api.slack.com/methods/conversations.replies + */ + conversationsReplies(token: TokenInput, params: Conversations.Params.Replies): Promise<{ + has_more?: boolean + messages: { + last_read: string + latest_reply: string + reply_count: number + reply_users: string[] + reply_users_count: number + source_team: string + subscribed: boolean + team: string + text: string + thread_ts: string + ts: string + type: string + unread_count: number + user: string + user_profile: Definitions.UserProfileShort + user_team: string + }[] + ok: boolean + }> + + /** + * Sets the purpose for a conversation. + * @see https://api.slack.com/methods/conversations.setPurpose + */ + conversationsSetPurpose(token: TokenInput, params: Conversations.Params.SetPurpose): Promise<{ + channel: Definitions.Conversation + ok: boolean + }> + + /** + * Sets the topic for a conversation. + * @see https://api.slack.com/methods/conversations.setTopic + */ + conversationsSetTopic(token: TokenInput, params: Conversations.Params.SetTopic): Promise<{ + channel: Definitions.Conversation + ok: boolean + }> + + /** + * Reverses conversation archival. + * @see https://api.slack.com/methods/conversations.unarchive + */ + conversationsUnarchive(token: TokenInput, params: Conversations.Params.Unarchive): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/definition.ts b/adapters/slack/src/types/definition.ts new file mode 100644 index 00000000..113b879b --- /dev/null +++ b/adapters/slack/src/types/definition.ts @@ -0,0 +1,530 @@ +export namespace Definitions { + export type BotProfile = { + app_id: string + deleted: boolean + icons: { + image_36: string + image_48: string + image_72: string + } + id: string + name: string + team_id: string + updated: number + } + + export type Channel = { + accepted_user: string + created: number + creator: string + id: string + is_archived: boolean + is_channel: boolean + is_frozen: boolean + is_general: boolean + is_member: boolean + is_moved: number + is_mpim: boolean + is_non_threadable: boolean + is_org_shared: boolean + is_pending_ext_shared: boolean + is_private: boolean + is_read_only: boolean + is_shared: boolean + is_thread_only: boolean + last_read: string + latest: Definitions.Message + members: string[] + name: string + name_normalized: string + num_members: number + pending_shared: string[] + previous_names: string[] + priority: unknown + purpose: { + creator: string + last_set: number + value: string + } + topic: { + creator: string + last_set: number + value: string + } + unlinked: number + unread_count: number + unread_count_display: number + } + + export type Comment = { + comment: string + created: number + id: string + is_intro: boolean + is_starred: boolean + num_stars: number + pinned_info: { + } + pinned_to: string[] + reactions: Definitions.Reaction[] + timestamp: number + user: string + } + + export type Comments = unknown[] + + export type Conversation = { + accepted_user: string + connected_team_ids: string[] + conversation_host_id: string + created: number + creator: string + display_counts: { + display_counts: number + guest_counts: number + } + enterprise_id: string + has_pins: boolean + id: string + internal_team_ids: string[] + is_archived: boolean + is_channel: boolean + is_ext_shared: boolean + is_frozen: boolean + is_general: boolean + is_global_shared: boolean + is_group: boolean + is_im: boolean + is_member: boolean + is_moved: number + is_mpim: boolean + is_non_threadable: boolean + is_open: boolean + is_org_default: boolean + is_org_mandatory: boolean + is_org_shared: boolean + is_pending_ext_shared: boolean + is_private: boolean + is_read_only: boolean + is_shared: boolean + is_starred: boolean + is_thread_only: boolean + last_read: string + latest: Definitions.Message + members: string[] + name: string + name_normalized: string + num_members: number + parent_conversation: string + pending_connected_team_ids: string[] + pending_shared: string[] + pin_count: number + previous_names: string[] + priority: unknown + purpose: { + creator: string + last_set: number + value: string + } + shared_team_ids: string[] + shares: { + accepted_user: string + is_active: boolean + team: Definitions.Team + user: string + }[] + timezone_count: number + topic: { + creator: string + last_set: number + value: string + } + unlinked: number + unread_count: number + unread_count_display: number + use_case: string + user: string + version: number + } + + export type EnterpriseUser = { + enterprise_id: string + enterprise_name: string + id: string + is_admin: boolean + is_owner: boolean + teams: string[] + } + + export type ExternalOrgMigrations = { + current: { + date_started: number + team_id: string + }[] + date_updated: number + } + + export type File = { + channels: string[] + comments_count: number + created: number + date_delete: number + display_as_bot: boolean + editable: boolean + editor: string + external_id: string + external_type: string + external_url: string + filetype: string + groups: string[] + has_rich_preview: boolean + id: string + image_exif_rotation: number + ims: string[] + is_external: boolean + is_public: boolean + is_starred: boolean + is_tombstoned: boolean + last_editor: string + mimetype: string + mode: string + name: string + non_owner_editable: boolean + num_stars: number + original_h: number + original_w: number + permalink: string + permalink_public: string + pinned_info: { + } + pinned_to: string[] + pretty_type: string + preview: string + public_url_shared: boolean + reactions: Definitions.Reaction[] + shares: { + private: unknown + public: unknown + } + size: number + source_team: string + state: string + thumb_1024: string + thumb_1024_h: number + thumb_1024_w: number + thumb_160: string + thumb_360: string + thumb_360_h: number + thumb_360_w: number + thumb_480: string + thumb_480_h: number + thumb_480_w: number + thumb_64: string + thumb_720: string + thumb_720_h: number + thumb_720_w: number + thumb_80: string + thumb_800: string + thumb_800_h: number + thumb_800_w: number + thumb_960: string + thumb_960_h: number + thumb_960_w: number + thumb_tiny: string + timestamp: number + title: string + updated: number + url_private: string + url_private_download: string + user: string + user_team: string + username: string + } + + export type Icon = { + image_102: string + image_132: string + image_230: string + image_34: string + image_44: string + image_68: string + image_88: string + image_default: boolean + } + + export type Message = { + attachments: { + fallback: string + id: number + image_bytes: number + image_height: number + image_url: string + image_width: number + }[] + blocks: { + type: string + }[] + bot_id: string + bot_profile: Definitions.BotProfile + client_msg_id: string + comment: Definitions.Comment + display_as_bot: boolean + file: Definitions.File + files: Definitions.File[] + icons: { + emoji: string + image_64: string + } + inviter: string + is_delayed_message: boolean + is_intro: boolean + is_starred: boolean + last_read: string + latest_reply: string + name: string + old_name: string + parent_user_id: string + permalink: string + pinned_to: string[] + purpose: string + reactions: Definitions.Reaction[] + reply_count: number + reply_users: string[] + reply_users_count: number + source_team: string + subscribed: boolean + subtype: string + team: string + text: string + thread_ts: string + topic: string + ts: string + type: string + unread_count: number + upload: boolean + user: string + user_profile: Definitions.UserProfileShort + user_team: string + username: string + } + + export type Paging = { + count: number + page: number + pages: number + per_page: number + spill: number + total: number + } + + export type PrimaryOwner = { + email: string + id: string + } + + export type Reaction = { + count: number + name: string + users: string[] + } + + export type Reminder = { + complete_ts: number + creator: string + id: string + recurring: boolean + text: string + time: number + user: string + } + + export type Resources = { + excluded_ids: string[] + ids: string[] + wildcard: boolean + } + + export type ResponseMetadata = { + next_cursor: string + } + + export type Scopes = string[] + + export type Subteam = { + auto_provision: boolean + auto_type: unknown + channel_count: number + created_by: string + date_create: number + date_delete: number + date_update: number + deleted_by: unknown + description: string + enterprise_subteam_id: string + handle: string + id: string + is_external: boolean + is_subteam: boolean + is_usergroup: boolean + name: string + prefs: { + channels: string[] + groups: string[] + } + team_id: string + updated_by: string + user_count: number + users: string[] + } + + export type Team = { + archived: boolean + avatar_base_url: string + created: number + date_create: number + deleted: boolean + description: unknown + discoverable: unknown + domain: string + email_domain: string + enterprise_id: string + enterprise_name: string + external_org_migrations: Definitions.ExternalOrgMigrations + has_compliance_export: boolean + icon: Definitions.Icon + id: string + is_assigned: boolean + is_enterprise: number + is_over_storage_limit: boolean + limit_ts: number + locale: string + messages_count: number + msg_edit_window_mins: number + name: string + over_integrations_limit: boolean + over_storage_limit: boolean + pay_prod_cur: string + plan: string + primary_owner: Definitions.PrimaryOwner + sso_provider: { + label: string + name: string + type: string + } + } + + export type TeamProfileField = { + field_name: unknown + hint: string + id: string + is_hidden: boolean + label: string + options: unknown + ordering: unknown + possible_values: unknown + type: string + } + + export type TeamProfileFieldOption = { + is_custom: unknown + is_multiple_entry: unknown + is_protected: unknown + is_scim: unknown + } + + export type User = { + color: string + deleted: boolean + enterprise_user: Definitions.EnterpriseUser + has_2fa: boolean + id: string + is_admin: boolean + is_app_user: boolean + is_bot: boolean + is_external: boolean + is_forgotten: boolean + is_invited_user: boolean + is_owner: boolean + is_primary_owner: boolean + is_restricted: boolean + is_stranger: boolean + is_ultra_restricted: boolean + locale: string + name: string + presence: string + profile: Definitions.UserProfile + real_name: string + team: string + team_id: string + team_profile: { + fields: Definitions.TeamProfileField[] + } + two_factor_type: string + tz: unknown + tz_label: string + tz_offset: unknown + updated: unknown + } + + export type UserProfile = { + always_active: boolean + api_app_id: string + avatar_hash: string + bot_id: string + display_name: string + display_name_normalized: string + email: unknown + fields: unknown + first_name: unknown + guest_expiration_ts: unknown + guest_invited_by: unknown + image_1024: unknown + image_192: unknown + image_24: unknown + image_32: unknown + image_48: unknown + image_512: unknown + image_72: unknown + image_original: unknown + is_app_user: boolean + is_custom_image: boolean + is_restricted: unknown + is_ultra_restricted: unknown + last_avatar_image_hash: string + last_name: unknown + memberships_count: number + name: unknown + phone: string + pronouns: string + real_name: string + real_name_normalized: string + skype: string + status_default_emoji: string + status_default_text: string + status_default_text_canonical: unknown + status_emoji: string + status_expiration: number + status_text: string + status_text_canonical: unknown + team: string + title: string + updated: number + user_id: string + username: unknown + } + + export type UserProfileShort = { + avatar_hash: string + display_name: string + display_name_normalized: string + first_name: unknown + image_72: string + is_restricted: boolean + is_ultra_restricted: boolean + name: string + real_name: string + real_name_normalized: string + team: string + } + +} diff --git a/adapters/slack/src/types/dialog.ts b/adapters/slack/src/types/dialog.ts new file mode 100644 index 00000000..699da29e --- /dev/null +++ b/adapters/slack/src/types/dialog.ts @@ -0,0 +1,30 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/dialog.open': { + GET: { 'dialogOpen': true }, + }, +}) + +export namespace Dialog { + export namespace Params { + export interface Open { + dialog: string + trigger_id: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Open a dialog with a user + * @see https://api.slack.com/methods/dialog.open + */ + dialogOpen(token: TokenInput, params: Dialog.Params.Open): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/dnd.ts b/adapters/slack/src/types/dnd.ts new file mode 100644 index 00000000..aa9823b0 --- /dev/null +++ b/adapters/slack/src/types/dnd.ts @@ -0,0 +1,96 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/dnd.endDnd': { + POST: { 'dndEndDnd': true }, + }, + '/dnd.endSnooze': { + POST: { 'dndEndSnooze': true }, + }, + '/dnd.info': { + GET: { 'dndInfo': false }, + }, + '/dnd.setSnooze': { + POST: { 'dndSetSnooze': false }, + }, + '/dnd.teamInfo': { + GET: { 'dndTeamInfo': false }, + }, +}) + +export namespace Dnd { + export namespace Params { + export interface EndDnd { + } + export interface EndSnooze { + } + export interface Info { + user?: string + } + export interface SetSnooze { + num_minutes: string + } + export interface TeamInfo { + users?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Ends the current user's Do Not Disturb session immediately. + * @see https://api.slack.com/methods/dnd.endDnd + */ + dndEndDnd(token: TokenInput): Promise<{ + ok: boolean + }> + + /** + * Ends the current user's snooze mode immediately. + * @see https://api.slack.com/methods/dnd.endSnooze + */ + dndEndSnooze(token: TokenInput): Promise<{ + dnd_enabled: boolean + next_dnd_end_ts: number + next_dnd_start_ts: number + ok: boolean + snooze_enabled: boolean + }> + + /** + * Retrieves a user's current Do Not Disturb status. + * @see https://api.slack.com/methods/dnd.info + */ + dndInfo(token: TokenInput, params: Dnd.Params.Info): Promise<{ + dnd_enabled: boolean + next_dnd_end_ts: number + next_dnd_start_ts: number + ok: boolean + snooze_enabled?: boolean + snooze_endtime?: number + snooze_remaining?: number + }> + + /** + * Turns on Do Not Disturb mode for the current user, or changes its duration. + * @see https://api.slack.com/methods/dnd.setSnooze + */ + dndSetSnooze(token: TokenInput, params: Dnd.Params.SetSnooze): Promise<{ + ok: boolean + snooze_enabled: boolean + snooze_endtime: number + snooze_remaining: number + }> + + /** + * Retrieves the Do Not Disturb status for up to 50 users on a team. + * @see https://api.slack.com/methods/dnd.teamInfo + */ + dndTeamInfo(token: TokenInput, params: Dnd.Params.TeamInfo): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/emoji.ts b/adapters/slack/src/types/emoji.ts new file mode 100644 index 00000000..97368cf7 --- /dev/null +++ b/adapters/slack/src/types/emoji.ts @@ -0,0 +1,28 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/emoji.list': { + GET: { 'emojiList': false }, + }, +}) + +export namespace Emoji { + export namespace Params { + export interface List { + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Lists custom emoji for a team. + * @see https://api.slack.com/methods/emoji.list + */ + emojiList(token: TokenInput): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/files.ts b/adapters/slack/src/types/files.ts new file mode 100644 index 00000000..20927aed --- /dev/null +++ b/adapters/slack/src/types/files.ts @@ -0,0 +1,246 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/files.comments.delete': { + POST: { 'filesCommentsDelete': true }, + }, + '/files.delete': { + POST: { 'filesDelete': true }, + }, + '/files.info': { + GET: { 'filesInfo': false }, + }, + '/files.list': { + GET: { 'filesList': false }, + }, + '/files.remote.add': { + POST: { 'filesRemoteAdd': false }, + }, + '/files.remote.info': { + GET: { 'filesRemoteInfo': false }, + }, + '/files.remote.list': { + GET: { 'filesRemoteList': false }, + }, + '/files.remote.remove': { + POST: { 'filesRemoteRemove': false }, + }, + '/files.remote.share': { + GET: { 'filesRemoteShare': false }, + }, + '/files.remote.update': { + POST: { 'filesRemoteUpdate': false }, + }, + '/files.revokePublicURL': { + POST: { 'filesRevokePublicURL': true }, + }, + '/files.sharedPublicURL': { + POST: { 'filesSharedPublicURL': true }, + }, + '/files.upload': { + POST: { 'filesUpload': false }, + }, +}) + +export namespace Files { + export namespace Params { + export interface CommentsDelete { + file?: string + id?: string + } + export interface Delete { + file?: string + } + export interface Info { + file?: string + count?: string + page?: string + limit?: number + cursor?: string + } + export interface List { + user?: string + channel?: string + ts_from?: number + ts_to?: number + types?: string + count?: string + page?: string + show_files_hidden_by_limit?: boolean + } + export interface RemoteAdd { + external_id?: string + title?: string + filetype?: string + external_url?: string + preview_image?: string + indexable_file_contents?: string + } + export interface RemoteInfo { + file?: string + external_id?: string + } + export interface RemoteList { + channel?: string + ts_from?: number + ts_to?: number + limit?: number + cursor?: string + } + export interface RemoteRemove { + file?: string + external_id?: string + } + export interface RemoteShare { + file?: string + external_id?: string + channels?: string + } + export interface RemoteUpdate { + file?: string + external_id?: string + title?: string + filetype?: string + external_url?: string + preview_image?: string + indexable_file_contents?: string + } + export interface RevokePublicURL { + file?: string + } + export interface SharedPublicURL { + file?: string + } + export interface Upload { + file?: string + content?: string + filetype?: string + filename?: string + title?: string + initial_comment?: string + channels?: string + thread_ts?: number + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Deletes an existing comment on a file. + * @see https://api.slack.com/methods/files.comments.delete + */ + filesCommentsDelete(token: TokenInput, params: Files.Params.CommentsDelete): Promise<{ + ok: boolean + }> + + /** + * Deletes a file. + * @see https://api.slack.com/methods/files.delete + */ + filesDelete(token: TokenInput, params: Files.Params.Delete): Promise<{ + ok: boolean + }> + + /** + * Gets information about a file. + * @see https://api.slack.com/methods/files.info + */ + filesInfo(token: TokenInput, params: Files.Params.Info): Promise<{ + comments: Definitions.Comments + content_html?: unknown + editor?: string + file: Definitions.File + ok: boolean + paging?: Definitions.Paging + response_metadata?: Definitions.ResponseMetadata + }> + + /** + * List for a team, in a channel, or from a user with applied filters. + * @see https://api.slack.com/methods/files.list + */ + filesList(token: TokenInput, params: Files.Params.List): Promise<{ + files: Definitions.File[] + ok: boolean + paging: Definitions.Paging + }> + + /** + * Adds a file from a remote service + * @see https://api.slack.com/methods/files.remote.add + */ + filesRemoteAdd(token: TokenInput, params: Files.Params.RemoteAdd): Promise<{ + ok: boolean + }> + + /** + * Retrieve information about a remote file added to Slack + * @see https://api.slack.com/methods/files.remote.info + */ + filesRemoteInfo(token: TokenInput, params: Files.Params.RemoteInfo): Promise<{ + ok: boolean + }> + + /** + * Retrieve information about a remote file added to Slack + * @see https://api.slack.com/methods/files.remote.list + */ + filesRemoteList(token: TokenInput, params: Files.Params.RemoteList): Promise<{ + ok: boolean + }> + + /** + * Remove a remote file. + * @see https://api.slack.com/methods/files.remote.remove + */ + filesRemoteRemove(token: TokenInput, params: Files.Params.RemoteRemove): Promise<{ + ok: boolean + }> + + /** + * Share a remote file into a channel. + * @see https://api.slack.com/methods/files.remote.share + */ + filesRemoteShare(token: TokenInput, params: Files.Params.RemoteShare): Promise<{ + ok: boolean + }> + + /** + * Updates an existing remote file. + * @see https://api.slack.com/methods/files.remote.update + */ + filesRemoteUpdate(token: TokenInput, params: Files.Params.RemoteUpdate): Promise<{ + ok: boolean + }> + + /** + * Revokes public/external sharing access for a file + * @see https://api.slack.com/methods/files.revokePublicURL + */ + filesRevokePublicURL(token: TokenInput, params: Files.Params.RevokePublicURL): Promise<{ + file: Definitions.File + ok: boolean + }> + + /** + * Enables a file for public/external sharing. + * @see https://api.slack.com/methods/files.sharedPublicURL + */ + filesSharedPublicURL(token: TokenInput, params: Files.Params.SharedPublicURL): Promise<{ + file: Definitions.File + ok: boolean + }> + + /** + * Uploads or creates a file. + * @see https://api.slack.com/methods/files.upload + */ + filesUpload(token: TokenInput, params: Files.Params.Upload): Promise<{ + file: Definitions.File + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/index.ts b/adapters/slack/src/types/index.ts index 2f2cbcff..a6a4623b 100644 --- a/adapters/slack/src/types/index.ts +++ b/adapters/slack/src/types/index.ts @@ -54,3 +54,31 @@ export interface SlackTeam { } export * from './events' +export * from './internal' +export * from './definition' + +export * from './admin' +export * from './api' +export * from './apps' +export * from './auth' +export * from './bots' +export * from './calls' +export * from './chat' +export * from './conversations' +export * from './dialog' +export * from './dnd' +export * from './emoji' +export * from './files' +export * from './migration' +export * from './oauth' +export * from './pins' +export * from './reactions' +export * from './reminders' +export * from './rtm' +export * from './search' +export * from './stars' +export * from './team' +export * from './usergroups' +export * from './users' +export * from './views' +export * from './workflows' diff --git a/adapters/slack/src/types/internal.ts b/adapters/slack/src/types/internal.ts new file mode 100644 index 00000000..1171e55b --- /dev/null +++ b/adapters/slack/src/types/internal.ts @@ -0,0 +1,57 @@ +import { Dict, makeArray, Quester } from '@satorijs/satori' +import { SlackBot } from '../bot' + +// https://api.slack.com/web#methods_supporting_json + +type SupportPostJSON = boolean + +export enum Token { + BOT = 0, + APP = 1, +} + +export type TokenInput = string | Token + +// https://api.slack.com/web#basics +export class Internal { + constructor(private bot: SlackBot, private http: Quester) { } + + // route: content-type + static define(routes: Dict>>>) { + for (const path in routes) { + for (const key in routes[path]) { + const method = key as Quester.Method + for (const name of Object.keys(routes[path][method])) { + Internal.prototype[name] = async function (this: Internal, ...args: any[]) { + const config: Quester.AxiosRequestConfig = { + headers: {}, + } + let token = '' + if (typeof args[0] === 'string') { + token = args[0] + } else { + token = args[0] === Token.BOT ? this.bot.config.botToken : this.bot.config.token + } + config.headers.Authorization = `Bearer ${token}` + const supportJson = routes[path][method][name] + if (method === 'GET') { + config.params = args[1] + } else if (supportJson && !(args[1] instanceof FormData)) { + config.headers['content-type'] = 'application/json; charset=utf-8' + config.data = JSON.stringify(args[1]) + } else { + config.headers['content-type'] = 'application/x-www-form-urlencoded' + config.data = args[1] + } + try { + return await this.http(method, path, config) + } catch (error) { + if (!Quester.isAxiosError(error) || !error.response) throw error + throw new Error(`[${error.response.status}] ${JSON.stringify(error.response.data)}`) + } + } + } + } + } + } +} diff --git a/adapters/slack/src/types/migration.ts b/adapters/slack/src/types/migration.ts new file mode 100644 index 00000000..87d13ff7 --- /dev/null +++ b/adapters/slack/src/types/migration.ts @@ -0,0 +1,36 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/migration.exchange': { + GET: { 'migrationExchange': false }, + }, +}) + +export namespace Migration { + export namespace Params { + export interface Exchange { + users: string + team_id?: string + to_old?: boolean + } + } +} + +declare module './internal' { + interface Internal { + + /** + * For Enterprise Grid workspaces, map local user IDs to global user IDs + * @see https://api.slack.com/methods/migration.exchange + */ + migrationExchange(token: TokenInput, params: Migration.Params.Exchange): Promise<{ + enterprise_id: string + invalid_user_ids?: string[] + ok: boolean + team_id: string + user_id_map?: { + } + }> + + } +} diff --git a/adapters/slack/src/types/oauth.ts b/adapters/slack/src/types/oauth.ts new file mode 100644 index 00000000..b693fbb0 --- /dev/null +++ b/adapters/slack/src/types/oauth.ts @@ -0,0 +1,68 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/oauth.access': { + GET: { 'oauthAccess': false }, + }, + '/oauth.token': { + GET: { 'oauthToken': false }, + }, + '/oauth.v2.access': { + GET: { 'oauthV2Access': false }, + }, +}) + +export namespace Oauth { + export namespace Params { + export interface Access { + client_id?: string + client_secret?: string + code?: string + redirect_uri?: string + single_channel?: boolean + } + export interface Token { + client_id?: string + client_secret?: string + code?: string + redirect_uri?: string + single_channel?: boolean + } + export interface V2Access { + client_id?: string + client_secret?: string + code: string + redirect_uri?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Exchanges a temporary OAuth verifier code for an access token. + * @see https://api.slack.com/methods/oauth.access + */ + oauthAccess(token: TokenInput, params: Oauth.Params.Access): Promise<{ + ok: boolean + }> + + /** + * Exchanges a temporary OAuth verifier code for a workspace token. + * @see https://api.slack.com/methods/oauth.token + */ + oauthToken(token: TokenInput, params: Oauth.Params.Token): Promise<{ + ok: boolean + }> + + /** + * Exchanges a temporary OAuth verifier code for an access token. + * @see https://api.slack.com/methods/oauth.v2.access + */ + oauthV2Access(token: TokenInput, params: Oauth.Params.V2Access): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/pins.ts b/adapters/slack/src/types/pins.ts new file mode 100644 index 00000000..d51e8868 --- /dev/null +++ b/adapters/slack/src/types/pins.ts @@ -0,0 +1,57 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/pins.add': { + POST: { 'pinsAdd': true }, + }, + '/pins.list': { + GET: { 'pinsList': false }, + }, + '/pins.remove': { + POST: { 'pinsRemove': true }, + }, +}) + +export namespace Pins { + export namespace Params { + export interface Add { + channel: string + timestamp?: string + } + export interface List { + channel: string + } + export interface Remove { + channel: string + timestamp?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Pins an item to a channel. + * @see https://api.slack.com/methods/pins.add + */ + pinsAdd(token: TokenInput, params: Pins.Params.Add): Promise<{ + ok: boolean + }> + + /** + * Lists items pinned to a channel. + * @see https://api.slack.com/methods/pins.list + */ + pinsList(token: TokenInput, params: Pins.Params.List): Promise + + /** + * Un-pins an item from a channel. + * @see https://api.slack.com/methods/pins.remove + */ + pinsRemove(token: TokenInput, params: Pins.Params.Remove): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/reactions.ts b/adapters/slack/src/types/reactions.ts new file mode 100644 index 00000000..f74d3d1d --- /dev/null +++ b/adapters/slack/src/types/reactions.ts @@ -0,0 +1,96 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/reactions.add': { + POST: { 'reactionsAdd': true }, + }, + '/reactions.get': { + GET: { 'reactionsGet': false }, + }, + '/reactions.list': { + GET: { 'reactionsList': false }, + }, + '/reactions.remove': { + POST: { 'reactionsRemove': true }, + }, +}) + +export namespace Reactions { + export namespace Params { + export interface Add { + channel: string + name: string + timestamp: string + } + export interface Get { + channel?: string + file?: string + file_comment?: string + full?: boolean + timestamp?: string + } + export interface List { + user?: string + full?: boolean + count?: number + page?: number + cursor?: string + limit?: number + } + export interface Remove { + name: string + file?: string + file_comment?: string + channel?: string + timestamp?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Adds a reaction to an item. + * @see https://api.slack.com/methods/reactions.add + */ + reactionsAdd(token: TokenInput, params: Reactions.Params.Add): Promise<{ + ok: boolean + }> + + /** + * Gets reactions for an item. + * @see https://api.slack.com/methods/reactions.get + */ + reactionsGet(token: TokenInput, params: Reactions.Params.Get): Promise<{ + channel: string + message: Definitions.Message + ok: boolean + type: string + }> + + /** + * Lists reactions made by a user. + * @see https://api.slack.com/methods/reactions.list + */ + reactionsList(token: TokenInput, params: Reactions.Params.List): Promise<{ + items: { + channel: string + message: Definitions.Message + type: string + }[] + ok: boolean + paging?: Definitions.Paging + response_metadata?: Definitions.ResponseMetadata + }> + + /** + * Removes a reaction from an item. + * @see https://api.slack.com/methods/reactions.remove + */ + reactionsRemove(token: TokenInput, params: Reactions.Params.Remove): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/reminders.ts b/adapters/slack/src/types/reminders.ts new file mode 100644 index 00000000..0e0cae0c --- /dev/null +++ b/adapters/slack/src/types/reminders.ts @@ -0,0 +1,89 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/reminders.add': { + POST: { 'remindersAdd': true }, + }, + '/reminders.complete': { + POST: { 'remindersComplete': true }, + }, + '/reminders.delete': { + POST: { 'remindersDelete': true }, + }, + '/reminders.info': { + GET: { 'remindersInfo': false }, + }, + '/reminders.list': { + GET: { 'remindersList': false }, + }, +}) + +export namespace Reminders { + export namespace Params { + export interface Add { + text: string + time: string + user?: string + } + export interface Complete { + reminder?: string + } + export interface Delete { + reminder?: string + } + export interface Info { + reminder?: string + } + export interface List { + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Creates a reminder. + * @see https://api.slack.com/methods/reminders.add + */ + remindersAdd(token: TokenInput, params: Reminders.Params.Add): Promise<{ + ok: boolean + reminder: Definitions.Reminder + }> + + /** + * Marks a reminder as complete. + * @see https://api.slack.com/methods/reminders.complete + */ + remindersComplete(token: TokenInput, params: Reminders.Params.Complete): Promise<{ + ok: boolean + }> + + /** + * Deletes a reminder. + * @see https://api.slack.com/methods/reminders.delete + */ + remindersDelete(token: TokenInput, params: Reminders.Params.Delete): Promise<{ + ok: boolean + }> + + /** + * Gets information about a reminder. + * @see https://api.slack.com/methods/reminders.info + */ + remindersInfo(token: TokenInput, params: Reminders.Params.Info): Promise<{ + ok: boolean + reminder: Definitions.Reminder + }> + + /** + * Lists all reminders created by or for a given user. + * @see https://api.slack.com/methods/reminders.list + */ + remindersList(token: TokenInput): Promise<{ + ok: boolean + reminders: Definitions.Reminder[] + }> + + } +} diff --git a/adapters/slack/src/types/rtm.ts b/adapters/slack/src/types/rtm.ts new file mode 100644 index 00000000..7e86399d --- /dev/null +++ b/adapters/slack/src/types/rtm.ts @@ -0,0 +1,40 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/rtm.connect': { + GET: { 'rtmConnect': false }, + }, +}) + +export namespace Rtm { + export namespace Params { + export interface Connect { + batch_presence_aware?: boolean + presence_sub?: boolean + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Starts a Real Time Messaging session. + * @see https://api.slack.com/methods/rtm.connect + */ + rtmConnect(token: TokenInput, params: Rtm.Params.Connect): Promise<{ + ok: boolean + self: { + id: string + name: string + } + team: { + domain: string + id: string + name: string + } + url: string + }> + + } +} diff --git a/adapters/slack/src/types/search.ts b/adapters/slack/src/types/search.ts new file mode 100644 index 00000000..6d0848bc --- /dev/null +++ b/adapters/slack/src/types/search.ts @@ -0,0 +1,34 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/search.messages': { + GET: { 'searchMessages': false }, + }, +}) + +export namespace Search { + export namespace Params { + export interface Messages { + count?: number + highlight?: boolean + page?: number + query: string + sort?: string + sort_dir?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Searches for messages matching a query. + * @see https://api.slack.com/methods/search.messages + */ + searchMessages(token: TokenInput, params: Search.Params.Messages): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/stars.ts b/adapters/slack/src/types/stars.ts new file mode 100644 index 00000000..29e4412c --- /dev/null +++ b/adapters/slack/src/types/stars.ts @@ -0,0 +1,73 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/stars.add': { + POST: { 'starsAdd': true }, + }, + '/stars.list': { + GET: { 'starsList': false }, + }, + '/stars.remove': { + POST: { 'starsRemove': true }, + }, +}) + +export namespace Stars { + export namespace Params { + export interface Add { + channel?: string + file?: string + file_comment?: string + timestamp?: string + } + export interface List { + count?: string + page?: string + cursor?: string + limit?: number + } + export interface Remove { + channel?: string + file?: string + file_comment?: string + timestamp?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Adds a star to an item. + * @see https://api.slack.com/methods/stars.add + */ + starsAdd(token: TokenInput, params: Stars.Params.Add): Promise<{ + ok: boolean + }> + + /** + * Lists stars for a user. + * @see https://api.slack.com/methods/stars.list + */ + starsList(token: TokenInput, params: Stars.Params.List): Promise<{ + items: { + channel: string + date_create: number + message: Definitions.Message + type: string + }[] + ok: boolean + paging?: Definitions.Paging + }> + + /** + * Removes a star from an item. + * @see https://api.slack.com/methods/stars.remove + */ + starsRemove(token: TokenInput, params: Stars.Params.Remove): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/team.ts b/adapters/slack/src/types/team.ts new file mode 100644 index 00000000..f304459f --- /dev/null +++ b/adapters/slack/src/types/team.ts @@ -0,0 +1,123 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/team.accessLogs': { + GET: { 'teamAccessLogs': false }, + }, + '/team.billableInfo': { + GET: { 'teamBillableInfo': false }, + }, + '/team.info': { + GET: { 'teamInfo': false }, + }, + '/team.integrationLogs': { + GET: { 'teamIntegrationLogs': false }, + }, + '/team.profile.get': { + GET: { 'teamProfileGet': false }, + }, +}) + +export namespace Team { + export namespace Params { + export interface AccessLogs { + before?: string + count?: string + page?: string + } + export interface BillableInfo { + user?: string + } + export interface Info { + team?: string + } + export interface IntegrationLogs { + app_id?: string + change_type?: string + count?: string + page?: string + service_id?: string + user?: string + } + export interface ProfileGet { + visibility?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Gets the access logs for the current team. + * @see https://api.slack.com/methods/team.accessLogs + */ + teamAccessLogs(token: TokenInput, params: Team.Params.AccessLogs): Promise<{ + logins: { + count: number + country: unknown + date_first: number + date_last: number + ip: unknown + isp: unknown + region: unknown + user_agent: string + user_id: string + username: string + }[] + ok: boolean + paging: Definitions.Paging + }> + + /** + * Gets billable users information for the current team. + * @see https://api.slack.com/methods/team.billableInfo + */ + teamBillableInfo(token: TokenInput, params: Team.Params.BillableInfo): Promise<{ + ok: boolean + }> + + /** + * Gets information about the current team. + * @see https://api.slack.com/methods/team.info + */ + teamInfo(token: TokenInput, params: Team.Params.Info): Promise<{ + ok: boolean + team: Definitions.Team + }> + + /** + * Gets the integration logs for the current team. + * @see https://api.slack.com/methods/team.integrationLogs + */ + teamIntegrationLogs(token: TokenInput, params: Team.Params.IntegrationLogs): Promise<{ + logs: { + admin_app_id: string + app_id: string + app_type: string + change_type: string + channel: string + date: string + scope: string + service_id: string + service_type: string + user_id: string + user_name: string + }[] + ok: boolean + paging: Definitions.Paging + }> + + /** + * Retrieve a team's profile. + * @see https://api.slack.com/methods/team.profile.get + */ + teamProfileGet(token: TokenInput, params: Team.Params.ProfileGet): Promise<{ + ok: boolean + profile: { + fields: Definitions.TeamProfileField[] + } + }> + + } +} diff --git a/adapters/slack/src/types/usergroups.ts b/adapters/slack/src/types/usergroups.ts new file mode 100644 index 00000000..c53dfeca --- /dev/null +++ b/adapters/slack/src/types/usergroups.ts @@ -0,0 +1,136 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/usergroups.create': { + POST: { 'usergroupsCreate': true }, + }, + '/usergroups.disable': { + POST: { 'usergroupsDisable': true }, + }, + '/usergroups.enable': { + POST: { 'usergroupsEnable': true }, + }, + '/usergroups.list': { + GET: { 'usergroupsList': false }, + }, + '/usergroups.update': { + POST: { 'usergroupsUpdate': true }, + }, + '/usergroups.users.list': { + GET: { 'usergroupsUsersList': false }, + }, + '/usergroups.users.update': { + POST: { 'usergroupsUsersUpdate': true }, + }, +}) + +export namespace Usergroups { + export namespace Params { + export interface Create { + channels?: string + description?: string + handle?: string + include_count?: boolean + name: string + } + export interface Disable { + include_count?: boolean + usergroup: string + } + export interface Enable { + include_count?: boolean + usergroup: string + } + export interface List { + include_users?: boolean + include_count?: boolean + include_disabled?: boolean + } + export interface Update { + handle?: string + description?: string + channels?: string + include_count?: boolean + usergroup: string + name?: string + } + export interface UsersList { + include_disabled?: boolean + usergroup: string + } + export interface UsersUpdate { + include_count?: boolean + usergroup: string + users: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Create a User Group + * @see https://api.slack.com/methods/usergroups.create + */ + usergroupsCreate(token: TokenInput, params: Usergroups.Params.Create): Promise<{ + ok: boolean + usergroup: Definitions.Subteam + }> + + /** + * Disable an existing User Group + * @see https://api.slack.com/methods/usergroups.disable + */ + usergroupsDisable(token: TokenInput, params: Usergroups.Params.Disable): Promise<{ + ok: boolean + usergroup: Definitions.Subteam + }> + + /** + * Enable a User Group + * @see https://api.slack.com/methods/usergroups.enable + */ + usergroupsEnable(token: TokenInput, params: Usergroups.Params.Enable): Promise<{ + ok: boolean + usergroup: Definitions.Subteam + }> + + /** + * List all User Groups for a team + * @see https://api.slack.com/methods/usergroups.list + */ + usergroupsList(token: TokenInput, params: Usergroups.Params.List): Promise<{ + ok: boolean + usergroups: Definitions.Subteam[] + }> + + /** + * Update an existing User Group + * @see https://api.slack.com/methods/usergroups.update + */ + usergroupsUpdate(token: TokenInput, params: Usergroups.Params.Update): Promise<{ + ok: boolean + usergroup: Definitions.Subteam + }> + + /** + * List all users in a User Group + * @see https://api.slack.com/methods/usergroups.users.list + */ + usergroupsUsersList(token: TokenInput, params: Usergroups.Params.UsersList): Promise<{ + ok: boolean + users: string[] + }> + + /** + * Update the list of users for a User Group + * @see https://api.slack.com/methods/usergroups.users.update + */ + usergroupsUsersUpdate(token: TokenInput, params: Usergroups.Params.UsersUpdate): Promise<{ + ok: boolean + usergroup: Definitions.Subteam + }> + + } +} diff --git a/adapters/slack/src/types/users.ts b/adapters/slack/src/types/users.ts new file mode 100644 index 00000000..97a8d0d0 --- /dev/null +++ b/adapters/slack/src/types/users.ts @@ -0,0 +1,222 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/users.conversations': { + GET: { 'usersConversations': false }, + }, + '/users.deletePhoto': { + POST: { 'usersDeletePhoto': false }, + }, + '/users.getPresence': { + GET: { 'usersGetPresence': false }, + }, + '/users.identity': { + GET: { 'usersIdentity': false }, + }, + '/users.info': { + GET: { 'usersInfo': false }, + }, + '/users.list': { + GET: { 'usersList': false }, + }, + '/users.lookupByEmail': { + GET: { 'usersLookupByEmail': false }, + }, + '/users.profile.get': { + GET: { 'usersProfileGet': false }, + }, + '/users.profile.set': { + POST: { 'usersProfileSet': true }, + }, + '/users.setActive': { + POST: { 'usersSetActive': true }, + }, + '/users.setPhoto': { + POST: { 'usersSetPhoto': false }, + }, + '/users.setPresence': { + POST: { 'usersSetPresence': true }, + }, +}) + +export namespace Users { + export namespace Params { + export interface Conversations { + user?: string + types?: string + exclude_archived?: boolean + limit?: number + cursor?: string + } + export interface DeletePhoto { + } + export interface GetPresence { + user?: string + } + export interface Identity { + } + export interface Info { + include_locale?: boolean + user?: string + } + export interface List { + limit?: number + cursor?: string + include_locale?: boolean + } + export interface LookupByEmail { + email: string + } + export interface ProfileGet { + include_labels?: boolean + user?: string + } + export interface ProfileSet { + name?: string + profile?: string + user?: string + value?: string + } + export interface SetActive { + } + export interface SetPhoto { + crop_w?: string + crop_x?: string + crop_y?: string + image?: string + } + export interface SetPresence { + presence: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * List conversations the calling user may access. + * @see https://api.slack.com/methods/users.conversations + */ + usersConversations(token: TokenInput, params: Users.Params.Conversations): Promise<{ + channels: Definitions.Conversation[] + ok: boolean + response_metadata?: { + next_cursor: string + } + }> + + /** + * Delete the user profile photo + * @see https://api.slack.com/methods/users.deletePhoto + */ + usersDeletePhoto(token: TokenInput): Promise<{ + ok: boolean + }> + + /** + * Gets user presence information. + * @see https://api.slack.com/methods/users.getPresence + */ + usersGetPresence(token: TokenInput, params: Users.Params.GetPresence): Promise<{ + auto_away?: boolean + connection_count?: number + last_activity?: number + manual_away?: boolean + ok: boolean + online?: boolean + presence: string + }> + + /** + * Get a user's identity. + * @see https://api.slack.com/methods/users.identity + */ + usersIdentity(token: TokenInput): Promise + + /** + * Gets information about a user. + * @see https://api.slack.com/methods/users.info + */ + usersInfo(token: TokenInput, params: Users.Params.Info): Promise<{ + ok: boolean + user: Definitions.User + }> + + /** + * Lists all users in a Slack team. + * @see https://api.slack.com/methods/users.list + */ + usersList(token: TokenInput, params: Users.Params.List): Promise<{ + cache_ts: number + members: Definitions.User[] + ok: boolean + response_metadata?: Definitions.ResponseMetadata + }> + + /** + * Find a user with an email address. + * @see https://api.slack.com/methods/users.lookupByEmail + */ + usersLookupByEmail(token: TokenInput, params: Users.Params.LookupByEmail): Promise<{ + ok: boolean + user: Definitions.User + }> + + /** + * Retrieves a user's profile information. + * @see https://api.slack.com/methods/users.profile.get + */ + usersProfileGet(token: TokenInput, params: Users.Params.ProfileGet): Promise<{ + ok: boolean + profile: Definitions.UserProfile + }> + + /** + * Set the profile information for a user. + * @see https://api.slack.com/methods/users.profile.set + */ + usersProfileSet(token: TokenInput, params: Users.Params.ProfileSet): Promise<{ + email_pending?: string + ok: boolean + profile: Definitions.UserProfile + username: string + }> + + /** + * Marked a user as active. Deprecated and non-functional. + * @see https://api.slack.com/methods/users.setActive + */ + usersSetActive(token: TokenInput): Promise<{ + ok: boolean + }> + + /** + * Set the user profile photo + * @see https://api.slack.com/methods/users.setPhoto + */ + usersSetPhoto(token: TokenInput, params: Users.Params.SetPhoto): Promise<{ + ok: boolean + profile: { + avatar_hash: string + image_1024: string + image_192: string + image_24: string + image_32: string + image_48: string + image_512: string + image_72: string + image_original: string + } + }> + + /** + * Manually sets user presence. + * @see https://api.slack.com/methods/users.setPresence + */ + usersSetPresence(token: TokenInput, params: Users.Params.SetPresence): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/views.ts b/adapters/slack/src/types/views.ts new file mode 100644 index 00000000..b15a22b3 --- /dev/null +++ b/adapters/slack/src/types/views.ts @@ -0,0 +1,78 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/views.open': { + GET: { 'viewsOpen': true }, + }, + '/views.publish': { + GET: { 'viewsPublish': true }, + }, + '/views.push': { + GET: { 'viewsPush': true }, + }, + '/views.update': { + GET: { 'viewsUpdate': true }, + }, +}) + +export namespace Views { + export namespace Params { + export interface Open { + trigger_id: string + view: string + } + export interface Publish { + user_id: string + view: string + hash?: string + } + export interface Push { + trigger_id: string + view: string + } + export interface Update { + view_id?: string + external_id?: string + view?: string + hash?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Open a view for a user. + * @see https://api.slack.com/methods/views.open + */ + viewsOpen(token: TokenInput, params: Views.Params.Open): Promise<{ + ok: boolean + }> + + /** + * Publish a static view for a User. + * @see https://api.slack.com/methods/views.publish + */ + viewsPublish(token: TokenInput, params: Views.Params.Publish): Promise<{ + ok: boolean + }> + + /** + * Push a view onto the stack of a root view. + * @see https://api.slack.com/methods/views.push + */ + viewsPush(token: TokenInput, params: Views.Params.Push): Promise<{ + ok: boolean + }> + + /** + * Update an existing view. + * @see https://api.slack.com/methods/views.update + */ + viewsUpdate(token: TokenInput, params: Views.Params.Update): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/types/workflows.ts b/adapters/slack/src/types/workflows.ts new file mode 100644 index 00000000..b353d389 --- /dev/null +++ b/adapters/slack/src/types/workflows.ts @@ -0,0 +1,63 @@ +import { Internal, TokenInput } from './internal' +import { Definitions } from './definition' +Internal.define({ + '/workflows.stepCompleted': { + GET: { 'workflowsStepCompleted': true }, + }, + '/workflows.stepFailed': { + GET: { 'workflowsStepFailed': true }, + }, + '/workflows.updateStep': { + GET: { 'workflowsUpdateStep': true }, + }, +}) + +export namespace Workflows { + export namespace Params { + export interface StepCompleted { + workflow_step_execute_id: string + outputs?: string + } + export interface StepFailed { + workflow_step_execute_id: string + error: string + } + export interface UpdateStep { + workflow_step_edit_id: string + inputs?: string + outputs?: string + step_name?: string + step_image_url?: string + } + } +} + +declare module './internal' { + interface Internal { + + /** + * Indicate that an app's step in a workflow completed execution. + * @see https://api.slack.com/methods/workflows.stepCompleted + */ + workflowsStepCompleted(token: TokenInput, params: Workflows.Params.StepCompleted): Promise<{ + ok: boolean + }> + + /** + * Indicate that an app's step in a workflow failed to execute. + * @see https://api.slack.com/methods/workflows.stepFailed + */ + workflowsStepFailed(token: TokenInput, params: Workflows.Params.StepFailed): Promise<{ + ok: boolean + }> + + /** + * Update the configuration for a workflow extension step. + * @see https://api.slack.com/methods/workflows.updateStep + */ + workflowsUpdateStep(token: TokenInput, params: Workflows.Params.UpdateStep): Promise<{ + ok: boolean + }> + + } +} diff --git a/adapters/slack/src/utils.ts b/adapters/slack/src/utils.ts index e889c9f6..fc5b1538 100644 --- a/adapters/slack/src/utils.ts +++ b/adapters/slack/src/utils.ts @@ -2,7 +2,7 @@ import { Element, h, Session, Universal } from '@satorijs/satori' import { SlackBot } from './bot' import { BasicSlackEvent, EnvelopedEvent, GenericMessageEvent, MessageChangedEvent, MessageDeletedEvent, MessageEvent, ReactionAddedEvent, ReactionRemovedEvent, RichText, RichTextBlock, SlackEvent, SlackUser } from './types/events' import { KnownBlock } from '@slack/types' -import { File, SlackChannel, SlackTeam } from './types' +import { Definitions, File, SlackChannel, SlackTeam } from './types' import { unescape } from './message' type NewKnownBlock = KnownBlock | RichTextBlock @@ -69,21 +69,19 @@ function adaptMessageBlocks(blocks: NewKnownBlock[]) { return result } -const adaptAuthor = (evt: GenericMessageEvent): Universal.Author => ({ - userId: evt.user || evt.app_id, +const adaptAuthor = (evt: Partial): Universal.Author => ({ + userId: evt.user || evt.bot_id as string, // username: evt.username }) -const adaptBotProfile = (evt: GenericMessageEvent): Universal.Author => ({ +const adaptBotProfile = (evt: Partial): Universal.Author => ({ userId: evt.bot_profile.app_id, username: evt.bot_profile.name, isBot: true, avatar: evt.bot_profile.icons.image_72, }) -export async function adaptMessage(bot: SlackBot, evt: GenericMessageEvent, session: Partial = {}) { - session.isDirect = evt.channel_type === 'im' - session.channelId = evt.channel +export async function adaptMessage(bot: SlackBot, evt: Partial, session: Partial = {}) { session.messageId = evt.ts session.timestamp = Math.floor(Number(evt.ts) * 1000) session.author = evt.bot_profile ? adaptBotProfile(evt) : adaptAuthor(evt) @@ -167,6 +165,8 @@ export async function adaptSession(bot: SlackBot, payload: EnvelopedEvent