UNPKG

@stack.thefennec.dev/telegram-export-parser

Version:

TypeScript library for parsing Telegram Desktop's data export with full type safety

541 lines 16.2 kB
import type { TelegramMessage } from './messages'; import type { TelegramEvent } from './events'; /** * Message type identifiers used to distinguish between user messages and service events. * * @example * ```typescript * if (item.type === MESSAGE_TYPES.MESSAGE) { * // Handle user message * } else if (item.type === MESSAGE_TYPES.SERVICE) { * // Handle service event * } * ``` */ export declare const MESSAGE_TYPES: { /** Regular user-generated message */ readonly MESSAGE: "message"; /** System-generated service event */ readonly SERVICE: "service"; }; /** * Union type for all possible message types. * Used to differentiate between user content and system events. */ export type MessageType = typeof MESSAGE_TYPES.MESSAGE | typeof MESSAGE_TYPES.SERVICE; /** * Media type identifiers for different kinds of file attachments. * * These constants correspond to the media_type field in Telegram exports * and help identify the specific type of media content. * * @example * ```typescript * if (mediaMessage.mediaType === MEDIA_TYPES.VIDEO_FILE) { * // Handle video file * } * ``` */ export declare const MEDIA_TYPES: { /** Static or animated sticker image */ readonly STICKER: "sticker"; /** Animated GIF or short video loop */ readonly ANIMATION: "animation"; /** Music or audio file with metadata */ readonly AUDIO_FILE: "audio_file"; /** Regular video file with full controls */ readonly VIDEO_FILE: "video_file"; /** Circular video message (video note) */ readonly VIDEO_NOTE: "video_message"; /** Voice message recording */ readonly VOICE_NOTE: "voice_message"; /** Generic document or file attachment */ readonly FILE: "file"; }; /** * Union type for all supported media types. * Used to type-check and validate media message content. */ export type MediaType = typeof MEDIA_TYPES[keyof typeof MEDIA_TYPES]; /** * Actor type identifiers for different kinds of message senders. * * Actors represent who sent a message, from regular users to bots, * channels, and special cases like deleted accounts. * * @example * ```typescript * if (actor.type === 'bot') { * console.log(`Bot message from ${actor.displayName}`) * } * ``` */ export declare const ACTOR_TYPES: readonly ["user", "bot", "channel", "channel_author", "deleted_user"]; /** * Union type for all possible actor types. * Used to identify the nature of message senders. */ export type ActorType = typeof ACTOR_TYPES[number]; /** * Represents any entity that can send messages in Telegram. * * Actors include users, bots, channels, and special cases like * deleted accounts. Contains identification and display information. * * @example * ```typescript * const formatSender = (actor: Actor): string => { * const name = actor.displayName || 'Unknown' * const username = actor.username ? `@${actor.username}` : '' * return `${name} ${username}`.trim() * } * ``` */ export interface Actor { /** Numeric Telegram ID (undefined for some edge cases) */ id: number | undefined; /** Type of actor (user, bot, channel, etc.) */ type: ActorType; /** Telegram username without @ symbol (if available) */ username: string | undefined; /** Display name or fallback for deleted/unknown users */ displayName: string | "Deleted User" | "Unknown"; /** For channel authors, the original author name */ authoredBy: string | undefined; } /** * Represents a file reference from Telegram export. * Can be a URL, null, or undefined depending on export format and availability. */ export type ExportedFile = URL | null | undefined; /** * Reaction type identifiers for message reactions. * * @example * ```typescript * if (reaction.type === 'custom_emoji') { * // Handle custom emoji reaction * } * ``` */ export declare const REACTION_TYPES: readonly ["emoji", "custom_emoji"]; /** * Union type for reaction types. */ export type ReactionType = typeof REACTION_TYPES[number]; /** * Represents a user reaction to a message. * * Contains the reaction emoji/sticker, count, and information about * recent users who added this reaction. * * @example * ```typescript * const formatReaction = (reaction: Reaction): string => { * return `${reaction.emoji} (${reaction.count})` * } * ``` */ export interface Reaction { /** The emoji or reaction identifier */ emoji: string; /** URL to custom emoji file (if applicable) */ documentURL: ExportedFile; /** Total number of users who added this reaction */ count: number; /** Recent users who added this reaction (up to a limit) */ recent: Array<{ /** User who added the reaction */ sender: Actor; /** When the reaction was added */ date: Date; }>; } /** * Conversation type identifiers for different kinds of Telegram chats. * * @example * ```typescript * if (conversation.type === 'public_channel') { * // Handle public channel * } * ``` */ export declare const CONVERSATION_TYPES: readonly ["personal_chat", "private_group", "private_supergroup", "public_supergroup", "public_channel", "private_channel"]; /** * Union type for all conversation types. * Used to identify the nature and privacy level of chats. */ export type ConversationType = typeof CONVERSATION_TYPES[number]; /** * Represents a Telegram chat or conversation. * * Contains basic metadata about the chat including its type, * name, and unique identifier. * * @example * ```typescript * const isGroupChat = (conv: Conversation): boolean => { * return conv.type.includes('group') * } * ``` */ export interface Conversation { /** Unique Telegram chat identifier */ id: number; /** Display name of the chat (undefined for some personal chats) */ name: string | undefined; /** Type of conversation (personal, group, channel, etc.) */ type: ConversationType; } /** * Complete parsed Telegram chat export data. * * This is the main data structure returned by the parser, containing * all messages, participants, and metadata for a chat export. * * @example * ```typescript * const analyzeExport = (export: TelegramChatExport) => { * console.log(`Chat: ${export.conversation.name}`) * console.log(`Messages: ${export.totalMessages}`) * console.log(`Participants: ${export.participants.size}`) * console.log(`Date range: ${export.dateRange.earliest} to ${export.dateRange.latest}`) * } * ``` */ export interface TelegramChatExport { /** Information about the chat/conversation */ conversation: Conversation; /** Map of user IDs to Actor objects for all participants */ participants: Map<number, Actor>; /** All messages and events in chronological order */ messages: (TelegramMessage | TelegramEvent)[]; /** Total count of messages for quick reference */ totalMessages: number; /** Time span covered by the export */ dateRange: { /** Oldest message timestamp */ earliest: Date; /** Newest message timestamp */ latest: Date; }; } /** * Inline button type identifiers for bot interaction buttons. * * These buttons appear below messages and provide various interaction * methods like URLs, callbacks, and payment flows. * * @example * ```typescript * if (button.type === 'url') { * // Handle URL button * window.open(button.url) * } * ``` */ export declare const INLINE_BUTTON_TYPES: readonly ["url", "callback", "switch_inline", "switch_inline_query", "switch_inline_query_current_chat", "callback_game", "pay"]; /** * Union type for all inline button types. */ export type InlineButtonType = typeof INLINE_BUTTON_TYPES[number]; /** * Represents an interactive button attached to a bot message. * * Inline buttons provide rich interaction capabilities including * web links, bot callbacks, payments, and game launches. * * @example * ```typescript * const handleButton = (button: InlineButton) => { * switch (button.type) { * case 'url': * return `<a href="${button.url}">${button.text}</a>` * case 'callback': * return `<button data-callback="${button.data}">${button.text}</button>` * } * } * ``` */ export interface InlineButton { /** Type of button interaction */ type: InlineButtonType; /** Display text on the button */ text: string; /** Callback data sent to bot (for callback buttons) */ data?: string; /** Base64 encoded callback data */ dataBase64?: string; /** URL to open (for URL buttons) */ url?: string; /** Unique button identifier */ button_id?: string; } /** * Geographical location coordinates. * * Used for location messages and venue information. * Coordinates follow standard WGS84 format. * * @example * ```typescript * const formatLocation = (location: LocationInfo): string => { * return `${location.latitude}, ${location.longitude}` * } * ``` */ export interface LocationInfo { /** Latitude coordinate (-90 to 90) */ latitude: number; /** Longitude coordinate (-180 to 180) */ longitude: number; } /** * Contact information for a person. * * Represents structured contact data that can be imported * into address book applications. * * @example * ```typescript * const formatContact = (contact: ContactInfo): string => { * const name = `${contact.first_name} ${contact.last_name}`.trim() * return `${name} (${contact.phone_number})` * } * ``` */ export interface ContactInfo { /** Contact's first/given name */ first_name: string; /** Contact's last/family name */ last_name: string; /** Phone number in international format */ phone_number: string; } /** * Single answer option in a poll. * * Contains the answer text, vote count, and whether the * current user selected this option. * * @example * ```typescript * const formatAnswer = (answer: PollAnswer): string => { * const selected = answer.chosen ? '✓ ' : '' * return `${selected}${answer.text} (${answer.voters} votes)` * } * ``` */ export interface PollAnswer { /** Answer option text */ text: string; /** Number of users who selected this answer */ voters: number; /** Whether the current user chose this answer */ chosen: boolean; } /** * Complete poll/survey data. * * Includes the question, all answer options with vote counts, * and poll state information. * * @example * ```typescript * const analyzePoll = (poll: Poll): string => { * const status = poll.closed ? 'Closed' : 'Active' * const participation = `${poll.total_voters} voters` * return `${poll.question} - ${status} (${participation})` * } * ``` */ export interface Poll { /** The poll question text */ question: string; /** Whether voting is still allowed */ closed: boolean; /** Total number of users who participated */ total_voters: number; /** All answer options with vote counts */ answers: PollAnswer[]; } /** * Payment invoice information. * * Contains details for Telegram payment requests including * price, currency, and item description. * * @example * ```typescript * const formatInvoice = (invoice: InvoiceInfo): string => { * return `${invoice.title} - ${invoice.amount} ${invoice.currency}` * } * ``` */ export interface InvoiceInfo { /** Product or service name */ title: string; /** Detailed description of the item */ description: string; /** Currency code (e.g., 'USD', 'EUR') */ currency: string; /** Price amount in smallest currency unit (cents) */ amount: number; } /** * Type guard to validate Actor objects. * * Ensures the object has all required Actor properties with correct types * and validates the actor type against known values. * * @param obj - The value to validate * @returns True if the value is a valid Actor * * @example * ```typescript * if (isActor(data)) { * // TypeScript now knows data is Actor * console.log(`Actor: ${data.displayName} (${data.type})`) * } * ``` */ export declare function isActor(obj: unknown): obj is Actor; /** * Type guard to validate Reaction objects. * * Validates reaction structure including emoji, count, and recent users array. * Also performs deep validation of the recent users array structure. * * @param obj - The value to validate * @returns True if the value is a valid Reaction * * @example * ```typescript * if (isReaction(data)) { * console.log(`${data.emoji}: ${data.count} reactions`) * } * ``` */ export declare function isReaction(obj: unknown): obj is Reaction; /** * Type guard to validate Conversation objects. * * Ensures the conversation has a valid ID and type from the known conversation types. * * @param obj - The value to validate * @returns True if the value is a valid Conversation * * @example * ```typescript * if (isConversation(data)) { * console.log(`Chat: ${data.name} (${data.type})`) * } * ``` */ export declare function isConversation(obj: unknown): obj is Conversation; /** * Type guard to validate InlineButton objects. * * Validates button type and text, with optional validation of type-specific * properties like URLs and callback data. * * @param obj - The value to validate * @returns True if the value is a valid InlineButton * * @example * ```typescript * if (isInlineButton(data)) { * if (data.type === 'url' && data.url) { * console.log(`URL Button: ${data.text} -> ${data.url}`) * } * } * ``` */ export declare function isInlineButton(obj: unknown): obj is InlineButton; /** * Type guard to validate LocationInfo objects. * * Ensures latitude and longitude are valid numbers within expected ranges. * * @param obj - The value to validate * @returns True if the value is valid LocationInfo * * @example * ```typescript * if (isLocationInfo(data)) { * console.log(`Location: ${data.latitude}, ${data.longitude}`) * } * ``` */ export declare function isLocationInfo(obj: unknown): obj is LocationInfo; /** * Type guard to validate ContactInfo objects. * * Ensures all name and phone number fields are present and non-empty strings. * * @param obj - The value to validate * @returns True if the value is valid ContactInfo * * @example * ```typescript * if (isContactInfo(data)) { * const fullName = `${data.first_name} ${data.last_name}`.trim() * console.log(`Contact: ${fullName} (${data.phone_number})`) * } * ``` */ export declare function isContactInfo(obj: unknown): obj is ContactInfo; /** * Type guard to validate Poll objects. * * Validates poll structure including question, state, and answers array. * Performs deep validation of all poll answers. * * @param obj - The value to validate * @returns True if the value is a valid Poll * * @example * ```typescript * if (isPoll(data)) { * const totalVotes = data.answers.reduce((sum, answer) => sum + answer.voters, 0) * console.log(`Poll: ${data.question} (${totalVotes} votes)`) * } * ``` */ export declare function isPoll(obj: unknown): obj is Poll; /** * Type guard to validate InvoiceInfo objects. * * Validates payment invoice data including title, description, currency, and amount. * Ensures amount is a positive number representing the price. * * @param obj - The value to validate * @returns True if the value is valid InvoiceInfo * * @example * ```typescript * if (isInvoiceInfo(data)) { * console.log(`Invoice: ${data.title} - ${data.amount} ${data.currency}`) * } * ``` */ export declare function isInvoiceInfo(obj: unknown): obj is InvoiceInfo; /** * Type guard to validate TelegramChatExport objects. * * Validates the complete export structure including conversation data, * participants map, messages array, and metadata. * * @param obj - The value to validate * @returns True if the value is a valid TelegramChatExport * * @example * ```typescript * if (isTelegramChatExport(data)) { * console.log(`Export: ${data.totalMessages} messages from ${data.conversation.name}`) * } * ``` */ export declare function isTelegramChatExport(obj: unknown): obj is TelegramChatExport; //# sourceMappingURL=shared.d.ts.map