diff --git a/src/api/gramjs/apiBuilders/bots.ts b/src/api/gramjs/apiBuilders/bots.ts index df37730d0..7fb7e7b42 100644 --- a/src/api/gramjs/apiBuilders/bots.ts +++ b/src/api/gramjs/apiBuilders/bots.ts @@ -398,7 +398,7 @@ export function buildBotAppSettings(settings: GramJs.BotAppSettings): ApiBotAppS }; } -function buildApiBotCommand(botId: string, command: GramJs.BotCommand): ApiBotCommand { +export function buildApiBotCommand(botId: string, command: GramJs.BotCommand): ApiBotCommand { return { botId, ...omitVirtualClassFields(command), diff --git a/src/api/gramjs/updates/mtpUpdateHandler.ts b/src/api/gramjs/updates/mtpUpdateHandler.ts index f7b382eb3..809230020 100644 --- a/src/api/gramjs/updates/mtpUpdateHandler.ts +++ b/src/api/gramjs/updates/mtpUpdateHandler.ts @@ -12,7 +12,7 @@ import { omit, pick, } from '../../../util/iteratees'; import { getServerTimeOffset, setServerTimeOffset } from '../../../util/serverTime'; -import { buildApiBotMenuButton } from '../apiBuilders/bots'; +import { buildApiBotCommand, buildApiBotMenuButton } from '../apiBuilders/bots'; import { buildApiGroupCall, buildApiGroupCallParticipant, @@ -953,6 +953,19 @@ export function updater(update: Update) { botId: id, button: buildApiBotMenuButton(button), }); + } else if (update instanceof GramJs.UpdateBotCommands) { + const { + botId, + commands, + } = update; + + const id = buildApiPeerId(botId, 'user'); + const commandsArray = commands.map((command) => buildApiBotCommand(id, command)); + sendApiUpdate({ + '@type': 'updateBotCommands', + botId: id, + commands: commandsArray.length ? commandsArray : undefined, + }); } else if (update instanceof GramJs.UpdateTranscribedAudio) { sendApiUpdate({ '@type': 'updateTranscribedAudio', diff --git a/src/api/types/updates.ts b/src/api/types/updates.ts index 06c50ff1d..c42e17073 100644 --- a/src/api/types/updates.ts +++ b/src/api/types/updates.ts @@ -8,7 +8,7 @@ import type { } from '../../lib/secret-sauce'; import type { ThreadId } from '../../types'; import type { RegularLangFnParameters } from '../../util/localization'; -import type { ApiBotMenuButton } from './bots'; +import type { ApiBotCommand, ApiBotMenuButton } from './bots'; import type { ApiGroupCall, ApiPhoneCall, } from './calls'; @@ -826,6 +826,12 @@ export type ApiUpdateLangPack = { keysToRemove: string[]; }; +export type ApiUpdateBotCommands = { + '@type': 'updateBotCommands'; + botId: string; + commands?: ApiBotCommand[]; +}; + export type ApiUpdate = ( ApiUpdateReady | ApiUpdateSession | ApiUpdateWebAuthTokenFailed | ApiUpdateRequestUserUpdate | ApiUpdateAuthorizationState | ApiUpdateAuthorizationError | ApiUpdateConnectionState | ApiUpdateCurrentUser | @@ -857,7 +863,7 @@ export type ApiUpdate = ( ApiRequestReconnectApi | ApiRequestSync | ApiUpdateFetchingDifference | ApiUpdateChannelMessages | ApiUpdateStealthMode | ApiUpdateAttachMenuBots | ApiUpdateNewAuthorization | ApiUpdateGroupInvitePrivacyForbidden | ApiUpdateViewForumAsMessages | ApiUpdateSavedDialogPinned | ApiUpdatePinnedSavedDialogIds | ApiUpdateChatLastMessage | - ApiUpdateDeleteSavedHistory | ApiUpdatePremiumFloodWait | ApiUpdateStarsBalance | + ApiUpdateDeleteSavedHistory | ApiUpdatePremiumFloodWait | ApiUpdateStarsBalance | ApiUpdateBotCommands | ApiUpdateQuickReplyMessage | ApiUpdateQuickReplies | ApiDeleteQuickReply | ApiUpdateDeleteQuickReplyMessages | ApiUpdateDeleteProfilePhoto | ApiUpdateNewProfilePhoto | ApiUpdateEntities | ApiUpdatePaidReactionPrivacy | ApiUpdateLangPackTooLong | ApiUpdateLangPack | ApiUpdateNotSupportedInFrozenAccountError diff --git a/src/global/actions/apiUpdaters/users.ts b/src/global/actions/apiUpdaters/users.ts index 77600a116..5f03c0882 100644 --- a/src/global/actions/apiUpdaters/users.ts +++ b/src/global/actions/apiUpdaters/users.ts @@ -107,6 +107,21 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => { }); } + case 'updateBotCommands': { + const { botId, commands } = update; + const targetUserFullInfo = selectUserFullInfo(global, botId); + if (!targetUserFullInfo?.botInfo) { + return undefined; + } + + return updateUserFullInfo(global, botId, { + botInfo: { + ...targetUserFullInfo.botInfo, + commands, + }, + }); + } + case 'updatePeerSettings': { const { id, settings } = update;