import BigInt from 'big-integer'; import { Api as GramJs } from '../../../lib/gramjs'; import type { ApiSticker, ApiVideo, OnApiUpdate } from '../../types'; import { invokeRequest } from './client'; import { buildStickerFromDocument, buildStickerSet, buildStickerSetCovered } from '../apiBuilders/symbols'; import { buildInputStickerSet, buildInputDocument, buildInputStickerSetShortName } from '../gramjsBuilders'; import { buildVideoFromDocument } from '../apiBuilders/messages'; import { RECENT_STICKERS_LIMIT } from '../../../config'; import localDb from '../localDb'; let onUpdate: OnApiUpdate; export function init(_onUpdate: OnApiUpdate) { onUpdate = _onUpdate; } export async function fetchStickerSets({ hash = '0' }: { hash?: string }) { const allStickers = await invokeRequest(new GramJs.messages.GetAllStickers({ hash: BigInt(hash) })); if (!allStickers || allStickers instanceof GramJs.messages.AllStickersNotModified) { return undefined; } allStickers.sets.forEach((stickerSet) => { if (stickerSet.thumbs?.length) { localDb.stickerSets[String(stickerSet.id)] = stickerSet; } }); return { hash: String(allStickers.hash), sets: allStickers.sets.map(buildStickerSet), }; } export async function fetchRecentStickers({ hash = '0' }: { hash?: string }) { const result = await invokeRequest(new GramJs.messages.GetRecentStickers({ hash: BigInt(hash) })); if (!result || result instanceof GramJs.messages.RecentStickersNotModified) { return undefined; } return { hash: String(result.hash), stickers: processStickerResult(result.stickers.slice(0, RECENT_STICKERS_LIMIT)), }; } export async function fetchFavoriteStickers({ hash = '0' }: { hash?: string }) { const result = await invokeRequest(new GramJs.messages.GetFavedStickers({ hash: BigInt(hash) })); if (!result || result instanceof GramJs.messages.FavedStickersNotModified) { return undefined; } return { hash: String(result.hash), stickers: processStickerResult(result.stickers), }; } export async function fetchFeaturedStickers({ hash = '0' }: { hash?: string }) { const result = await invokeRequest(new GramJs.messages.GetFeaturedStickers({ hash: BigInt(hash) })); if (!result || result instanceof GramJs.messages.FeaturedStickersNotModified) { return undefined; } return { hash: String(result.hash), sets: result.sets.map(buildStickerSetCovered), }; } export async function faveSticker({ sticker, unfave, }: { sticker: ApiSticker; unfave?: boolean; }) { const request = new GramJs.messages.FaveSticker({ id: buildInputDocument(sticker), unfave, }); const result = await invokeRequest(request); if (result) { onUpdate({ '@type': 'updateFavoriteStickers', }); } } export function removeRecentSticker({ sticker, }: { sticker: ApiSticker; }) { const request = new GramJs.messages.SaveRecentSticker({ id: buildInputDocument(sticker), unsave: true, }); return invokeRequest(request); } export function clearRecentStickers() { return invokeRequest(new GramJs.messages.ClearRecentStickers()); } export async function fetchStickers( { stickerSetShortName, stickerSetId, accessHash }: { stickerSetShortName?: string; stickerSetId?: string; accessHash: string }, ) { const result = await invokeRequest(new GramJs.messages.GetStickerSet({ stickerset: stickerSetId ? buildInputStickerSet(stickerSetId, accessHash) : buildInputStickerSetShortName(stickerSetShortName!), })); if (!(result instanceof GramJs.messages.StickerSet)) { return undefined; } return { set: buildStickerSet(result.set), stickers: processStickerResult(result.documents), packs: processStickerPackResult(result.packs), }; } export async function fetchAnimatedEmojis() { const result = await invokeRequest(new GramJs.messages.GetStickerSet({ stickerset: new GramJs.InputStickerSetAnimatedEmoji(), })); if (!(result instanceof GramJs.messages.StickerSet)) { return undefined; } return { set: buildStickerSet(result.set), stickers: processStickerResult(result.documents), }; } export async function fetchAnimatedEmojiEffects() { const result = await invokeRequest(new GramJs.messages.GetStickerSet({ stickerset: new GramJs.InputStickerSetAnimatedEmojiAnimations(), })); if (!(result instanceof GramJs.messages.StickerSet)) { return undefined; } return { set: buildStickerSet(result.set), stickers: processStickerResult(result.documents), }; } export async function searchStickers({ query, hash = '0' }: { query: string; hash?: string }) { const result = await invokeRequest(new GramJs.messages.SearchStickerSets({ q: query, hash: BigInt(hash), })); if (!result || result instanceof GramJs.messages.FoundStickerSetsNotModified) { return undefined; } return { hash: String(result.hash), sets: result.sets.map(buildStickerSetCovered), }; } export async function fetchSavedGifs({ hash = '0' }: { hash?: string }) { const result = await invokeRequest(new GramJs.messages.GetSavedGifs({ hash: BigInt(hash) })); if (!result || result instanceof GramJs.messages.SavedGifsNotModified) { return undefined; } return { hash: String(result.hash), gifs: processGifResult(result.gifs), }; } export function saveGif({ gif, shouldUnsave }: { gif: ApiVideo; shouldUnsave?: boolean }) { const request = new GramJs.messages.SaveGif({ id: buildInputDocument(gif), unsave: shouldUnsave, }); return invokeRequest(request, true); } export async function installStickerSet({ stickerSetId, accessHash }: { stickerSetId: string; accessHash: string }) { const result = await invokeRequest(new GramJs.messages.InstallStickerSet({ stickerset: buildInputStickerSet(stickerSetId, accessHash), })); if (result) { onUpdate({ '@type': 'updateStickerSet', id: stickerSetId, stickerSet: { installedDate: Date.now() }, }); } } export async function uninstallStickerSet({ stickerSetId, accessHash }: { stickerSetId: string; accessHash: string }) { const result = await invokeRequest(new GramJs.messages.UninstallStickerSet({ stickerset: buildInputStickerSet(stickerSetId, accessHash), })); if (result) { onUpdate({ '@type': 'updateStickerSet', id: stickerSetId, stickerSet: { installedDate: undefined }, }); } } let inputGifBot: GramJs.InputUser | undefined; export async function searchGifs({ query, offset = '' }: { query: string; offset?: string }) { if (!inputGifBot) { const config = await invokeRequest(new GramJs.help.GetConfig()); if (!config) { return undefined; } const resolvedPeer = await invokeRequest(new GramJs.contacts.ResolveUsername({ username: config.gifSearchUsername, })); if (!resolvedPeer || !(resolvedPeer.users[0] instanceof GramJs.User)) { return undefined; } inputGifBot = new GramJs.InputUser({ userId: (resolvedPeer.peer as GramJs.PeerUser).userId, accessHash: resolvedPeer.users[0].accessHash!, }); } const result = await invokeRequest(new GramJs.messages.GetInlineBotResults({ bot: inputGifBot, peer: new GramJs.InputPeerEmpty(), query, offset, })); if (!result) { return undefined; } const documents = result.results .map((foundGif) => { if (foundGif instanceof GramJs.BotInlineMediaResult) { return foundGif.document; } return undefined; }) .filter(Boolean as any); return { nextOffset: result.nextOffset, gifs: processGifResult(documents), }; } export async function fetchStickersForEmoji({ emoji, hash = '0', }: { emoji: string; hash?: string }) { const result = await invokeRequest(new GramJs.messages.GetStickers({ emoticon: emoji, hash: BigInt(hash), })); if (!result || result instanceof GramJs.messages.StickersNotModified) { return undefined; } return { stickers: processStickerResult(result.stickers), hash: String(result.hash), }; } export async function fetchEmojiKeywords({ language, fromVersion }: { language: string; fromVersion?: number; }) { const result = await invokeRequest(new GramJs.messages.GetEmojiKeywordsDifference({ langCode: language, fromVersion, })); if (!result) { return undefined; } return { language: result.langCode, version: result.version, keywords: result.keywords.reduce((acc, emojiKeyword) => { acc[emojiKeyword.keyword] = emojiKeyword.emoticons; return acc; }, {} as Record), }; } function processStickerResult(stickers: GramJs.TypeDocument[]) { return stickers .map((document) => { if (document instanceof GramJs.Document) { const sticker = buildStickerFromDocument(document); if (sticker) { localDb.documents[String(document.id)] = document; return sticker; } } return undefined; }) .filter(Boolean as any); } function processStickerPackResult(packs: GramJs.StickerPack[]) { return packs.reduce((acc, { emoticon, documents }) => { acc[emoticon] = documents.map((documentId) => buildStickerFromDocument( localDb.documents[String(documentId)], )).filter(Boolean as any); return acc; }, {} as Record); } function processGifResult(gifs: GramJs.TypeDocument[]) { return gifs .map((document) => { if (document instanceof GramJs.Document) { const gif = buildVideoFromDocument(document); if (gif) { localDb.documents[String(document.id)] = document; return gif; } } return undefined; }) .filter(Boolean as any); }