/**
 * A node in a {@link TextBlock} that renders its children as a clickable {@link https://talkjs.com/docs/Guides/JavaScript/Classic/Action_Buttons_Links/ | action button} which triggers a custom action.
 *
 * @remarks
 * By default, users do not have permission to send messages containing action buttons as they can be used maliciously to trick others into invoking custom actions.
 * For example, a user could send an "accept offer" action button, but disguise it as "view offer".
 *
 * @public
 */
export declare interface ActionButtonNode {
    readonly type: "actionButton";
    /**
     * The name of the custom action to invoke when the button is clicked.
     */
    readonly action: string;
    /**
     * The parameters to pass to the custom action when the button is clicked.
     */
    readonly params: Record<string, string>;
    readonly children: TextNode[];
}

/**
 * @public
 * Provides additional parameters to custom message action or conversation action events.
 */
export declare interface ActionEventParams {
    /**
     * Any number of key/value pairs that will be sent with the action event.
     *
     * @remarks
     * Both the key and the value must be strings. Deeply nested JSON is not supported.
     *
     * Add to action buttons in your theme components with the syntax `data-<key>=<value>`,
     * or to action buttons in messages with the syntax `action?<key>=<value>`.
     *
     * @example In a theme
     * ```
     * <ActionButton action="color" data-choice="red">Red</ActionButton>
     * ```
     *
     * This theme component creates an action button that emits a `color` action event
     * when you click it, with a parameter called `choice` that takes the value `red`.
     *
     * @example In message markup
     * ```
     * <actionbutton:color?choice=blue|Blue>
     * ```
     *
     * This message markup creates an action button that emits a `color` message action event
     * when you click it, with a parameter called `choice` that takes the value `blue`.
     */
    [key: string]: string;
}

/**
 * A node in a {@link TextBlock} that renders its children as a clickable {@link https://talkjs.com/docs/Guides/JavaScript/Classic/Action_Buttons_Links/ | action link} which triggers a custom action.
 *
 * @remarks
 * By default, users do not have permission to send messages containing `ActionLinkNode` as it can be used maliciously to trick others into invoking custom actions.
 * For example, a user could send an "accept offer" action link, but disguise it as a link to a website.
 *
 * @public
 */
export declare interface ActionLinkNode {
    readonly type: "actionLink";
    /**
     * The name of the custom action to invoke when the link is clicked.
     */
    readonly action: string;
    /**
     * The parameters to pass to the custom action when the link is clicked.
     */
    readonly params: Record<string, string>;
    readonly children: TextNode[];
}

declare type Attachment = {
    url: string;
    size: number;
    dimensions?: AttachmentDimensions;
};

declare type AttachmentDimensions = {
    width?: number;
    height?: number;
    duration?: number;
};

/**
 * A FileBlock variant for an audio attachment, with additional audio-specific metadata.
 *
 * @remarks
 * You can identify this variant by checking for `subtype: "audio"`.
 *
 * The same file could be uploaded as either an audio block, or as a {@link VoiceBlock}.
 * The same data will be available either way, but they will be rendered differently in the UI.
 *
 * Includes metadata about the duration of the audio file in seconds, where available.
 *
 * Audio files that you upload with the TalkJS UI will include the duration as long as the sender's browser can preview the file.
 * Audio files that you upload with the REST API or {@link Session.uploadAudio} will include the duration if you specified it when uploading.
 * Audio files attached in a reply to an email notification will not include the duration.
 *
 * @public
 */
export declare interface AudioBlock {
    readonly type: "file";
    readonly subtype: "audio";
    /**
     * An encoded identifier for this file. Use in {@link SendFileBlock} to send this file in another message.
     */
    readonly fileToken: FileToken;
    /**
     * The URL where you can fetch the file
     */
    readonly url: string;
    /**
     * The size of the file in bytes
     */
    readonly size: number;
    /**
     * The name of the audio file, including file extension
     */
    readonly filename: string;
    /**
     * The duration of the audio in seconds, if known
     */
    readonly duration?: number;
}

/**
 * @public
 */
export declare interface AudioFileMetadata {
    /**
     * The name of the file including extension.
     */
    filename: string;
    /**
     * The duration of the audio file in seconds, if known.
     */
    duration?: number;
}

/**
 * A node in a {@link TextBlock} that renders `text` as a link (HTML `<a>`).
 *
 * @remarks
 * Used when user-typed text is turned into a link automatically.
 *
 * Unlike {@link LinkNode}, users do have permission to send AutoLinkNodes by default, because the `text` and `url` properties must match.
 * Specifically:
 *
 * - If `text` is an email, `url` must contain a `mailto:` link to the same email address
 *
 * - If `text` is a phone number, `url` must contain a `tel:` link to the same phone number
 *
 * - If `text` is a website, the domain name including subdomains must be the same in both `text` and `url`.
 * If `text` includes a protocol (such as `https`), path (/page), query string (?page=true), or url fragment (#title), they must be the same in `url`.
 * If `text` does not specify a protocol, `url` must use either `https` or `http`.
 *
 * This means that the following AutoLink is valid:
 *
 * ```json
 * {
 *     type: "autoLink",
 *     text: "talkjs.com"
 *     url: "https://talkjs.com/docs/JavaScript_Data_API/Message_Content/#AutoLinkNode"
 * }
 * ```
 *
 * That link will appear as `talkjs.com` and link you to the specific section of the documentation that explains how AutoLinkNodes work.
 *
 * These rules ensure that the user knows what link they are clicking, and prevents AutoLinkNode being used for phishing.
 * If you try to send a message containing an AutoLink that breaks these rules, the request will be rejected.
 *
 * @public
 */
export declare interface AutoLinkNode {
    readonly type: "autoLink";
    /**
     * The URL to open when a user clicks this node.
     */
    readonly url: string;
    /**
     * The text to display in the link.
     */
    readonly text: string;
}

/**
 * @public
 * @hidden due to being empty
 * @deprecated Use `chatbox.onBlur(() => {...})` instead, without an event parameter.
 */
export declare interface BlurEvent {
}

/**
 * Sent by {@link Session.onBrowserPermissionDenied} when the user tried to do
 * an action that require explicit browser permission, but it was denied.
 *
 * @public
 */
export declare interface BrowserPermissionDeniedEvent {
    /**
     * The type of permission that was denied.
     *
     * @remarks
     * Note that more possible values may be added in the future, so make sure your
     * handler can deal with unknown permission types gracefully.
     */
    type: PermissionType;
}

/**
 * Sent by {@link Session.onBrowserPermissionNeeded} when a browser permission
 * dialog is about to be shown to the user.
 *
 * @public
 */
export declare interface BrowserPermissionNeededEvent {
    /**
     * The type of permission requested.
     *
     * @remarks
     * Note that more possible values may be added in the future, so make sure your
     * handler can deal with unknown permission types gracefully.
     */
    type: PermissionType;
    /**
     * Cancel whatever user action caused the permission to be requested.
     *
     * @remarks
     * For example, if a user wants to share their location for the first time so
     * that this event is triggered, then if you call `preventDefault()`, no
     * permission will be requested from the browser, the location sharing will be
     * cancelled, and TalkJS will continue as if the location sharing button had
     * not been clicked at all.
     *
     * This may be useful if you're using this event to show custom UI elements
     * that nudge users towards granting permission, and this UI has a "cancel"
     * button.
     */
    preventDefault(): void;
}

/**
 * A node in a {@link TextBlock} that adds indentation for a bullet-point list around its children (HTML `<ul>`).
 *
 * @remarks
 * Used when users send a bullet-point list by starting lines of their message with `-` or `*`.
 *
 * @public
 */
export declare interface BulletListNode {
    readonly type: "bulletList";
    readonly children: TextNode[];
}

/**
 * A node in a {@link TextBlock} that renders its children with a bullet-point (HTML `<li>`).
 *
 * @remarks
 * Used when users start a line of their message with `-` or `*`.
 *
 * @public
 */
export declare interface BulletPointNode {
    readonly type: "bulletPoint";
    readonly children: TextNode[];
}

/**
 * A messaging UI for just a single conversation
 *
 * @remarks
 * There is no way for the user to switch between conversations
 * (but you can change the active conversation through {@link Chatbox.select}).
 * Create a Chatbox through {@link Session.createChatbox} and then call
 * {@link Chatbox.mount} to show it.
 * @public
 */
export declare interface Chatbox extends UIBox {
    /**
     * Renders the Chatbox UI inside a DOM element on your page.
     *
     * @remarks
     * The container element specified by `container` must either be a DOM Element (as returned by e.g.
     * `document.getElementById`) or a JQuery object with a single element.
     */
    mount(container: HTMLElement | null): Promise<void>;
    /**
     * Destroys the chatbox and removes it from the DOM
     *
     * @remarks
     * Destroys the chatbox, removes it from the DOM and removes all event listeners it has running. Call this before removing
     * the chatbox container from the DOM.
     */
    destroy(): void;
}

/**
 * @alias UIBox Chatbox
 * @public
 */
export declare interface ChatboxOptions {
    /**
     * Controls the text direction (for supporting right-to-left languages such as Arabic and Hebrew). TalkJS tries
     * to determine the appropriate text direction from the parent page, but if that does not work or you want to
     * explicitly control it, you can override it here. Defaults to "ltr".
     */
    dir?: "ltr" | "rtl";
    /**
     * Sets the message input box to the given text.
     * You can use this to suggest a certain initial message to be sent. The user can still edit it before hitting "send".
     *
     * @deprecated We recommend using {@link MessageField.setText} before mounting the chatbox to precisely control when message suggestions are shown.
     */
    messageSuggestion?: string;
    /**
     * Used to control if the Chat Header is displayed in the UI. Defaults to true.
     */
    showChatHeader?: boolean;
    /**
     * Controls what text appears in the chat title, in the header above the messages.
     * Defaults to `"participants"`.
     *
     * (also see {@link ChatboxOptions.chatSubtitleMode} and {@link InboxOptions.feedConversationTitleMode})
     *
     * @deprecated This field only has effect if you use a {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Themes/Legacy_Themes/ | Legacy Theme}, or an older custom theme which does not have a ChatHeader component. If you do not, edit the ChatHeader component in the theme editor instead.
     */
    chatTitleMode?: "subject" | "participants";
    /**
     * Controls what text appears in the chat subtitle, right below the chat title.
     * No subtitle is displayed when the conversation has no subject set or when set to `null`.
     * Defaults to `"subject"`.
     *
     * (also see {@link ChatboxOptions.chatTitleMode} and {@link InboxOptions.feedConversationTitleMode})
     *
     * @deprecated This field only has effect if you use a {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Themes/Legacy_Themes/ | Legacy Theme }, or an older custom theme which does not have a ChatHeader component. If you do not, edit the ChatHeader component in the theme editor instead.
     */
    chatSubtitleMode?: "subject" | "participants" | null;
    /**
     * TalkJS leverages `iframe`s behind the scenes and therefore not all services that you use in your app will work out of the box.
     * This option adds support for a number of services to help you use them. Let us know if you're missing any.
     */
    thirdparties?: ThirdPartyOptions;
    /**
     * Used to control which messages are shown in the message list, depending on a type, origin
     * or custom message attributes.
     *
     * *Note*: Messages are only filtered in the message list. The inbox UI's conversation feed will always show the last message sent to the conversation, regardless of the message filter set.
     *
     * See {@link MessagePredicate} for all available options.
     *
     * You can also modify the filter on the fly using {@link UIBox.setMessageFilter}.
     */
    messageFilter?: MessagePredicate;
    /**
     * TalkJS can translate conversations to the current user's locale using Google Translate.
     * This option specifies which conversations should be translated in this UI. You can pass a boolean to enable or turn off
     * translation for all conversations, "auto" to enable translation on conversations where users have different locales,
     * or you can pass an array of {@link ConversationBuilder}s or conversation Ids to be translated.
     * This feature is only available on the Growth plan and above. Make sure you add your Google Translate API key on the "Settings" page of the dashboard.
     */
    translateConversations?: boolean | "auto" | string[] | ConversationBuilder[];
    /**
     * Set this to `true` to show a translation toggle in all conversations.
     * Set this to `"auto"` to show a translation toggle in conversations where there are participants with different locales.
     * This setting defaults to `false`, meaning that no toggles will be shown.
     * In order to use this, you must be on the Growth plan, and set a Google Translate API key on the "Settings" page of the dashboard.
     */
    showTranslationToggle?: boolean | "auto";
    /**
     * Settings that affect the behavior of the message field
     */
    messageField?: MessageFieldOptions;
    /**
     * Overrides the theme used for this chat UI.
     *
     * @remarks
     * This only works with themes created in the Theme Editor. If you don't pass a theme name, we'll first check for a theme set in the user's role, and then fall back to using the default theme.
     *
     * You can either pass the name of the theme you'd like to use, or a {@link ThemeOptions} object, which you can use to pass variables to your theme.
     */
    theme?: string | ThemeOptions;
    /**
     * Enables capturing {@link Chatbox.onKeyup} events.
     *
     * @remarks
     * Note: Setting this to true also disables any non-standard keyboard shortcuts in TalkJS.
     *
     * At the time of writing, the only such shortcut is that when `captureKeyboardEvents` is
     * disabled, TalkJS will auto-focus the message field if the user starts typing but no input field
     * is focused.
     */
    captureKeyboardEvents?: boolean;
    /**
     * Sets metadata for the current session.
     *
     * @remarks
     * - `visible` manually sets the information about the visibility of TalkJS.
     *   This is useful when TalkJS is hidden with CSS. TalkJS will assume that UIs
     *   marked `visible: false` cannot be seen, and thus messages arriving on this UI will
     *   not be marked as read until you set `visible` to true again.
     *
     * - `custom` is an additional parameter to store the custom fields, that you
     *   may want to use in the REST API call.
     */
    presence?: UserPresence;
    /**
     * Allows users to send and receive custom emojis.
     *
     * @remarks
     * This adds a set of custom emoji images to the emoji picker, the emoji
     * autocompleter, and emoji reactions.
     *
     * Every emoji name *must* start and end with a colon, for example `:lol:`.
     * Emoji names can be up to 50 characters long, including the colons.
     *
     * Make sure you always specify a consistent, backward-compatible set of
     * custom emojis. If an existing message contains a custom emoji that is not
     * specified in `customEmojis` here, then the emoji cannot be displayed and
     * the textual name will be displayed instead (including colons).
     *
     * If you want to allow an emoji to be displayed if it's used in existing
     * data, but not let users select it in new messages/reactions, set the
     * `hidden` option to `true` for that emoji.
     *
     * @example Create three custom emojis
     * ```json
     * {
     *   // Static image
     *   ":lol:": { url: "https://example.com/images/emoji-lol.svg" },
     *   // Animated
     *   ":roomba-cat:": { url: "https://example.com/images/roomba-cat.gif" },
     *   // Hidden
     *   ":alert:": { url: "https://example.com/images/alert.gif", hidden: true },
     * }
     * ```
     */
    customEmojis?: {
        [name: string]: CustomEmojiDefinition;
    };
}

/** @public
 * @hidden due to being empty
 * @deprecated Use `popup.onClose(() => {...})` instead, without an event parameter
 */
declare interface CloseEvent_2 {
}
export { CloseEvent_2 as CloseEvent }

/**
 * A node in a {@link TextBlock} that renders `text` in an inline code span (HTML `<code>`).
 *
 * @remarks
 * Used when a user types ```text```.
 *
 * @public
 */
export declare interface CodeSpanNode {
    readonly type: "codeSpan";
    readonly text: string;
}

/**
 * Allows you to filter conversations down to a specific subset.
 *
 * @remarks
 * Use with {@link Inbox.setFeedFilter} or pass {@link InboxOptions.feedFilter} to
 * {@link Session.createInbox}.
 *
 * The first element must be the string "any", and the second element a list of SimpleConversationPredicate objects.
 *
 * See {@link SimpleConversationPredicate} for all available options.
 *
 * @example Show conversations where you have read-only access, or whose custom `accountId` property is "my_account"
 * ```json
 * ["any", [{ access: ["==", "Read"] }, { custom: { accountId: ["==", "my_account"] } }]]
 * ```
 *
 * @public
 */
export declare type CompoundConversationPredicate = [
"any",
SimpleConversationPredicate[]
];

/**
 * Combines multiple simple filters into one, matching whenever any of the simple filters match (OR).
 *
 * @remarks
 * The first element must be the string "any", and the second element a list of simple filter objects.
 *
 * See {@link SimpleConversationFilter} for all available options in simple conversation filters.
 *
 * @example Only show conversations with messages, and empty conversations with the subject "cats!"
 * ```json
 * ["any", [
 *   { hasMessages: true },
 *   { subject: ["==", "cats!"] }
 * ]]
 * ```
 *
 * @public
 */
export declare type CompoundFilter<T> = ["any", T[]];

/**
 * Lets you show only specific messages in the chat panel of a Chatbox, Inbox or Popup.
 *
 * @remarks
 * Used in methods like {@link Chatbox.setMessageFilter}.
 *
 * The first element must be the string "any", and the second element a list of SimpleMessagePredicate objects.
 *
 * See {@link SimpleMessagePredicate} for all available options.
 *
 * @example Only show system messages and messages from users with the "admin" role
 * ```json
 * ["any", [{ type: ["==", "SystemMessage"] }, { sender: {"role": ["==", "admin"] } }]]
 * ```
 *
 * @public
 */
export declare type CompoundMessagePredicate = [
"any",
SimpleMessagePredicate[]
];

/**
 * The content of a message is structured as a list of content blocks.
 *
 * @remarks
 * Currently, each message can only have one content block, but this will change in the future.
 * This will not be considered a breaking change, so your code should assume there can be multiple content blocks.
 *
 * These blocks are rendered in order, top-to-bottom.
 *
 * Currently the available Content Block types are:
 *
 * - `type: "text"` ({@link TextBlock})
 *
 * - `type: "file"` ({@link FileBlock})
 *
 * - `type: "location"` ({@link LocationBlock})
 *
 * @public
 */
export declare type ContentBlock = TextBlock | FileBlock | LocationBlock;

/**
 * Encapsulates an active conversation between two parties.
 *
 * @remarks
 * Use this object to send system messages to the conversation or to programmatically select a
 * conversation by passing it to {@link Inbox.select}.
 *
 * Conversation objects are created with the deprecated {@link Session.getOrStartConversation}
 * method.
 *
 *
 * @public
 * @deprecated Use {@link ConversationRef} via {@link Session.conversation|Session.conversation()} instead
 */
export declare interface Conversation {
    /**
     * The ID of the conversation
     */
    readonly id: string;
    /**
     * @hidden
     * An array of {@link Participant | Participants} in the conversation.
     */
    participants: Array<Participant>;
    /**
     * An optional conversation subject which is displayed in the chat header
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    subject?: string | null;
    /**
     * Optional custom conversation meta data
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom?: {
        [name: string]: string | null;
    } | null;
    /**
     * One or more welcome messages that will display to the user as a SystemMessage
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessages?: Array<string> | null;
    /**
     * An optional URL to a photo which will be shown as the photo for the conversation.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    photoUrl?: string | null;
}

/**
 * @public
 * A string that must be `"ReadWrite"`, `"Read"` or `"None"`.
 */
export declare type ConversationAccessLevel = "ReadWrite" | "Read" | "None";

/**
 * @public
 * Emitted from {@link Chatbox.onCustomConversationAction} when a user clicks on a
 * custom action in a conversation within the TalkJS UI
 */
export declare interface ConversationActionEvent {
    action: string;
    params: ActionEventParams;
    /**
     * The value will be `null` if the conversation action is triggered
     * from inside the `ConversationListHeader` component.
     */
    conversation: ConversationData | null;
}

/**
 * The state of a conversation subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface ConversationActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the conversation, or `null` if you are not a participant in the conversation (including when the conversation does not exist).
     */
    readonly latestSnapshot: ConversationSnapshot | null;
}

/**
 * Conversation attributes that can be set using {@link ConversationBuilder.setAttributes}
 * @public
 */
export declare interface ConversationAttributes {
    /**
     * A human-readable subject of the conversation. Supports formatted links in a Markdown-style syntax, e.g.
     * `Beautiful <https://example.com/booking/18644|home by the sea>!`.
     *  URLs and email addresses are made clickable, and emojis made to work cross-platform.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    subject?: string | null;
    /**
     * The URL of a photo to be used for this conversation in the TalkJS UI in case there are more than 2 participants
     * (TalkJS shows the photo of the other participant in a 1-on-1 conversation)
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    photoUrl?: string | null;
    /**
     * Custom metadata that is stored with the conversation
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom?: {
        [key: string]: string | null;
    } | null;
    /**
     * Messages which are sent at the beginning of a chat.
     * In this case the messages will appear as system messages.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     *
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessages?: Array<string> | null;
}

/**
 * A Conversation Builder represents a conversation that is about to be created, fetched, or updated.
 * You can use this object to set up or modify a conversation before showing it.
 *
 * @remarks
 * To create a ConversationBuilder, call {@link Session.getOrCreateConversation}.
 *
 * Note: any changes you make here will not be sent to TalkJS immediately.
 * Instead, instantiate a TalkJS UI using methods such as {@link Session.createInbox}.
 *
 * @classic New TalkJS integrations should use {@link ConversationRef} via {@link Session.conversation | Session.conversation()} instead.
 * `ConversationRef` is part of the simpler and more powerful {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API}.
 *
 * @public
 */
export declare interface ConversationBuilder {
    /**
     * An optional conversation subject which will be displayed in the chat header.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    subject?: string | null;
    /**
     * Allows custom conversation metadata to be stored in the form `{ [name: string]: string }`
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom?: {
        [name: string]: string | null;
    } | null;
    /**
     * An optional URL to a photo which will be shown as the photo for the conversation.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    photoUrl?: string | null;
    /**
     * Messages which are sent at the beginning of a chat.
     * In this case the messages will appear as system messages.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     *
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessages?: Array<string> | null;
    /**
     * Sets a participant of the conversation.
     *
     * @remarks
     * This method is idempotent and can be called multiple times.
     *
     * @param user - A `User` object that identifies the person who is a participant of the
     * conversation. The user is uniquely identified by their id; all other fields (name, photo etc)
     * are overwritten in the TalkJS database each time they change.
     * @param settings - An optional setting of participation, can be an initial `access` right or
     * if user should be notified.
     *
     * @classic The {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API} equivalent of `setParticipant` is {@link ParticipantRef.set}:
     *
     * ```ts
     * session.conversation(convId).participant(userId).set({ notify: false });
     * ```
     */
    setParticipant(user: User, settings?: Partial<ParticipationSettings>): void;
    /**
     * Used to set certain attributes for a specific conversation
     *
     * @example Setting the conversation subject
     * ```ts
     * conversation.setAttributes({subject: "Booking question"});
     * ```
     *
     * @example Setting the `custom.sold` and `custom.itemId` properties
     * ```ts
     * conversation.setAttributes({custom:
     *   {
     *     sold: "true",
     *     itemId: "720"
     *   }
     * });
     * ```
     *
     * If the conversation has any pre-existing custom properties, they will not be removed unless you set them to null.
     *
     * @classic The {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API} equivalent of `setAttributes` is {@link ConversationRef.set}:
     *
     * ```ts
     * session.conversation(convId).set({ subject: "Booking question" });
     * ```
     */
    setAttributes(attributes: ConversationAttributes): void;
    /**
     * Sends a text message in a given conversation.
     * @param text - The message body that is to be sent.
     *
     * @classic The {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API} equivalent of `sendMessage` is {@link ConversationRef.send}:
     *
     * ```ts
     * session.conversation(convId).send("Hello");
     * ```
     *
     * It can also send formatted messages, file attachments, and map locations.
     */
    sendMessage(text: string, options?: SendMessageOptions): Promise<void>;
    /**
     * Removes the current user from this conversation.
     *
     * @returns A promise that resolves with true upon success (indicating that
     * the user has been removed from this conversation), or false when the user
     * did not have the appropriate permissions, as defined on the "Chat UI" page in the
     * TalkJS dashboard). The promise may reject in case of an unexpected error.
     *
     * @classic The {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API} equivalent of `leave` is {@link ParticipantRef.delete}:
     *
     * ```ts
     * session.conversation(convId).participant(session.currentUser).delete();
     * ```
     */
    leave(): Promise<boolean>;
}

/** @public */
export declare interface ConversationData {
    /**
     * The ID of the conversation
     */
    id: string;
    /**
     * Contains custom metadata for the conversation if it was set using {@link ConversationBuilder.custom}.
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     * When sending `custom: null` all properties and values will be removed.
     */
    custom: CustomData;
    /**
     * Contains the conversation subject if it was set using {@link ConversationBuilder.subject}.
     */
    subject: string | null;
    /**
     * Contains the URL of a photo that was set using {@link ConversationBuilder.photoUrl}.
     */
    photoUrl: string | null;
    /**
     * One or more welcome messages that will display to the user as a SystemMessage
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessages: Array<string> | null;
    /**
     * A map of the access rights for the participants in this conversation.
     *
     * This property is not guaranteed to be complete.
     * It always includes the current user, but does not always list other participants.
     *
     * Specifically, `ConversationData` returned from the following functions will only include the current user: `Session.onMessage`, `Session.onDesktopNotificationClicked`, `Session.unreads.onChange`.
     * In all other cases, this field contains every participant in the conversation.
     *
     * Note on guest access:
     * This field indicates a user's access as a participant.
     * Guests always have "ReadWrite" access and are not included in this map
     */
    participants: Record<string, {
        access: "Read" | "ReadWrite";
    }>;
}

/**
 * Passed to `Session.subscribeConversations`, specifying which conversations should be returned in the subscription.
 *
 * @remarks
 * Either a {@link SimpleConversationFilter} or a {@link CompoundFilter} OR-ing multiple simple filters together.
 *
 * @example A simple conversation filter that only includes conversations with the subject "cats!"
 * ```json
 * { subject: ["==", "cats!"] }
 * ```
 *
 * @example A compound conversation filter that includes conversations with messages, and empty conversations with the subject "cats!"
 * ```json
 * ["any", [
 *   { hasMessages: true },
 *   { subject: ["==", "cats!"] }
 * ]]
 *
 * @public
 */
export declare type ConversationFilter = SimpleConversationFilter | CompoundFilter<SimpleConversationFilter>;

/**
 * The state of a conversation list subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface ConversationListActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the conversations
     */
    readonly latestSnapshot: ConversationSnapshot[];
    /**
     * True if `latestSnapshot` contains all conversations you are in.
     * Use {@link ConversationListSubscription.loadMore} to load more.
     */
    readonly loadedAll: boolean;
}

/**
 * A subscription to your most recently active conversations.
 *
 * @remarks
 * Get a ConversationListSubscription by calling {@link Session.subscribeConversations}.
 *
 * The subscription is 'windowed'. Initially, this window contains the 20 most recent conversations.
 * Conversations are ordered by last activity. The last activity of a conversation is either `joinedAt` or `lastMessage.createdAt`, whichever is higher.
 *
 * The window will automatically expand to include any conversations you join, and any old conversations that receive new messages after subscribing.
 *
 * You can expand this window by calling {@link ConversationListSubscription.loadMore}, which extends the window further into the past.
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface ConversationListSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot` and `loadedAll`.
     *
     * - `latestSnapshot: ConversationSnapshot[]` the current state of the conversations in the window
     *
     * - `loadedAll: boolean` true when `latestSnapshot` contains all the conversations you are in
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | ConversationListActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     *
     * @remarks
     * Wait for this promise if you want to perform some action as soon as the subscription is active.
     *
     * The promise rejects if the subscription is terminated before it connects.
     */
    readonly connected: Promise<ConversationListActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Expand the window to include older conversations
     *
     * @remarks
     * The `count` parameter is relative to the current number of loaded conversations.
     * If you call `loadMore(5)` and then call `loadMore(10)` immediately afterwards (without awaiting the promise),
     * then only 10 additional conversations will be loaded, not 15.
     *
     * Avoid calling `.loadMore` in a loop until you have loaded all conversations.
     * This is usually unnecessary: any time a conversation receives a message, it appears at the start of the list of conversations.
     * If you do need to call loadMore in a loop, make sure you set a small upper bound (e.g. 100) on the number of conversations, where the loop will exit.
     *
     * @param count - The number of additional conversations to load. Must be between 1 and 30. Default 20.
     * @returns A promise that resolves once the additional conversations have loaded
     */
    loadMore(count?: number): Promise<void>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * Allows you to filter conversations down to a specific subset.
 *
 * @remarks
 * Use with {@link Inbox.setFeedFilter} or pass {@link InboxOptions.feedFilter} to
 * {@link Session.createInbox}.
 *
 * The ConversationPredicate can be either of the following:
 *
 * - a single SimpleConversationPredicate object that filters based on all the fields of the predicate
 *
 * - an array that gives you all the conversations that satisfy at least one of the SimpleConversationPredicates
 *
 * See {@link SimpleConversationPredicate} and {@link CompoundConversationPredicate} for all available options.
 *
 * @public
 */
export declare type ConversationPredicate = SimpleConversationPredicate | CompoundConversationPredicate;

/**
 * References the current user's view of the conversation with a given conversation ID.
 *
 * @remarks
 * Used in all Data API operations affecting that conversation, such as fetching or updating conversation attributes.
 * Created via {@link Session.conversation|Session.conversation()}.
 *
 * Important note: ConversationRef is a reference to *the current user's view* of the conversation.
 *
 * If they are not a participant, "their view" of the conversation does not exist.
 * This means that {@link ConversationRef.get|ConversationRef.get()} will return null.
 * Additionally, it means that {@link ConversationRef.set|set()} and {@link ConversationRef.createIfNotExists|createIfNotExists()} will add the current user as a participant, in order to create "their view" of the conversation.
 * For more details, see the documentation for those methods.
 *
 * @public
 */
export declare interface ConversationRef {
    /**
     * The ID of the referenced conversation.
     *
     * @remarks
     * Immutable: if you want to reference a different conversation, get a new ConversationRef instead.
     */
    readonly id: string;
    /**
     * Get a reference to a participant in this conversation
     *
     * @remarks
     * Note that `Participant` is not the same as `User`.
     * A `Participant` represents a user's settings related to a specific conversation.
     *
     * Calling this method multiple times with the same ID reuses the same {@link ParticipantRef} object.
     *
     * Calling {@link ConversationRef.createIfNotExists|ConversationRef.createIfNotExists} or {@link ConversationRef.set|ConversationRef.set} will automatically add the current user as a participant.
     *
     * @example To add "Alice" to the conversation "Cats"
     * ```ts
     * session.conversation("Cats").participant("Alice").createIfNotExists();
     * ```
     *
     * The user "Alice" must exist before you do this.
     *
     * @example To remove "Alice" from the conversation "Cats"
     * ```ts
     * session.conversation("Cats").participant("Alice").delete();
     * ```
     *
     * The user "Alice" will still exist after you do this. This deletes the participant, not the user.
     *
     * @param user - Specifies which participant in the conversation you want to reference. Either the user's ID, or a reference to that user.
     * @returns A {@link ParticipantRef} for that user's participation in this conversation
     * @throws If the user is not a UserRef or a non-empty string
     * @public
     */
    participant(user: string | UserRef): ParticipantRef;
    /**
     * Get a reference to a message in this conversation
     *
     * @remarks
     * Use this if you need to fetch, delete, or edit a specific message in this conversation, and you know its message ID.
     *
     * Calling this method multiple times with the same ID reuses the same {@link MessageRef} object.
     *
     * To fetch the most recent messages in this conversation, use {@link ConversationRef.subscribeMessages} instead.
     * To send a message, use {@link ConversationRef.send}.
     *
     * @param id - The ID of the message that you want to reference
     * @returns A {@link MessageRef} for the message with that ID in this conversation
     * @throws If the id is not a string or is an empty string
     * @public
     */
    message(id: string): MessageRef;
    /**
     * Fetches a snapshot of the conversation.
     *
     * @remarks
     * This contains all of the information related to the conversation and the current user's participation in the conversation.
     *
     * @returns A snapshot of the current user's view of the conversation, or null if the current user is not a participant (including if the conversation doesn't exist).
     */
    get(): Promise<ConversationSnapshot | null>;
    /**
     * Sets properties of this conversation and the current user's participation.
     *
     * @remarks
     * If this conversation does not already exist, it will be created.
     *
     * If the user is not currently a participant in this conversation, they will be added.
     *
     * @returns A promise that resolves when the operation completes.
     * When client-side conversation syncing is disabled, you must already be a participant and you cannot set anything except the `notify` property.
     * Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
     */
    set(params: SetConversationParams): Promise<void>;
    /**
     * Creates this conversation if it does not already exist.
     * Adds you as a participant in this conversation, if you are not already a participant.
     *
     * @remarks
     * If the conversation already exists or you are already a participant, this operation is still considered successful and the promise will still resolve.
     *
     * @returns A promise that resolves when the operation completes. The promise rejects if you are not already a participant and client-side conversation syncing is disabled.
     */
    createIfNotExists(params?: CreateConversationParams): Promise<void>;
    /**
     * Marks the conversation as read.
     *
     * @returns A promise that resolves when the operation completes. The promise rejects if you are not a participant in the conversation.
     */
    markAsRead(): Promise<void>;
    /**
     * Marks the conversation as unread.
     *
     * @returns A promise that resolves when the operation completes. The promise rejects if you are not a participant in the conversation.
     */
    markAsUnread(): Promise<void>;
    /**
     * Sends a message in the conversation
     *
     * @example Send a simple message with markup (bold in this example)
     * ```ts
     * conversationRef.send("*Hello*");
     * ```
     *
     * @example Reply to a message and set custom message data
     * ```ts
     * conversationRef.send({
     *   text: "Agreed",
     *   referencedMessageId: "...",
     *   custom: { priority: "HIGH" }
     * });
     * ```
     *
     * @example Send pre-formatted text with {@link TextBlock}
     * ```ts
     * conversationRef.send({
     *   content: [{
     *     type: "text",
     *     children: [{
     *       type: "bold",
     *       children: ["Hello"]
     *     }]
     *   }]
     * });
     * ```
     *
     * @example Send a file with {@link SendFileBlock}
     * ```ts
     * // `file` is a File object from `<input type="file">`
     * const fileToken = await session.uploadImage(
     *   file, { filename: file.name, width: 640, height: 480 }
     * );
     *
     * conversationRef.send({
     *   content: [{ type: "file", fileToken }]
     * });
     * ```
     *
     * @example Send a location with {@link LocationBlock}
     * ```ts
     * // You can get the user's location with the browser's geolocation API
     * const [latitude, longitude] = [42.43, -83.99];
     * conversationRef.send({
     *   content: [{ type: "location", latitude, longitude }]
     * });
     * ```
     *
     * @returns A promise that resolves with a reference to the newly created message. The promise will reject if you do not have permission to send the message.
     */
    send(params: string | SendTextMessageParams | SendMessageParams): Promise<MessageRef>;
    /**
     * Subscribes to the messages in the conversation.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called whenever the message snapshots change.
     * This includes when a message is sent, edited, deleted, and when you load more messages.
     * It also includes when nested data changes, such as when `snapshot[0].referencedMessage.sender.name` changes.
     * `loadedAll` is true when `snapshot` contains all the messages in the conversation, and false if you could load more.
     *
     * The `snapshot` list is ordered chronologically with the most recent messages at the start.
     * When a new message is received, it will be added to the start of the list.
     *
     * The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
     *
     * Initially, you will be subscribed to the 30 most recent messages and any new messages.
     * Call `loadMore` to load additional older messages. This will trigger `onSnapshot`.
     *
     * Tip: If you only care about the most recent message in the conversation, use `ConversationRef.subscribe` or `Session.subscribeConversations`.
     * Then use the `ConversationSnapshot.lastMessage` property. This is easier to use and slightly more efficient.
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     */
    subscribeMessages(onSnapshot?: (snapshot: MessageSnapshot[] | null, loadedAll: boolean) => void, options?: {
        filter?: ConversationFilter;
    }): MessageSubscription;
    /**
     * Subscribes to the participants in the conversation.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called whenever the participant snapshots change.
     * This includes when someone joins or leaves, when their participant attributes are edited, and when you load more participants.
     * It also includes when nested data changes, such as when `snapshot[0].user.name` changes.
     * `loadedAll` is true when `snapshot` contains all the participants in the conversation, and false if you could load more.
     *
     * The `snapshot` list is ordered chronologically with the participants who joined most recently at the start.
     * When someone joins the conversation, they will be added to the start of the list.
     *
     * The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
     *
     * Initially, you will be subscribed to the 10 participants who joined most recently, and any new participants.
     * Call `loadMore` to load additional older participants. This will trigger `onSnapshot`.
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     */
    subscribeParticipants(onSnapshot?: (snapshot: ParticipantSnapshot[] | null, loadedAll: boolean) => void): ParticipantSubscription;
    /**
     * Subscribes to the conversation.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called when you join or leave the conversation, or when the snapshot changes.
     * This includes changes to nested data. As an extreme example, `onSnapshot` would be called when `snapshot.lastMessage.referencedMessage.sender.name` changes.
     *
     * The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     */
    subscribe(onSnapshot?: (snapshot: ConversationSnapshot | null) => void): ConversationSubscription;
    /**
     * Subscribes to the typing status of the conversation.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called when you join or leave the conversation, or when the snapshot changes.
     * This includes changes to the nested `UserSnapshot`s. If one of the people who is typing, changes their name, `onSnapshot` will be called.
     * You will not be notified when there are already "many" people typing, and another person starts typing, because the snapshot does not change.
     *
     * The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     */
    subscribeTyping(onSnapshot?: (snapshot: TypingSnapshot | null) => void): TypingSubscription;
    /**
     * Marks the current user as typing in this conversation for 10 seconds.
     *
     * @remarks
     * This means that other users will see a typing indicator in the UI, from the current user.
     *
     * The user will automatically stop typing after 10 seconds. You cannot manually mark a user as "not typing".
     * Users are also considered "not typing" when they send a message, even if that message was sent from a different tab or using the REST API.
     *
     * To keep the typing indicator visible for longer, call this function again to reset the 10s timer.
     *
     * @example Example implementation
     * ```ts
     * let lastMarkedAsTyping = 0;
     *
     * inputElement.addEventListener("change", event => {
     *   const text = event.target.value;
     *
     *   // Deleting your draft never counts as typing
     *   if (text.length === 0) {
     *     return;
     *   }
     *
     *   const now = Date.now();
     *
     *   // Call `markAsTyping` sparingly - not on every keystroke
     *   // Only call if it has been at least 5 seconds since last time
     *   if (now - lastMarkedAsTyping > 5000) {
     *     lastMarkedAsTyping = now;
     *     convRef.markAsTyping();
     *   }
     * });
     *
     * // When you send a message, you are no longer considered typing
     * // So we need to send markAsTyping as soon as you type something
     * function onSendMessage() {
     *   lastMarkedAsTyping = 0;
     * }
     * ```
     */
    markAsTyping(): Promise<void>;
}

/**
 * Search object returned by `TalkSession.searchConversations` functions.
 * Used to search for conversations the user is in.
 * @public
 */
export declare interface ConversationSearch {
    /**
     * Sets the query string for this search and starts searching for conversations whose `subject` or `custom.search` match the query.
     *
     * @remarks
     * This resets the search to its initial state, clearing all previous results.
     * Initially loads 3 results. Call {@link MessageSearch.loadMore} to load additional results.
     *
     * The query matches a conversation when, for each word in the query, that word appears in the conversation's subject or in `conversation.custom.search`.
     * This means one of the words in the string starts with the word from the query.
     * This is case-insensitive and punctuation at the start / end of words is ignored (in both the string and the query).
     *
     * A conversation titled `I like to look at rainbows`, will appear in searches for `rainbows`, `rain`, `look at`, `(look, i *LIKE* rain)`, and `look look look!`.
     * It will not appear in searches for `bows`, `rain-bows`, `look-at`, or `I like to look at rainbows too`.
     *
     * It is not possible to match both a conversation's subject and its `custom.search` field at the same time.
     * A conversation called `Kittens` with `custom.search: "where to buy food"` will not appear in a search for `kitten food`.
     * However, this only applies per-conversation. If there is one conversation with subject `Kittens` and a second conversation with `custom.search: "Kittens"`, then a search for `kittens` will return both conversations.
     *
     * @returns A promise that resolves with the complete first page of results. The promise rejects if the search encounters an error.
     */
    setQuery(query: string): Promise<ConversationSearchState>;
    /**
     * Continues searching for more conversations.
     *
     * @remarks
     * You can only call `loadMore` when the search has a query set, and is idle.
     * Calling `loadMore` before calling `setQuery`, while the `setQuery` promise is still pending, or while another `loadMore` promise is pending, has no effect.
     *
     * @param limit - The number of results to load. `limit` should be between 1 and 50. Default 10.
     * @returns A promise that resolves once finished loading, containing all the results from this page and all previous pages. The promise rejects if the search encounters an error.
     */
    loadMore(limit?: number): Promise<ConversationSearchState>;
}

/**
 * The state of a conversation search in the current step.
 *
 * @public
 */
export declare interface ConversationSearchState {
    /**
     * The conversations that were found in the search.
     */
    results: ConversationSnapshot[];
    /**
     * Whether all results have been loaded.
     *
     * @remarks
     * Note: When true, this means that the search has reached the oldest matching conversation and no more conversations can be loaded.
     * However, it does not mean that `results` contains every matching conversation.
     * Any conversations that received messages since you called `setQuery`, may be missing from `results`.
     */
    loadedAll: boolean;
}

/** @public
 *
 * This represents the interface of the event triggered from {@link Inbox.onConversationSelected}.
 */
export declare interface ConversationSelectedEvent {
    /**
     * The current TalkJS User
     */
    me: UserSnapshot;
    /**
     * @deprecated When you are the only participant in the conversation, this property includes the current user.
     * This incorrect behavior is maintained for backwards compatibility.
     * Use `participants` and filter out the current user instead.
     *
     * The other participants in the conversation that are not the current user
     */
    others?: Array<UserSnapshot>;
    /**
     * The participants in the conversation, including the current user
     */
    participants?: Array<UserSnapshot>;
    /**
     * The current conversation object
     */
    conversation: ConversationData | null;
}

/**
 * A snapshot of a conversation's attributes at a given moment in time.
 *
 * @remarks
 * Also includes information about the current user's view of that conversation, such as whether or not notifications are enabled.
 *
 * Snapshots are immutable and we try to reuse them when possible. You should only re-render your UI when `oldSnapshot !== newSnapshot`.
 *
 * @public
 */
export declare interface ConversationSnapshot {
    /**
     * The ID of the conversation
     */
    readonly id: string;
    /**
     * Contains the conversation subject, or `null` if the conversation does not have a subject specified.
     */
    readonly subject: string | null;
    /**
     * Contains the URL of a photo to represent the topic of the conversation or `null` if the conversation does not have a photo specified.
     */
    readonly photoUrl: string | null;
    /**
     * One or more welcome messages that will be rendered at the start of this conversation as system messages.
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    readonly welcomeMessages: string[];
    /**
     * Custom metadata you have set on the conversation
     */
    readonly custom: Record<string, string>;
    /**
     * The date that the conversation was created, as a unix timestamp in milliseconds.
     */
    readonly createdAt: number;
    /**
     * The date that the current user joined the conversation, as a unix timestamp in milliseconds.
     */
    readonly joinedAt: number;
    /**
     * The last message sent in this conversation, or null if no messages have been sent.
     */
    readonly lastMessage: MessageSnapshot | null;
    /**
     * The number of messages in this conversation that the current user hasn't read.
     */
    readonly unreadMessageCount: number;
    /**
     * The most recent date that the current user read the conversation.
     *
     * @remarks
     * This value is updated whenever you read a message in a chat UI, open an email notification, or mark the conversation as read using an API like {@link ConversationRef.markAsRead}.
     *
     * Any messages sent after this timestamp are unread messages.
     */
    readonly readUntil: number;
    /**
     * Everyone in the conversation has read any messages sent on or before this date.
     *
     * @remarks
     * This is the minimum of all the participants' `readUntil` values.
     * Any messages sent on or before this timestamp should show a "read" indicator in the UI.
     *
     * This value will rarely change in very large conversations.
     * If just one person stops checking their messages, `everyoneReadUntil` will never update.
     */
    readonly everyoneReadUntil: number;
    /**
     * Whether the conversation should be considered unread.
     *
     * @remarks
     * This can be true even when `unreadMessageCount` is zero, if the user has manually marked the conversation as unread.
     */
    readonly isUnread: boolean;
    /**
     * The current user's permission level in this conversation.
     */
    readonly access: "Read" | "ReadWrite";
    /**
     * The current user's notification settings for this conversation.
     *
     * @remarks
     * `false` means no notifications, `true` means notifications for all messages, and `"MentionsOnly"` means that the user will only be notified when they are mentioned with an `@`.
     */
    readonly notify: boolean | "MentionsOnly";
}

/**
 * A subscription to a specific conversation.
 *
 * @remarks
 * Get a ConversationSubscription by calling {@link ConversationRef.subscribe}
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface ConversationSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot: ConversationSnapshot | null`, the current state of the conversation.
     * `latestSnapshot` is `null` when you are not a participant or the conversation does not exist.
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | ConversationActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     */
    readonly connected: Promise<ConversationActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * Parameters you can pass to {@link ConversationRef.createIfNotExists}.
 *
 * Properties that are `undefined` will be set to the default.
 *
 * @public
 */
export declare interface CreateConversationParams {
    /**
     * The conversation subject to display in the chat header.
     * Default = no subject, list participant names instead.
     */
    subject?: string;
    /**
     * The URL for the conversation photo to display in the chat header.
     * Default = no photo, show a placeholder image.
     */
    photoUrl?: string;
    /**
     * System messages which are sent at the beginning of a conversation.
     * Default = no messages.
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessages?: string[];
    /**
     * Custom metadata to set on the conversation.
     * Default = no custom metadata
     */
    custom?: Record<string, string>;
    /**
     * Your access to the conversation.
     * Default = "ReadWrite" access.
     */
    access?: "Read" | "ReadWrite";
    /**
     * Your notification settings.
     * Default = `true`
     */
    notify?: boolean | "MentionsOnly";
}

/**
 * Parameters you can pass to {@link ParticipantRef.createIfNotExists}.
 *
 * @remarks
 * Properties that are `undefined` will be set to the default.
 *
 * @public
 */
export declare interface CreateParticipantParams {
    /**
     * The level of access the participant should have in the conversation.
     * Default = "ReadWrite" access.
     */
    access?: "ReadWrite" | "Read";
    /**
     * When the participant should be notified about new messages in this conversation.
     * Default = `true`
     *
     * @remarks
     * `false` means no notifications, `true` means notifications for all messages, and `"MentionsOnly"` means that the user will only be notified when they are mentioned with an `@`.
     */
    notify?: boolean | "MentionsOnly";
}

/**
 * Parameters you can pass to {@link UserRef.createIfNotExists}.
 *
 * @remarks
 * Properties that are `undefined` will be set to the default.
 *
 * @public
 */
export declare interface CreateUserParams {
    /**
     * The user's name which is displayed on the TalkJS UI
     */
    name: string;
    /**
     * Custom metadata you have set on the user.
     * Default = no custom metadata
     */
    custom?: Record<string, string>;
    /**
     * An {@link https://www.w3.org/International/articles/language-tags/ | IETF language tag}.
     * See the {@link https://talkjs.com/docs/Features/Language_Support/#localization | localization documentation}
     * Default = null, will use the locale set on the dashboard
     */
    locale?: string;
    /**
     * An optional URL to a photo that is displayed as the user's avatar.
     * Default = no photo
     */
    photoUrl?: string;
    /**
     * TalkJS supports multiple sets of settings, called "roles". These allow you to change the behavior of TalkJS for different users.
     * You have full control over which user gets which configuration.
     * Default = the `default` role
     */
    role?: string;
    /**
     * The default message a person sees when starting a chat with this user.
     * Default = no welcome message
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessage?: string;
    /**
     * A single email address or an array of email addresses associated with the user.
     * Default = no email addresses
     */
    email?: string | string[];
    /**
     * A single phone number or an array of phone numbers associated with the user.
     * Default = no phone numbers
     */
    phone?: string | string[];
    /**
     * An object of push registration tokens to use when notifying this user.
     *
     * Keys in the object have the format `'provider:token_id'`,
     * where `provider` is either `"fcm"` for Android (Firebase Cloud Messaging),
     * or `"apns"` for iOS (Apple Push Notification Service).
     *
     * Default = no push registration tokens
     */
    pushTokens?: Record<string, true>;
}

/**
 * @public
 * Additional metadata stored on users, conversations and messages
 */
export declare interface CustomData {
    /**
     * Any number of key/value pairs that are stored along with the associated resource.
     *
     * @remarks
     * You can use custom data for all kinds of purposes, such as customizing a user's email notification text or transmitting contextual user data.
     *
     * Both the key and the value will be strings. Deeply nested JSON is not supported.
     *
     * @example Custom data storing `country` and `itemId`
     * ```json
     * {"country":"nl", "itemId": "720"}
     * ```
     */
    [key: string]: string;
}

/**
 * Defines a custom emoji
 *
 * @remarks
 * See {@link ChatboxOptions.customEmojis}
 *
 * @public
 */
export declare interface CustomEmojiDefinition {
    /**
     * Image file URL
     *
     * @remarks
     * Must be a fully-qualified URL of image file, eg an SVG, GIF or PNG. The
     * image must be square (same width and height) and is always scaled down to
     * the size of an emoji.
     */
    url: string;
    /**
     * Hides this emoji from the emoji picker and autocompleter
     *
     * @remarks
     * Hidden emojis can't be sent in new messages, or used in new emoji
     * reactions, but they still display properly in existing messages and
     * reactions. This lets you safely remove previously used custom emoji from
     * the chat UI.
     */
    hidden?: boolean;
}

/**
 * A node in a {@link TextBlock} that is used for {@link https://talkjs.com/docs/Features/Messages/Emojis/#custom-emojis | custom emoji}.
 *
 * @public
 */
export declare interface CustomEmojiNode {
    readonly type: "customEmoji";
    /**
     * The name (including colons at the start and end) of the custom emoji to show.
     */
    readonly text: string;
}

/**
 * @public
 * A string or a two-element array that forms a predicate about a string field in a `custom` field.
 *
 * @remarks
 * Used in {@link MessagePredicate} and {@link ConversationPredicate}.
 * Allows all forms in {@link FieldPredicate} plus the following:
 *
 * - `"exists"`
 *
 * - `"!exists"`
 */
export declare type CustomFieldPredicate = FieldPredicate<string> | "exists" | "!exists";

/**
 * @public
 * A string or a two-element array that forms a predicate about a string field in a `custom` field.
 *
 * @remarks
 * Used in {@link MessagePredicate} and {@link ConversationPredicate}.
 * Allows all forms in {@link StringFilter} plus the following:
 *
 * - `"exists"`
 *
 * - `"!exists"`
 */
export declare type CustomFilter = Record<string, StringFilter | "exists" | "!exists">;

/**
 * Sent by {@link Session.onDesktopNotificationClicked} when a user clicks on a browser notification.
 *
 * @public
 */
export declare interface DesktopNotificationClickedEvent {
    conversation: ConversationData;
}

/**
 * @public
 * This event is triggered when {@link https://talkjs.com/docs/Features/Notifications/Browser_Notifications | desktop notifications} are toggled.
 */
export declare interface DesktopNotificationToggledEvent {
    /**
     * Boolean indicating if desktop Notifications are enabled or not
     */
    isEnabled: boolean;
}

/**
 * Parameters you can pass to {@link MessageRef.edit}.
 *
 * @remarks
 * Properties that are `undefined` will not be changed.
 * To clear / reset a property to the default, pass `null`.
 *
 * This is the more advanced method for editing a message. It gives you full control over the message content.
 * You can decide exactly how a text message should be formatted, edit an attachment, or even turn a text message into a location.
 *
 * @public
 */
export declare interface EditMessageParams {
    /**
     * Custom metadata to set on the message.
     * This value acts as a patch. Remove specific properties by setting them to `null`.
     * Default = no custom metadata
     */
    custom?: Record<string, string | null> | null;
    /**
     * The new content for the message.
     *
     * @remarks
     * Any value provided here will overwrite the existing message content.
     *
     * By default users do not have permission to send {@link LinkNode}, {@link ActionLinkNode}, or {@link ActionButtonNode}, as they can be used to trick the recipient.
     */
    content?: [SendContentBlock];
}

/**
 * Parameters you can pass to {@link MessageRef.edit}.
 *
 * @remarks
 * Properties that are `undefined` will not be changed.
 * To clear / reset a property to the default, pass `null`.
 *
 * This is a simpler version of {@link EditMessageParams} that only supports setting the message content to text.
 *
 * @public
 */
export declare interface EditTextMessageParams {
    /**
     * Custom metadata to set on the message.
     * This value acts as a patch. Remove specific properties by setting them to `null`.
     * Default = no custom metadata
     */
    custom?: Record<string, string | null> | null;
    /**
     * The new text to set in the message body.
     *
     * @remarks
     * This is parsed the same way as the text entered in the message field. For example, `*hi*` will appear as `hi` in bold.
     *
     * See the {@link https://talkjs.com/docs/Features/Messages/Formatting/ | message formatting documentation} for more details.
     */
    text?: string;
}

/**
 * @public
 * A machine-readable error code enum.
 *
 * @remarks
 * Supports the following values:
 *
 * - `NOTIFICATIONS_PERMISSION_DENIED`
 *
 * - `NOTIFICATIONS_NOT_SUPPORTED`
 *
 * - `ARGUMENT_INVALID`
 */
export declare enum ErrorCode {
    NOTIFICATIONS_PERMISSION_DENIED = 0,
    NOTIFICATIONS_NOT_SUPPORTED = 1,
    ARGUMENT_INVALID = 2
}

/**
 * The state of a subscription after it encounters an unrecoverable error
 *
 * @public
 */
export declare interface ErrorState {
    readonly type: "error";
    /**
     * The error that caused the subscription to be terminated
     */
    readonly error: Error;
}

/**
 * The {@link TypingSnapshot} variant used when only a few people are typing.
 */
export declare interface FewTypingSnapshot {
    /**
     * Check this to differentiate between FewTypingSnapshot (`false`) and ManyTypingSnapshot (`true`).
     *
     * @remarks
     * When `false`, you can see the list of users who are typing in the `users` property.
     */
    readonly many: false;
    /**
     * The users who are currently typing in this conversation.
     *
     * @remarks
     * The list is in chronological order, starting with the users who have been typing the longest.
     * The current user is never contained in the list, only other users.
     */
    readonly users: UserSnapshot[];
}

/**
 * @public
 * A two-element array that forms a predicate about a field.
 *
 * @remarks
 * Used in {@link MessagePredicate} and {@link ConversationPredicate}.
 * Possible forms:
 *
 * - `["==", "someValue"]`
 *
 * - `["!=", "someValue"]`
 *
 * - `["oneOf", ["someValue", "someOtherValue"]]`
 *
 * - `["!oneOf", ["someValue", "someOtherValue"]]`
 */
export declare type FieldPredicate<T> = ["==" | "!=", T] | ["oneOf" | "!oneOf", T[]];

/**
 * A file attachment received in a message's content.
 *
 * @remarks
 * All `FileBlock` variants contain `url`, `size`, and `fileToken`.
 * Some file blocks have additional metadata, in which case they will have the `subtype` property set.
 *
 * Currently the available FileBlock subtypes are:
 *
 * - No `subtype` set ({@link GenericFileBlock})
 *
 * - `subtype: "video"` ({@link VideoBlock})
 *
 * - `subtype: "image"` ({@link ImageBlock})
 *
 * - `subtype: "audio"` ({@link AudioBlock})
 *
 * - `subtype: "voice"` ({@link VoiceBlock})
 *
 * @public
 */
export declare type FileBlock = VideoBlock | ImageBlock | AudioBlock | VoiceBlock | GenericFileBlock;

/**
 * A token representing a file uploaded to TalkJS.
 *
 * @remarks
 * You cannot create a FileToken yourself. Get a file token by uploading your file to TalkJS with {@link Session.uploadFile}, or one of the subtype-specific variants like {@link Session.uploadImage}.
 * Alternatively, take a file token from an existing {@link FileBlock} to re-send an attachment you received, without having to download and re-upload the file.
 * You can also upload files using the {@link https://talkjs.com/docs/REST_API/Messages/#1-upload-a-file| REST API}.
 * This system ensures that all files must be uploaded to TalkJS before being sent to users, limiting the risk of malware.
 *
 * Passed in {@link SendFileBlock} when you send a message containing a file attachment.
 *
 * We may change the FileToken format in the future.
 * Do not store old file tokens for future use, as these may stop working.
 *
 * @example Using a file input
 * ```ts
 * // From `<input type="file">`
 * const file: File = fileInputElement.files[0];
 * const myFileToken = await session.uploadFile(file, { filename: file.name });
 *
 * const block = {
 *   type: 'file',
 *   fileToken: myFileToken,
 * };
 * session.conversation('example_conversation_id').send({ content: [block] });
 * ```
 *
 * @example Re-sending a file from a previous message
 * ```ts
 * session.conversation('example_conversation_id').send({
 *   content: previousMessageSnapshot.content
 * });
 * ```
 *
 * @public
 */
export declare type FileToken = string & {
    readonly __tag: Record<"TalkJS Encoded File Token", true>;
};

/**
 * @public
 * @hidden due to being empty
 * @deprecated Use `chatbox.onFocus(() => {...})` instead, without an event parameter.
 */
declare interface FocusEvent_2 {
}
export { FocusEvent_2 as FocusEvent }

/**
 *  @public
 */
export declare interface FullStoryOptions {
    /**
     * Fullstory hostname
     */
    host?: string;
    /**
     * Fullstory organization ID
     */
    org: string;
}

/**
 * The most basic FileBlock variant, used whenever there is no additional metadata for a file.
 *
 * @remarks
 * Do not try to check for `subtype === undefined` directly, as this will break when we add new FileBlock variants in the future.
 *
 * Instead, treat GenericFileBlock as the default. For example:
 *
 * ```ts
 * if (block.subtype === "video") {
 *     handleVideoBlock(block);
 * } else if (block.subtype === "image") {
 *     handleImageBlock(block);
 * } else if (block.subtype === "audio") {
 *     handleAudioBlock(block);
 * } else if (block.subtype === "voice") {
 *     handleVoiceBlock(block);
 * } else {
 *     handleGenericFileBlock(block);
 * }
 * ```
 *
 * @public
 */
export declare interface GenericFileBlock {
    readonly type: "file";
    /**
     * Never set for generic file blocks.
     */
    readonly subtype?: never;
    /**
     * An encoded identifier for this file. Use in {@link SendFileBlock} to send this file in another message.
     */
    readonly fileToken: FileToken;
    /**
     * The URL where you can fetch the file
     */
    readonly url: string;
    /**
     * The size of the file in bytes
     */
    readonly size: number;
    /**
     * The name of the file, including file extension
     */
    readonly filename: string;
}

/**
 * @public
 */
export declare interface GenericFileMetadata {
    /**
     * The name of the file including extension.
     */
    filename: string;
}

/**
 * @public
 * @hidden
 * @deprecated Use {@link ConversationRef} via {@link Session.conversation|Session.conversation()} instead
 */
export declare interface GetOrStartOptionsA {
    /**
     * A human-readable subject
     * of the conversation. Supports formatted links in a Markdown-style syntax, e.g.
     * `Beautiful <https://yoursite.com/booking/18644|home by the sea>!`.
     * URLs and email addresses are made clickable, and emojis made to work
     * cross-platform.
     */
    subject?: string;
    /**
     * Additional parameter to store the custom fields, that you
     * want to use in the email template. E.g. `custom.specialToken`
     */
    custom?: {
        [name: string]: string;
    };
    /**
     * Photo to be used for this conversation in the TalkJS UI.
     */
    photoUrl?: string;
    welcomeMessages?: string[];
}

/**
 * @public
 * @hidden
 * @deprecated Use {@link ConversationRef} via {@link Session.conversation|Session.conversation()} instead
 */
export declare interface GetOrStartOptionsB {
    participants: Array<User>;
    /**
     * A human-readable subject
     * of the conversation. Supports formatted links in a Markdown-style syntax, e.g.
     * `Beautiful <https://yoursite.com/booking/18644|home by the sea>!`.
     * URLs and email addresses are made clickable, and emojis made to work
     * cross-platform.
     */
    subject?: string;
    /**
     * Additional parameter to store the custom fields, that you
     * want to use in the email template. E.g. `custom.specialToken`
     */
    custom?: {
        [name: string]: string;
    };
    /**
     * Photo to be used for this conversation in the TalkJS UI.
     */
    photoUrl?: string;
}

/**
 * Lets you jump the chat scroll position between highlighted words
 *
 * @remarks
 * These methods do the same as when the user clicks on the "up" and "down" icons in the conversation search box.
 *
 * Returned from {@link Chatbox.setHighlightedWords}
 * @public
 */
export declare interface HighlightControls {
    /**
     * Jump to the previous highlighted word.
     */
    jumpUp(): Promise<HighlightResult>;
    /**
     * Jump to the next highlighted word.
     */
    jumpDown(): Promise<HighlightResult>;
}

/**
 * @public
 *
 * @remarks
 * See {@link HighlightControls} and {@link Chatbox.setHighlightedWords}
 */
export declare interface HighlightResult {
    /**
     * True when a next result was found
     */
    found: boolean;
    /**
     * True when a next result was found, and it's the last result (in this direction)
     */
    isLast: boolean;
}

/**
 * HTML Panel
 * HTML panels should only be created through {@link Inbox.createHtmlPanel}, {@link Chatbox.createHtmlPanel} or {@link Popup.createHtmlPanel}.
 * @public
 */
export declare interface HtmlPanel {
    /**
     * Shows the panel if it's hidden.
     */
    show(): void;
    /**
     * Hides the panel if it's visible.
     */
    hide(): void;
    /**
     * Changes the panel height.
     *
     * @remarks
     * If you don't need to change the height after the panel is created, you can pass it as an option to the `createHtmlPanel`.
     */
    setHeight(height: number): void;
    /**
     * Returns `true` if the panel is visible, `false` if it's hidden or destroyed
     */
    isVisible(): boolean;
    /**
     * Destroys the HTML panel
     */
    destroy(): Promise<void>;
    /**
     * The HTML Panel iframe's {@link https://developer.mozilla.org/en-US/docs/Web/API/Window | window} object
     */
    window: Window;
    /**
     * This promise resolves when the "DOMContentLoaded" event fires on the iframe's window.
     */
    DOMContentLoadedPromise: Promise<void>;
    /**
     * This promise resolves when the "load" event fires on the iframe's window.
     */
    windowLoadedPromise: Promise<void>;
}

/** @public */
export declare interface HtmlPanelOptions {
    /**
     * Required. URL you want to load inside the HTML panel.
     * Url can be absolute ("https://www.example.com/register-form.html") or relative ("register-form.html").
     * We recommend using same origin pages to have better control of the page.
     * Learn more about HTML Panels and same origin pages {@link https://talkjs.com/docs/Guides/JavaScript/Classic/HTML_Panels/ | here}.
     */
    url: string;
    /**
     * Optional, defaults to 100 (px).
     */
    height?: number;
    /**
     * Optional, defaults to true. Set false if you don't want the HTML panel to be shown after
     * `createHtmlPanel` is called. You can change the visibility of the HTML panels by
     * calling `.hide()` or `.show()` on the `HtmlPanel` instance returned by `createHtmlPanel`'s promise.
     */
    show?: boolean;
    /**
     * Either a `Conversation` object
     * (as returned from `getOrCreateConversation`) or the `id` field of
     * a conversation (which you may have stored in your database).
     * If given, the HTML panel called will only show up for that conversation.
     */
    conversation?: Conversation | ConversationBuilder | string;
}

/**
 * A FileBlock variant for an image attachment, with additional image-specific metadata.
 *
 * @remarks
 * You can identify this variant by checking for `subtype: "image"`.
 *
 * Includes metadata about the height and width of the image in pixels, where available.
 *
 * Images that you upload with the TalkJS UI will include the image dimensions as long as the sender's browser can preview the file.
 * Images that you upload with the REST API or {@link Session.uploadImage} will include the dimensions if you specified them when uploading.
 * Image attached in a reply to an email notification will not include the dimensions.
 *
 * @public
 */
export declare interface ImageBlock {
    readonly type: "file";
    readonly subtype: "image";
    /**
     * An encoded identifier for this file. Use in {@link SendFileBlock} to send this image in another message.
     */
    readonly fileToken: FileToken;
    /**
     * The URL where you can fetch the file.
     */
    readonly url: string;
    /**
     * The size of the file in bytes.
     */
    readonly size: number;
    /**
     * The name of the image file, including file extension.
     */
    readonly filename: string;
    /**
     * The width of the image in pixels, if known.
     */
    readonly width?: number;
    /**
     * The height of the image in pixels, if known.
     */
    readonly height?: number;
}

/**
 * @public
 */
export declare interface ImageFileMetadata {
    /**
     * The name of the file including extension.
     */
    filename: string;
    /**
     * The width of the image in pixels, if known.
     */
    width?: number;
    /**
     * The height of the image in pixels, if known.
     */
    height?: number;
}

/**
 * The main messaging UI. Chats on the left, messages on the right.
 * Create an Inbox through {@link Session.createInbox} and then call {@link Inbox.mount} to show it.
 * @public
 */
export declare interface Inbox extends UIBox {
    /**
     * The conversation currently shown in the UI.
     *
     * @remarks
     * This field is `null` when the UI does not currently show a conversation (eg
     * because `null` was passed to {@link UIBox.select}, it's an Inbox with only
     * conversation list visible, or the selected conversation could not be
     * found).
     *
     * This field will always be equal to
     * {@link ConversationSelectedEvent.conversation | conversation} in the
     * {@link Inbox.onConversationSelected} event.
     *
     * Also note that because the {@link Inbox.onSelectConversation} event is
     * emitted before the new conversation is actually shown, this field will
     * still reflect the previous conversation at that point.
     */
    readonly currentConversation: ConversationData | null;
    /**
     * Controls which conversations are shown in the conversation feed
     *
     * @remarks
     * Lets you filter conversations in the conversation list, depending on access level, custom
     * conversation attributes or message read status.
     *
     * See {@link ConversationPredicate} for all available options.
     *
     * You can also set the filter in {@link Session.createInbox} using
     * {@link InboxOptions.feedFilter}.
     *
     * @param filter - A predicate object that controls which conversations are shown.
     */
    setFeedFilter(filter: ConversationPredicate): void;
    /**
     * Renders the Inbox UI inside a DOM element on your page
     *
     * @remarks
     * The container element specified by `container` must either be a DOM Element (as returned by e.g.
     * `document.getElementById`) or a JQuery object with a single element.
     */
    mount(container: HTMLElement | null): Promise<void>;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "selectConversation", handler: (event: SelectConversationEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "conversationSelected", handler: (event: ConversationSelectedEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "desktopNotificationToggled", handler: (event: DesktopNotificationToggledEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "sendMessage", handler: (event: SendMessageEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "focus", handler: () => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "blur", handler: () => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "translationToggled", handler: (event: TranslationToggledEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Inbox} instead.
     */
    on(eventType: "keyup", handler: (event: KeyEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "selectConversation", handler: (event: SelectConversationEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "conversationSelected", handler: (event: ConversationSelectedEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "desktopNotificationToggled", handler: (event: DesktopNotificationToggledEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "focus", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "blur", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "sendMessage", handler: (event: SendMessageEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "translationToggled", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Inbox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Inbox} `onXyz` instead.
     */
    off(eventType: "keyup", handler: (event: KeyEvent) => void): void;
    /**
     * Triggers when a user clicks a conversation in the conversation list.
     *
     * @remarks
     * This event is triggered *before* a conversation is selected.
     * You can prevent the conversation from being actually selected by calling `event.preventDefault()`.
     */
    onSelectConversation(handler: (event: SelectConversationEvent) => void): Subscription;
    /**
     * Triggers after a conversation is selected
     *
     * @remarks
     * This event is emitted in 4 situations:
     *
     * 1. When the Inbox loads;
     *
     * 2. When the user clicks on a conversation in the feed;
     *
     * 3. When something in your code calls {@link Inbox.select}
     *
     * 4. When the Inbox is shown in mobile view, and the user clicks the `< Inbox` button.
     *
     * Note that the event's `conversation` field will be `null` when the inbox loads (and the user
     * has no conversations), when calling {@link Inbox.select} with `null` to deselect any
     * conversation, and in case 4 above.
     */
    onConversationSelected(handler: (event: ConversationSelectedEvent) => void): Subscription;
    /**
     * Triggers when the user toggles the "Desktop Notifications" toggle in the inbox conversation list header.
     */
    onDesktopNotificationToggled(handler: (event: DesktopNotificationToggledEvent) => void): Subscription;
    /**
     * Destroys the inbox and removes it from the DOM
     *
     * @remarks
     * Destroys the inbox, removes it from the DOM and removes all event listeners it has running. Call this before removing
     * the inbox container from the DOM.
     */
    destroy(): void;
}

/**
 * @alias UIBox Inbox
 * @public
 */
export declare interface InboxOptions extends ChatboxOptions {
    /**
     * Makes the inbox start up with the given Conversation. Can be passed a value of the type ConversationBuilder (returned by getOrCreateConversation) or the string value of the conversation id. Conversation can be deselected on startup by passing a null value. Passing undefined means that the last conversation (or "no chats yet page") will be displayed.
     *
     * @deprecated Please use {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Inbox/#Inbox__select | Inbox.select} instead.
     */
    selected?: Conversation | ConversationBuilder | string | null;
    /**
     * Controls if the feed header containing the toggle to enable desktop notifications is shown.
     * Defaults to true.
     */
    showFeedHeader?: boolean;
    /**
     * Controls how a chat is displayed in the feed of chats.
     *
     * Note: when set to `"subject"` but a conversation has no subject set, then
     * TalkJS falls back to `"participants"`.
     *
     * When not set, defaults to `"auto"`, which means that in group conversations
     * that have a subject set, the subject is displayed and otherwise the participants.
     *
     * (also see {@link ChatboxOptions.chatSubtitleMode} and {@link ChatboxOptions.chatTitleMode})
     *
     * @deprecated This field only has effect if you use a {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Themes/Legacy_Themes/ | Legacy Theme }, or an older custom theme which does not have a ConversationListItem component. If you do not, edit the ChatHeader component in the theme editor instead.
     */
    feedConversationTitleMode?: "participants" | "subject" | "auto";
    /**
     * Controls whether the user navigating between conversation should count
     * as steps in the browser history. Defaults to true, which means that if the user
     * clicks the browser's back button, they go back to the previous conversation
     * (if any).
     */
    useBrowserHistory?: boolean;
    /**
     * Used to control which conversations are shown in the conversation feed, depending on access
     * level, custom conversation attributes or message read status.
     *
     * The feedFilter can be either of the following:
     * - a single ConversationPredicate object that filters based on all the fields
     * of the predicate
     * - an array that gives you all the conversations that satisfy at least one
     * of the ConversationPredicates
     *
     * When filtering conversations with an array, the first element must be the string
     * "any", and the second element a list of ConversationPredicate objects.
     *
     * See {@link ConversationPredicate} for all available options.
     *
     * You can also modify the filter on the fly using {@link Inbox.setFeedFilter}.
     *
     * @example Match conversations if you have write access or if their custom `accountId` property is `"my_account"`
     * ```json
     * ["any", [{ access: ["==", "ReadWrite"] }, { custom: { accountId: ["==", "my_account"] } }]]
     * ```
     */
    feedFilter?: ConversationPredicate;
    /**
     * Whether to show a "Back" button at the top of the chat screen on mobile devices.
     */
    showMobileBackButton?: boolean;
}

/**
 * @public
 * @hidden
 * Anything that can be JSON-serialised.
 */
export declare type JsonSerializable = string | number | boolean | null | JsonSerializableObject | JsonSerializableArray;

/**
 * @public
 * @hidden
 */
export declare interface JsonSerializableArray extends Array<JsonSerializable> {
}

/**
 * @public
 * @hidden
 */
export declare interface JsonSerializableObject {
    [key: string]: JsonSerializable;
}

/**
 * @public
 * Emitted through {@link Chatbox.onKeyup} when the user presses a key.
 * All fields except `isInputFocused` precisely match the corresponding fields in the browser's
 * {@link https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent | KeyboardEvent}.
 */
declare interface KeyEvent {
    /**
     * True if the event was triggered while an element was focused that can handle keyboard events.
     */
    isInputFocused: boolean;
    altKey: boolean;
    code: string;
    ctrlKey: boolean;
    key: string;
    location: number;
    metaKey: boolean;
    shiftKey: boolean;
    repeat: boolean;
}
export { KeyEvent }
export { KeyEvent as KeyupEvent }

/**
 * @public
 * Triggered when the user clicks a "Leave conversation" action in the chat UI.
 *
 * @see {@link Chatbox.onLeaveConversation}
 */
export declare interface LeaveConversationEvent {
    /**
     * The conversation that the user intends to leave
     */
    conversation: ConversationData;
    /**
     * Call this to prevent the conversation from being left, ie to cancel the
     * user action.
     *
     * @remarks
     * Doing this will turn the "Leave conversation" action into a no-op, so you
     * might want to display some sort of error message to the user so they
     * understand why their click didn't do anything.
     *
     * You can only call `preventDefault` from inside the `onLeaveConversation`
     * event handler or a function immediately invoked from it. Calling
     * `preventDefault` later, or after some promise resolved, has no effect.
     */
    preventDefault(): void;
}

/**
 * A node in a {@link TextBlock} that renders its children as a clickable link (HTML `<a>`).
 *
 * @remarks
 * By default, users do not have permission to send messages containing `LinkNode` as it can be used to maliciously hide the true destination of a link.
 *
 * @public
 */
export declare interface LinkNode {
    readonly type: "link";
    /**
     * The URL to open when the node is clicked.
     */
    readonly url: string;
    readonly children: TextNode[];
}

/**
 * A block showing a location in the world, typically because a user shared their location in the chat.
 *
 * @remarks
 * In the TalkJS UI, location blocks are rendered as a link to Google Maps, with the map pin showing at the specified coordinate.
 * A thumbnail shows the surrounding area on the map.
 *
 * @public
 */
export declare interface LocationBlock {
    readonly type: "location";
    /**
     * The north-south coordinate of the location.
     *
     * @remarks
     * Usually listed first in a pair of coordinates.
     *
     * Must be a number between -90 and 90
     */
    readonly latitude: number;
    /**
     * The east-west coordinate of the location.
     *
     * @remarks
     * Usually listed second in a pair of coordinates.
     *
     * Must be a number between -180 and 180
     */
    readonly longitude: number;
}

/**
 * The {@link TypingSnapshot} variant used when many people are typing.
 */
export declare interface ManyTypingSnapshot {
    /**
     * Check this to differentiate between FewTypingSnapshot (`false`) and ManyTypingSnapshot (`true`).
     *
     * @remarks
     * When `true`, you do not receive a list of users who are typing.
     * You should show a message like "several people are typing" instead.
     */
    readonly many: true;
}

/**
 * @public
 * Triggered when the user clicks a "Mark as unread" action in the chat UI.
 *
 * @see {@link Chatbox.onMarkConversationAsUnread}
 */
export declare interface MarkConversationAsUnreadEvent {
    /**
     * The conversation that the user intends to mark as unread
     */
    conversation: ConversationData;
    /**
     * Call this to prevent the conversation from being marked as unread, ie to
     * cancel the user action.
     *
     * @remarks
     * Doing this will turn the "Mark as unread" action into a no-op, so you might
     * want to display some sort of error message to the user so they understand
     * why their click didn't do anything.
     *
     * You can only call `preventDefault` from inside the
     * `onMarkConversationAsUnread` event handler or a function immediately
     * invoked from it. Calling `preventDefault` later, or after some promise
     * resolved, has no effect.
     */
    preventDefault(): void;
}

/**
 * A node in a {@link TextBlock} that renders its children with a specific style.
 *
 * @public
 */
export declare interface MarkupNode {
    /**
     * The kind of formatting to apply when rendering the children
     *
     * - `type: "bold"` is used when users type `*text*` and is rendered with HTML `<strong>`
     *
     * - `type: "italic"` is used when users type `_text_` and is rendered with HTML `<em>`
     *
     * - `type: "strikethrough"` is used when users type `~text~` and is rendered with HTML `<s>`
     */
    readonly type: "bold" | "italic" | "strikethrough";
    readonly children: TextNode[];
}

/**
 * A node in a {@link TextBlock} that is used when a user is {@link https://talkjs.com/docs/Features/Messages/Mentions/ | mentioned}.
 *
 * @remarks
 * Used when a user types `@name` and selects the user they want to mention.
 *
 * @public
 */
export declare interface MentionNode {
    readonly type: "mention";
    /**
     * The ID of the user who is mentioned.
     */
    readonly id: string;
    /**
     * The name of the user who is mentioned.
     */
    readonly text: string;
}

/**
 * @public
 * A TalkJS message, used as part of {@link Session.onMessage}
 */
export declare interface Message {
    /**
     * The message's ID.
     */
    id: string;
    /**
     * Contains the {@link ConversationData} that the message belongs to.
     */
    conversation: ConversationData;
    /**
     * 'true' if the message was sent by the current user.
     */
    isByMe: boolean;
    /**
     * The senderID (userID) for the person that sent the message
     */
    senderId: string | null;
    /**
     * The {@link User} that sent the message
     */
    sender: UserSnapshot | null;
    /**
     * Contains the message's content
     */
    body: string;
    /**
     * Specifies if if the message is media (file), text or a shared location
     */
    type: "media" | "text" | "location";
    /**
     * UNIX timestamp specifying when the message was sent (UTC, in milliseconds)
     */
    timestamp: number;
    /**
     * 'true' if the message has been read, 'false' has not been seen yet
     */
    read: boolean;
    /**
     * Specifies how this message was created.
     *
     * - "web" = Message sent using a classic SDK UI or via {@link ConversationBuilder.sendMessage}
     *
     * - "rest" = Message sent via one of the new UI components, the Data API, or the REST API "send message" endpoint
     *
     * - "import" = Message sent via the admin REST API's "import messages" endpoint
     *
     * - "email" = Message sent as a reply to an email notification
     *
     * To track more detailed information about where a message comes from, such as browser vs mobile app, use message custom data.
     *
     * The "rest" and "web" values are confusingly named. This is for historical reasons and to maintain backwards compatibility.
     */
    origin: "web" | "rest" | "import" | "email";
    /**
     * Custom metadata that is stored with the conversation
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom: CustomData;
    /**
     * Only given if the message's `type` equals `"media"`. An object with the URL and filesize (in bytes) of the given file. Attachment dimensions (in px) are sometimes available for media file attachments, used to set the size of the thumbnail before loading, to prevent content shift when loading media on slower connections.
     */
    attachment: Attachment | null;
    /**
     * Only given if the message's `type` equals `"location"`.
     * An array of two numbers which represent the longitude and latitude of this location, respectively.
     * Only given if this message is a shared location.
     * For example, `[51.481083, -3.178306]`.
     */
    location: [number, number] | null;
}

/**
 * @public
 * Emitted from {@link Chatbox.onCustomMessageAction} when a user clicks on a
 * custom action, as defined on the "Chat UI" page of the dashboard.
 */
export declare interface MessageActionEvent {
    action: string;
    params: ActionEventParams;
    message: Message;
}

/**
 * The state of a messages subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface MessageActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the messages, or `null` if you're not a participant in the conversation.
     */
    readonly latestSnapshot: MessageSnapshot[] | null;
    /**
     * True if `latestSnapshot` contains all messages in the conversation.
     * Use {@link MessageSubscription.loadMore} to load more.
     */
    readonly loadedAll: boolean;
}

/**
 * Encapsulates the message entry field tied to the currently selected conversation.
 * @public
 */
export declare interface MessageField {
    /**
     * Focuses the message entry field.
     *
     * @remarks
     * Note that on mobile devices, this will cause the on-screen keyboard to pop up, obscuring part
     * of the screen.
     *
     * This method will silently fail if the participant only has "Read" access in the
     * current conversation.
     */
    focus(): void;
    /**
     * Sets the message field to `text`.
     *
     * @remarks
     * Useful if you want to guide your user with message suggestions. If you want to start a UI
     * with a given text showing immediately, call this method before calling {@link Inbox.mount}
     *
     * This method will silently fail if the participant only has "Read" access in the
     * current conversation.
     *
     * @param text - The text to be displayed in the message entry field
     */
    setText(text: string): void;
    /**
     * Types the given `text` into the message field.
     *
     * @remarks
     * Inserts `text` wherever the cursor currently is.
     *
     * This method may be useful for various bot/simulation scenarios. Additionally, it lets you make
     * it so that any regular keypress lets the user start typing into the message field, even if it
     * is not focused.
     *
     * This method will silently fail if the participant only has "Read" access in the
     * current conversation.
     *
     * To do that, capture the keypress using a regular window event listener, ensure that the user
     * isn't typing into a different input, and then call this method to type the key, followed by
     * {@link MessageField.focus}. Note that TalkJS already does this out-of-the box when the chat UI
     * iframe has focus and {@link ChatboxOptions.captureKeyboardEvents} is off.
     *
     * @param text - The text to be inserted in the message entry field
     */
    typeText(text: string): void;
    /**
     * Gets the current content of the message field.
     */
    getText(): Promise<string>;
    /**
     * Sets the visibility of the Message Field to a given value or to a certain predicate.
     *
     * @remarks
     * See {@link MessageFieldOptions.visible} for examples.
     *
     * @param visible - boolean or a more advanced predicate.
     */
    setVisible(visible: boolean | ConversationPredicate): void;
}

/**
 * @public
 */
export declare interface MessageFieldOptions {
    /**
     * If set to `true`, pressing the enter key sends the message (if there is text in the message
     * field). When set to `false`, the only way to send a message is by clicking or touching the
     * "Send" button. Defaults to `true`.
     */
    enterSendsMessage?: boolean;
    /**
     * Specifies whether the
     * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attr-spellcheck | spellcheck}
     * attribute is set on the message field. Note that setting this to `true` may also enable
     * autocorrect on some mobile devices. Defaults to `false`.
     */
    spellcheck?: boolean;
    /**
     * Overrides the placeholder text that is displayed in the message field when no text has yet been entered.
     *
     * Defaults to "Say something..." (or a {@link https://talkjs.com/docs/Features/Language_Support/#localization | translation thereof}).
     */
    placeholder?: string;
    /**
     * Determines whether the message field is visible. Pass either a boolean (`false` to hide it),
     * or a {@link ConversationPredicate}. The latter approach lets you show/hide the message field
     * based on properties of the current conversation.
     *
     * Defaults to `true`.
     *
     * @example To hide the message field when the user does not have write access to the conversation
     * ```ts
     * // true only if the user's `access` in this conversation is `"ReadWrite"`
     * const showMessageField = { access: ["==", "ReadWrite"] };
     * session.createInbox(conversation, { messageField: { visible: showMessageField } });
     * ```
     */
    visible?: boolean | ConversationPredicate;
    /**
     * Determines whether the message field should automatically focus when the user navigates.
     *
     * The default option is `"smart"`, which means that focus is switched to the message field
     * whenever a conversation is selected, if it is possible to do this without negative side effects.
     * This is possible when:
     *
     * - The message field is inside the browser viewport (so focusing will not unexpectedly cause
     *   the page to scroll)
     *
     * - The user is likely on a desktop/laptop computer (so focusing will not unexpectedly expand a
     *   mobile on-screen keyboard).
     *
     * Note: If you need more control, consider setting `autofocus` to false and calling
     * {@link MessageField.focus} at appropriate times.
     */
    autofocus?: false | "smart";
}

/**
 * Lets you show only specific messages in the chat panel of a Chatbox, Inbox or Popup.
 *
 * @remarks
 * Used in methods like {@link Chatbox.setMessageFilter}.
 *
 * The MessagePredicate can be either of the following:
 *
 * - a single SimpleMessagePredicate object that filters based on all the fields of the predicate
 *
 * - an array that gives you all the messages that satisfy at least one of the SimpleMessagePredicates
 *
 * See {@link SimpleMessagePredicate} and {@link CompoundMessagePredicate} for all available options.
 *
 * @public
 */
export declare type MessagePredicate = SimpleMessagePredicate | CompoundMessagePredicate;

/**
 * References the message with a given message ID.
 *
 * @remarks
 * Used in all Data API operations affecting that message, such as fetching or editing the message attributes, or deleting the message.
 * Created via {@link ConversationRef.message} and {@link ConversationRef.send}.
 *
 * @public
 */
export declare interface MessageRef {
    /**
     * The ID of the referenced message.
     *
     * @remarks
     * Immutable: if you want to reference a different message, get a new MessageRef instead.
     */
    readonly id: string;
    /**
     * The ID of the conversation that the referenced message belongs to.
     *
     * @remarks
     * Immutable: if you want to reference a message from a different conversation, get a new MessageRef from that conversation.
     */
    readonly conversationId: string;
    /**
     * Get a reference to a specific emoji reaction on this message
     *
     * @remarks
     * If you call `.reactions` with an invalid emoji, it will still succeed and you will still get a `ReactionRef`.
     * However, the TalkJS server will reject any calls that use an invalid emoji.
     *
     * Calling this method multiple times with the same emoji reuses the same {@link ReactionsRef} object.
     *
     * @example Reacting to the message with a Unicode emoji
     * ```ts
     * MessageRef.reactions("🚀").add()
     * ```
     *
     * @example Removing your custom emoji reaction from the message
     * ```ts
     * MessageRef.reactions(":cat-roomba:").remove()
     * ```
     *
     * @example Subscribing to the list of users who reacted with a specific emoji
     * ```ts
     * MessageRef.reactions("🚀").subscribe(snapshots => console.log(snapshots))
     * ```
     *
     * @param emoji - The emoji for the reaction you want to reference. a single Unicode emoji like "🚀" or a custom emoji like ":cat_roomba:". Custom emoji can be up to 50 characters long.
     * @returns A {@link ReactionsRef} for the reactions with that emoji on this message
     * @throws If the emoji is not a string or is an empty string
     * @public
     */
    reactions(emoji: string): ReactionsRef;
    /**
     * Get a reference to a specific emoji reaction on this message
     *
     * @deprecated This has been renamed to {@link MessageRef.reactions}. For back-compat, this method will continue to be available as an alias.
     */
    reaction(emoji: string): ReactionsRef;
    /**
     * Fetches a snapshot of the message.
     *
     * @returns A snapshot of the message's attributes, or null if the message doesn't exist, the conversation doesn't exist, or you're not a participant in the conversation.
     */
    get(): Promise<MessageSnapshot | null>;
    /**
     * Edits this message.
     *
     * @returns A promise that resolves when the operation completes. The promise will reject if the request is invalid, the message doesn't exist, or you do not have permission to edit that message.
     */
    edit(params: string | EditTextMessageParams | EditMessageParams): Promise<void>;
    /**
     * Deletes this message, or does nothing if the message does not exist.
     *
     * @remarks
     * Deleting a nonexistent message is treated as success, and the promise will resolve.
     *
     * @returns A promise that resolves when the operation completes. This promise will reject if you are not a participant in the conversation or if your role does not give you permission to delete this message.
     */
    delete(): Promise<void>;
}

/**
 * Search object returned by `TalkSession.searchMessages`.
 * Used to search for messages in the current user's conversations.
 *
 * @public
 */
export declare interface MessageSearch {
    /**
     * Sets the query string for this search and starts searching for messages matching the query.
     *
     * @remarks
     * This resets the search to its initial state, clearing all previous results.
     * Initially loads 3 results. Call {@link MessageSearch.loadMore} to load additional results.
     *
     * The query matches a message when, for each word in the query, that word appears in the message text.
     * This means one of the words in the string starts with the word from the query.
     * This is case-insensitive and punctuation at the start / end of words is ignored (in both the string and the query).
     *
     * Non-text messages (such as uploaded images) are never returned by search.
     *
     * A message saying `I like to look at rainbows`, will appear in searches for `rainbows`, `rain`, `look at`, `(look, i *LIKE* rain)`, and `look look look!`.
     * It will not appear in searches for `bows`, `rain-bows`, `look-at`, or `I like to look at rainbows too`.
     *
     * @returns A promise that resolves with the complete first page of results. The promise rejects if the search encounters an error.
     */
    setQuery(query: string): Promise<MessageSearchState>;
    /**
     * Continues searching for more messages.
     *
     * @remarks
     * You can only call `loadMore` when the search has a query set, and is idle.
     * Calling `loadMore` before calling `setQuery`, while the `setQuery` promise is still pending, or while another `loadMore` promise is pending, has no effect.
     *
     * @param limit - The number of results to load. `limit` should be between 1 and 50. Default 10.
     * @returns A promise that resolves once finished loading, containing all the results from this page and all previous pages. The promise rejects if the search encounters an error.
     */
    loadMore(limit?: number): Promise<MessageSearchState>;
}

/**
 * The state of a message search in the current step.
 *
 * @public
 */
export declare interface MessageSearchState {
    /**
     * Contains all messages found by the search. Each message is paired up with the conversation it is from.
     */
    results: SearchMessageSnapshot[];
    /**
     * Whether all results have been loaded.
     *
     * @remarks
     * Note: When true, this means that the search has reached the oldest matching message and no more messages can be loaded.
     * However, it does not mean that `results` contains every matching message.
     * Any messages sent after you called `setQuery` will be missing from `results`.
     */
    loadedAll: boolean;
}

/**
 * A snapshot of a message's attributes at a given moment in time.
 *
 * @remarks
 * Automatically expanded to include a snapshot of the user that sent the message, and a snapshot of the referenced message, if this message is a reply.
 *
 * Snapshots are immutable and we try to reuse them when possible. You should only re-render your UI when `oldSnapshot !== newSnapshot`.
 *
 * @public
 */
export declare interface MessageSnapshot {
    /**
     * The unique ID that is used to identify the message in TalkJS
     */
    readonly id: string;
    /**
     * Whether this message was "from a user" or a general system message without a specific sender.
     *
     * The `sender` property is always present for "UserMessage" messages and never present for "SystemMessage" messages.
     */
    readonly type: "UserMessage" | "SystemMessage";
    /**
     * A snapshot of the user who sent the message, or null if it is a system message.
     * The user's attributes may have been updated since they sent the message, in which case this snapshot contains the updated data.
     * It is not a historical snapshot.
     */
    readonly sender: UserSnapshot | null;
    /**
     * Custom metadata you have set on the message
     */
    readonly custom: Record<string, string>;
    /**
     * Time at which the message was sent, as a unix timestamp in milliseconds
     */
    readonly createdAt: number;
    /**
     * Time at which the message was last edited, as a unix timestamp in milliseconds.
     * `null` if the message has never been edited.
     */
    readonly editedAt: number | null;
    /**
     * A snapshot of the message that this message is a reply to, or null if this message is not a reply.
     *
     * @remarks
     * Only UserMessages can reference other messages.
     * The referenced message snapshot does not have a `referencedMessage` field.
     * Instead, it has `referencedMessageId`.
     * This prevents TalkJS fetching an unlimited number of messages in a long chain of replies.
     */
    readonly referencedMessage: ReferencedMessageSnapshot | null;
    /**
     * Specifies how this message was created.
     *
     * - "rest" = Message sent normally, via one of the UI components, the Data API, or the REST API
     *
     * - "import" = Message sent via the admin REST API's "import messages" endpoint
     *
     * - "email" = Message sent as a reply to an email notification
     *
     * - "web" = Message sent using a classic SDK
     *
     * To track more detailed information about where a message comes from, such as browser vs mobile app, use message custom data.
     *
     * The "rest" and "web" values are confusingly named. This is for historical reasons and to maintain backwards compatibility.
     */
    readonly origin: "rest" | "import" | "email" | "web";
    /**
     * The contents of the message, as a plain text string without any formatting or attachments.
     * Useful for showing in a conversation list or in notifications.
     */
    readonly plaintext: string;
    /**
     * The main body of the message, as a list of blocks that are rendered top-to-bottom.
     */
    readonly content: ContentBlock[];
    /**
     * A summary of the emoji reactions that have been added to this message.
     *
     * @remarks
     * Each message can have up to 50 unique emoji used for reactions.
     * They are sorted in the order they were first added to the message, starting with the oldest.
     */
    readonly reactions: ReactionsSummarySnapshot[];
}

/**
 * A subscription to the messages in a specific conversation.
 *
 * @remarks
 * Get a MessageSubscription by calling {@link ConversationRef.subscribeMessages}
 *
 * The subscription is 'windowed'. It includes all messages since a certain point in time.
 * By default, you subscribe to the 30 most recent messages, and any new messages that are sent after you subscribe.
 *
 * You can expand this window by calling {@link MessageSubscription.loadMore}, which extends the window further into the past.
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface MessageSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot` and `loadedAll`.
     *
     * - `latestSnapshot: MessageSnapshot[] | null` the current state of the messages in the window, or null if you're not a participant in the conversation
     *
     * - `loadedAll: boolean` true when `latestSnapshot` contains all the messages in the conversation
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | MessageActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     *
     * @remarks
     * Wait for this promise if you want to perform some action as soon as the subscription is active.
     *
     * The promise rejects if the subscription is terminated before it connects.
     */
    readonly connected: Promise<MessageActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Expand the window to include older messages
     *
     * @remarks
     * The `count` parameter is relative to the current number of loaded messages.
     * If you call `loadMore(5)` and then call `loadMore(10)` immediately afterwards (without awaiting the promise),
     * then only 10 additional messages will be loaded, not 15.
     *
     * Avoid calling `.loadMore` in a loop until you have loaded all messages.
     * If you do need to call loadMore in a loop, make sure you set an upper bound (e.g. 1000) on the number of messages, where the loop will exit.
     *
     * @param count - The number of additional messages to load. Must be between 1 and 100. Default 30.
     * @returns A promise that resolves once the additional messages have loaded
     */
    loadMore(count?: number): Promise<void>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * @public
 * A two-element array that forms a predicate about a numeric field.
 *
 * @remarks
 * Used in {@link ConversationPredicate}.
 * Possible forms:
 *
 * - `[">", someNumber]`
 *
 * - `["<", someNumber]`
 *
 * - `[">=", someNumber]`
 *
 * - `["<=", someNumber]`
 *
 * - `["between", [lowerBound, upperBound]]`
 *
 * - `["!between", [lowerBound, upperBound]]`
 *
 * The lower bound is inclusive, the upper bound is exclusive.
 */
export declare type NumberFilter = [">" | "<" | ">=" | "<=", number] | ["between" | "!between", [number, number]];

/**
 * @public
 * A two-element array that forms a predicate about a numeric field.
 *
 * @remarks
 * Used in {@link ConversationPredicate}.
 * Possible forms:
 *
 * - `[">", someNumber]`
 *
 * - `["<", someNumber]`
 *
 * - `[">=", someNumber]`
 *
 * - `["<=", someNumber]`
 *
 * - `["between", [lowerBound, upperBound]]`
 *
 * - `["!between", [lowerBound, upperBound]]`
 */
export declare type NumberPredicate = [">" | "<" | ">=" | "<=", number] | ["between" | "!between", [number, number]];

/**
 * A helper method to predictably compute a Conversation ID based on participants' ids in the given conversation.
 * Use this method if you want to simply create a conversation between two users,
 * not related to a particular product, order or transaction.
 *
 * The order of the parameters does not matter.
 * For example, `Talk.oneOnOneId("a", "b")` yields the same result as `Talk.oneOnOneId("b", "a")`.
 *
 * This method takes the following steps:
 * 1. Take two ids of users and put them in an array
 * 2. Sort them lexicographically
 * 3. JSON encode them
 * 4. hash the result using SHA1, return the first 20 characters
 *
 * In pseudocode, this is what this function does:
 *
 *     var sorted = [me.id, other.id].sort()
 *     var encoded = JSON.encode(sorted)
 *     var hash = sha1(encoded)             // as lowercase hex
 *     return truncate(hash, 20)
 *
 * For a PHP implementation, see https://gist.github.com/eteeselink/4dc3ad32cc478986ff2b5b6361a1825f.
 * {@link https://talkjs.com/?chat | Get in touch} if you need our help implementing this in your backend language.
 * @public
 */
export declare function oneOnOneId(me: User | string, other: User | string): string;

/**
 * @public
 * @hidden due to being empty
 * @deprecated Use `popup.onOpen(() => {...})` instead, without an event parameter
 */
export declare interface OpenEvent {
}

/**
 * @public
 * @hidden
 * Contains information about an individual participant
 */
export declare interface Participant {
    /**
     * A Talk JS {@link User}
     */
    readonly user: User;
    /**
     * Contains access and notification settings for a given user's participation to a given conversation. Used in ConversationBuilder.setParticipant.
     */
    readonly participationSettings: Partial<ParticipationSettings>;
}

/**
 * The state of a participants subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface ParticipantActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the participants, or `null` if you are not a participant in that conversation.
     */
    readonly latestSnapshot: ParticipantSnapshot[] | null;
    /**
     * True if `latestSnapshot` contains all participants in the conversation.
     * Use {@link ParticipantSubscription.loadMore} to load more.
     */
    readonly loadedAll: boolean;
}

/**
 * References a given user's participation in a conversation.
 *
 * @remarks
 * Used in all Data API operations affecting that participant, such as joining/leaving a conversation, or setting their access.
 * Created via {@link ConversationRef.participant}.
 *
 * @public
 */
export declare interface ParticipantRef {
    /**
     * The ID of the user who is participating.
     *
     * @remarks
     * Immutable: if you want to reference a different participant, get a new ParticipantRef instead.
     */
    readonly userId: string;
    /**
     * The ID of the conversation the user is participating in.
     *
     * @remarks
     * Immutable: if you want to reference the user in a different conversation, get a new ParticipantRef instead.
     */
    readonly conversationId: string;
    /**
     * Fetches a snapshot of the participant.
     *
     * @remarks
     * This contains all of the participant's public information.
     *
     * @returns A snapshot of the participant's attributes, or null if the user is not a participant. The promise will reject if you are not a participant and try to read information about someone else.
     */
    get(): Promise<ParticipantSnapshot | null>;
    /**
     * Sets properties of this participant. If the user is not already a participant in the conversation, they will be added.
     *
     * @returns A promise that resolves when the operation completes.
     * When client-side conversation syncing is disabled, you must already be a participant and you cannot set anything except the `notify` property.
     * Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
     */
    set(params: SetParticipantParams): Promise<void>;
    /**
     * Edits properties of a pre-existing participant. If the user is not already a participant in the conversation, the promise will reject.
     *
     * @returns A promise that resolves when the operation completes.
     * When client-side conversation syncing is disabled, you must already be a participant and you cannot set anything except the `notify` property.
     * Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
     */
    edit(params: SetParticipantParams): Promise<void>;
    /**
     * Adds the user as a participant, or does nothing if they are already a participant.
     *
     * @remarks
     * If the participant already exists, this operation is still considered successful and the promise will still resolve.
     *
     * @returns A promise that resolves when the operation completes. The promise will reject if client-side conversation syncing is disabled and the user is not already a participant.
     */
    createIfNotExists(params?: CreateParticipantParams): Promise<void>;
    /**
     * Removes the user as a participant, or does nothing if they are already not a participant.
     *
     * @remarks
     * Deleting a nonexistent participant is treated as success, and the promise will resolve.
     *
     * @returns A promise that resolves when the operation completes. This promise will reject if client-side conversation syncing is disabled.
     */
    delete(): Promise<void>;
    /**
     * Subscribe to this participant's state.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called when the participant joins or leaves the conversation, or their attributes change, including attributes on their user.
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     *
     * @returns A subscription to the participant
     */
    subscribe(onSnapshot?: (snapshot: ParticipantSnapshot | null) => void): SingleParticipantSubscription;
}

/**
 * A snapshot of a participant's attributes at a given moment in time.
 *
 * @remarks
 * Automatically expanded to include a snapshot of the user who is a participant.
 *
 * Snapshots are immutable and we try to reuse them when possible. You should only re-render your UI when `oldSnapshot !== newSnapshot`.
 *
 * @public
 */
export declare interface ParticipantSnapshot {
    /**
     * The user who this participant snapshot is referring to
     */
    readonly user: UserSnapshot;
    /**
     * The level of access this participant has in the conversation.
     */
    readonly access: "ReadWrite" | "Read";
    /**
     * When the participant will be notified about new messages in this conversation.
     *
     * @remarks
     * `false` means no notifications, `true` means notifications for all messages, and `"MentionsOnly"` means that the user will only be notified when they are mentioned with an `@`.
     */
    readonly notify: boolean | "MentionsOnly";
    /**
     * The date that this user joined the conversation, as a unix timestamp in milliseconds.
     */
    readonly joinedAt: number;
}

/**
 * A subscription to the participants in a specific conversation.
 *
 * @remarks
 * Get a ParticipantSubscription by calling {@link ConversationRef.subscribeParticipants}
 *
 * The subscription is 'windowed'. It includes everyone who joined since a certain point in time.
 * By default, you subscribe to the 10 most recent participants, and any participants who joined after you subscribe.
 *
 * You can expand this window by calling {@link ParticipantSubscription.loadMore}, which extends the window further into the past.
 * Do not call `.loadMore` in a loop until you have loaded all participants, unless you know that the maximum number of participants is small (under 100).
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface ParticipantSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot` and `loadedAll`.
     *
     * - `latestSnapshot: ParticipantSnapshot[] | null` the current state of the participants in the window, or null if you're not a participant in the conversation
     *
     * - `loadedAll: boolean` true when `latestSnapshot` contains all the participants in the conversation
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | ParticipantActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     *
     * @remarks
     * Wait for this promise if you want to perform some action as soon as the subscription is active.
     *
     * The promise rejects if the subscription is terminated before it connects.
     */
    readonly connected: Promise<ParticipantActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Expand the window to include older participants
     *
     * @remarks
     * The `count` parameter is relative to the current number of loaded participants.
     * If you call `loadMore(5)` and then call `loadMore(10)` immediately afterwards (without awaiting the promise),
     * then only 10 additional participants will be loaded, not 15.
     *
     * Avoid calling `.loadMore` in a loop until you have loaded all participants.
     * If you do need to call loadMore in a loop, make sure you set a small upper bound (e.g. 100) on the number of participants, where the loop will exit.
     *
     * @param count - The number of additional participants to load. Must be between 1 and 50. Default 10.
     * @returns A promise that resolves once the additional participants have loaded
     */
    loadMore(count?: number): Promise<void>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * Specifies access and notification settings for a given user's participation
 * to a given conversation. Used in {@link ConversationBuilder.setParticipant}.
 * @public
 */
export declare interface ParticipationSettings {
    /**
     * Specifies the participant's access permission for a conversation. See {@link ConversationBuilder.setParticipant}
     * @remarks
     * When omitted or `undefined`, the existing value remains unchanged.
     */
    access?: "Read" | "ReadWrite";
    /**
     * Specifies the participants's notification settings. See {@link ConversationBuilder.setParticipant}
     * @remarks
     * When omitted or `undefined`, the existing value remains unchanged.
     */
    notify?: boolean | "MentionsOnly";
}

/**
 * The state of a subscription before it has connected to the server
 *
 * @public
 */
export declare interface PendingState {
    readonly type: "pending";
}

/**
 * @public
 *
 * A string that is one of `"notifications" | "microphone" | "geolocation"`.
 *
 * @remarks
 * Used in {@link BrowserPermissionNeededEvent} and {@link BrowserPermissionDeniedEvent}
 *
 * Note that more possible values may be added in the future, so make sure your
 * handler can deal with unknown permission types gracefully.
 */
export declare type PermissionType = "notifications" | "microphone" | "geolocation";

/**
 * A messaging UI for just a single conversation.
 *
 * There is no way for the user to switch between conversations
 * (but you can change the active conversation through {@link Popup.select}).
 * Create a Popup through {@link Session.createPopup} and then call
 * {@link Popup.mount} to show it.
 * @public
 */
export declare interface Popup extends UIBox {
    /**
     * Renders the Popup UI on your page
     *
     * @remarks
     * Loads the popup in the background, but by default shows only the launcher button. Pass
     * `{ show: true }` to open the popup as soon as it's loaded.
     */
    mount(options?: {
        show?: boolean;
    }): Promise<void>;
    /**
     * Destroys the popup and removes it from the DOM
     *
     * @remarks
     * Destroys the popup, removes it from the DOM and removes all event listeners it has running.
     */
    destroy(): void;
    /**
     * Shows the Popup
     *
     * @remarks
     * Use this to show a popup that was previously hidden or mounted with a parameter `show: false`.
     * Note: does nothing on unmounted popups. Make sure you call {@link Popup.mount} once before you call `show()` or {@link Popup.hide}.
     */
    show(): void;
    /**
     * Closes the popup, but doesn't remove it from the DOM
     */
    hide(): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "open", handler: () => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "close", handler: () => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "sendMessage", handler: (event: SendMessageEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "focus", handler: () => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "blur", handler: () => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "translationToggled", handler: (event: TranslationToggledEvent) => void): void;
    /**
     * Listens for an event.
     * @deprecated Please use the `onXyz` methods on {@link Popup} instead.
     */
    on(eventType: "keyup", handler: (event: KeyEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("open")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "open", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("close")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "close", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("sendMessage")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "sendMessage", handler: (event: SendMessageEvent) => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "focus", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("blur")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "blur", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("translationToggled")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "translationToggled", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link Popup.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("keyup")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Popup} `onXyz` instead.
     */
    off(eventType: "keyup", handler: (event: KeyEvent) => void): void;
    /**
     * Triggers when the popup is opened by the user
     *
     * @remarks
     * Only gets triggered when the user performs an action to open the popup.
     * This event is not triggered when you call {@link Popup.show} or when you
     * {@link Popup.mount} it with the `{show: true}` option.
     */
    onOpen(handler: () => void): Subscription;
    /**
     * Triggers when the popup is closed by the user
     *
     * @remarks
     * Only gets triggered when the user performs an action to close the popup,
     * eg when they click the "X" on the launcher or,
     * {@link PopupOptions.showCloseInHeader | if enabled}, in the popup header.
     * This event is not triggered when you call {@link Popup.hide} or
     * {@link Popup.destroy}.
     */
    onClose(handler: () => void): Subscription;
}

/**
 * @alias UIBox Popup
 * @public
 */
export declare interface PopupOptions extends ChatboxOptions {
    /**
     * If enabled, the Popup will reopen every time
     * the user navigates to another page. This way, a conversation can continue
     * while the user browses around. Set to `false` to disable this behavior.
     *
     * Defaults to false.
     */
    keepOpen?: boolean;
    /**
     * Specifies whether to show a round
     * launcher and/or close button beneath the popup in the right bottom corner
     * of the page.
     *
     * @remarks
     * `"close-only"`: show a close button beneath the popup, but don't show a launch button
     *
     * `"always"`: show a launch button when the popup is closed, show a close button when it is visible
     *
     * `"never"`: never show a launcher
     *
     * Note: if you choose `"never"` you may want to override the positioning of the popup as well.
     * Just tune the `__talkjs_popup` class in your CSS.
     *
     * Ignored on mobile, where the popup fills the entire screen so the value is effectively `"never"`.
     *
     * Defaults to `"always"`.
     *
     */
    launcher?: "close-only" | "always" | "never";
    /**
     * Whether to show the "x" icon in the popup header to close the popup.
     * "auto", which is the default value means `true` on mobile and to `false` on desktop.
     */
    showCloseInHeader?: boolean | "auto";
}

/**
 * @public
 */
export declare interface PushRegistrationOptions {
    /**
     * The push message provider to use: Google's Firebase Cloud Messaging (`fcm`)
     * or Apple's APNs (`apns`).
     */
    provider: "fcm" | "apns";
    /**
     * The APNs {@link https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#//apple_ref/doc/uid/TP40008194-CH6-SW4|device token} or the FCM {@link https://firebase.google.com/docs/cloud-messaging/android/client|registration token}.
     */
    pushRegistrationId: string;
}

/**
 * References all the reactions on a message using a specific emoji.
 *
 * @deprecated This has been renamed to {@link ReactionsRef}. For back-compat, this will continue to be available as an alias.
 *
 * @public
 */
export declare type ReactionRef = ReactionsRef;

/**
 * The state of a user reaction list subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface ReactionsActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the participants, or `null` if you are not a participant in that conversation.
     */
    readonly latestSnapshot: SingleReactionSnapshot[] | null;
    /**
     * True if `latestSnapshot` contains all users who used this reaction.
     * Use {@link ReactionsSubscription.loadMore} to load more.
     */
    readonly loadedAll: boolean;
}

/**
 * A summary of the reactions to a message using a specific emoji.
 *
 * @deprecated This has been renamed to {@link ReactionsSummarySnapshot}. For back-compat, this will continue to be available as an alias.
 *
 * @public
 */
export declare type ReactionSnapshot = ReactionsSummarySnapshot;

/**
 * References all the reactions on a message using a specific emoji.
 *
 * @remarks
 * Used in all Data API operations affecting reactions with this emoji.
 * This includes mutating *your* reaction with `.add` and `.remove`, as well as fetching information about the aggregate state using `getFirstReactions` and `.subscribe`.
 * Created via {@link MessageRef.reactions}.
 *
 * @public
 */
export declare interface ReactionsRef {
    /**
     * Which emoji the reactions use.
     *
     * @remarks
     * Either a single Unicode emoji, or the name of a custom emoji with a colon at the start and end.
     * This is not validated until you send a request to the server.
     * Since custom emoji are configured in the frontend, there are no checks to make sure a custom emoji actually exists.
     *
     * Immutable: if you want to use a different emoji, get a new ReactionRef instead.
     *
     * @example Unicode emoji
     * "👍"
     *
     * @example Custom emoji
     * ":cat-roomba:"
     */
    readonly emoji: string;
    /**
     * The ID of the message that this is a reaction to.
     *
     * @remarks
     * Immutable: if you want reactions for a different message, get a new ReactionRef instead.
     */
    readonly messageId: string;
    /**
     * The ID of the conversation the message belongs to.
     *
     * @remarks
     * Immutable: if you want reactions for a message in a different conversation, get a new MessageRef from that conversation and call `.reactions` on that MessageRef.
     */
    readonly conversationId: string;
    /**
     * React with this emoji reaction, as the current user.
     *
     * @returns A promise that resolves when the operation completes. The promise will reject if the request is invalid, the message doesn't exist, there are already 50 different reactions on this message, or if you do not have permission to use emoji reactions on that message. The promise will resolve with no effect if you have already reacted with this emoji.
     */
    add(): Promise<void>;
    /**
     * Un-react with this emoji reaction, as the current user.
     *
     * @returns A promise that resolves when the operation completes. The promise will reject if the request is invalid, the message doesn't exist, or you do not have permission to use emoji reactions on that message. The promise will resolve with no effect if you have not reacted with this emoji.
     */
    remove(): Promise<void>;
    /**
     * Lists the first 10 users who added this reaction to the message.
     *
     * @remarks
     * If more than 10 users added this reaction to the message, only the first 10 users will be returned.
     *
     * To load more than 10 users, and to get real-time updates when users add or remove reactions, use {@link subscribe} instead.
     *
     * @returns The first 10 users, or `null` if the message doesn't exist or is inaccessible to you.
     */
    getFirstReactions(): Promise<SingleReactionSnapshot[] | null>;
    /**
     * Subscribe to the list of users who have added this reaction to the message
     */
    subscribe(onSnapshot?: (snapshot: SingleReactionSnapshot[] | null, loadedAll: boolean) => void): ReactionsSubscription;
}

/**
 * A subscription to the users who have reacted with a specific emoji on a specific message.
 *
 * @remarks
 * Get a ReactionsSubscription by calling {@link ReactionsRef.subscribe}
 *
 * The subscription is 'windowed'. It includes all reactions up to a certain point in time.
 * By default, you subscribe to the 10 oldest reactions.
 *
 * You can expand this window to load newer reactions by calling {@link ReactionsSubscription.loadMore}, which extends the window further into the future.
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface ReactionsSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot` and `loadedAll`.
     *
     * - `latestSnapshot: SingleReactionSnapshot[] | null` the current state of who used this reaction, or null if the message does not exist, or if you're not a participant in the conversation
     *
     * - `loadedAll: boolean` true when `latestSnapshot` contains all the users who added this reaction to the message
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | ReactionsActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     *
     * @remarks
     * Wait for this promise if you want to perform some action as soon as the subscription is active.
     *
     * The promise rejects if the subscription is terminated before it connects.
     */
    readonly connected: Promise<ReactionsActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Expand the window to include people who added the reaction later
     *
     * @remarks
     * The `count` parameter is relative to the current number of loaded users.
     * If you call `loadMore(5)` and then call `loadMore(10)` immediately afterwards (without awaiting the promise),
     * then only 10 additional users will be loaded, not 15.
     *
     * Avoid calling `.loadMore` in a loop until you have loaded all users.
     * If you do need to call loadMore in a loop, make sure you set an upper bound (e.g. 1000) on the number of users, where the loop will exit.
     *
     * @param count - The number of additional users to load. Must be between 1 and 100. Default 30.
     * @returns A promise that resolves once the additional users have loaded
     */
    loadMore(count?: number): Promise<void>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * A summary of the reactions to a message using a specific emoji.
 *
 * @remarks
 * To see who reacted with a given emoji, or to add a reaction yourself, get a {@link ReactionsRef} using {@link MessageRef.reactions}.
 *
 * @public
 */
export declare interface ReactionsSummarySnapshot {
    /**
     * Which emoji the users reacted with.
     *
     * @remarks
     * Either a single Unicode emoji, or the name of a custom emoji with a colon at the start and end.
     * Since custom emoji are defined in the frontend, they are not validated by the TalkJS server.
     * The UI should ignore reactions that use unrecognised custom emoji.
     *
     * NOTE: In unicode, it is possible to have multiple emoji that look identical but are represented differently.
     * For example, `"👍" !== "👍️"` because the second emoji includes a {@link https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block) | variation selector 16 codepoint}.
     * This codepoint forces the character to appear as an emoji.
     *
     * TalkJS normalises all emoji reactions to be "fully qualified" {@link https://unicode.org/Public/emoji/16.0/emoji-test.txt | according to this list}.
     * This prevents a message having multiple separate 👍 reactions.
     *
     * Be careful when processing the `emoji` property, as this normalisation might break equality checks:
     *
     * ```ts
     * // Emoji has unnecessary variation selector 16
     * const sent = "👍"
     *
     * // React with thumbs up,
     * await message.reactions(emoji).add()
     *
     * // Fetch the reaction
     * const snapshot = await message.get();
     * const received = snapshot.reactions[0].emoji;
     *
     * // Fails because TalkJS removed the variation selector
     * assert sent === received;
     * ```
     *
     * @example Unicode emoji
     * "👍"
     *
     * @example Custom emoji
     * ":cat-roomba:"
     */
    readonly emoji: string;
    /**
     * The number of times this emoji has been added to the message.
     */
    readonly count: number;
    /**
     * Whether the current user has reacted to the message with this emoji.
     */
    readonly currentUserReacted: boolean;
}

/** @public */
export declare const ready: Promise<void>;

/**
 * A snapshot of a message's attributes at a given moment in time, used in {@link MessageSnapshot.referencedMessage}.
 *
 * @remarks
 * Automatically expanded to include a snapshot of the user that sent the message.
 * Since this is a snapshot of a referenced message, its referenced message is not automatically expanded, to prevent fetching an unlimited number of messages in a long chain of replies.
 * Instead, contains the `referencedMessageId` field.
 *
 * Snapshots are immutable and we try to reuse them when possible. You should only re-render your UI when `oldSnapshot !== newSnapshot`.
 *
 * @public
 */
export declare interface ReferencedMessageSnapshot {
    /**
     * The unique ID that is used to identify the message in TalkJS
     */
    readonly id: string;
    /**
     * Referenced messages are always "UserMessage" because you cannot reply to a system message.
     */
    readonly type: "UserMessage";
    /**
     * A snapshot of the user who sent the message.
     * The user's attributes may have been updated since they sent the message, in which case this snapshot contains the updated data.
     * It is not a historical snapshot.
     *
     * @remarks
     * Guaranteed to be set, unlike in MessageSnapshot, because you cannot reference a SystemMessage
     */
    readonly sender: UserSnapshot;
    /**
     * Custom metadata you have set on the message
     */
    readonly custom: Record<string, string>;
    /**
     * Time at which the message was sent, as a unix timestamp in milliseconds
     */
    readonly createdAt: number;
    /**
     * Time at which the message was last edited, as a unix timestamp in milliseconds.
     * `null` if the message has never been edited.
     */
    readonly editedAt: number | null;
    /**
     * The ID of the message that this message is a reply to, or null if this message is not a reply.
     *
     * @remarks
     * Since this is a snapshot of a referenced message, we do not automatically expand its referenced message.
     * The ID of its referenced message is provided here instead.
     */
    readonly referencedMessageId: string | null;
    /**
     * Specifies how this message was created.
     *
     * - "rest" = Message sent normally, via one of the UI components, the Data API, or the REST API
     *
     * - "import" = Message sent via the admin REST API's "import messages" endpoint
     *
     * - "email" = Message sent as a reply to an email notification
     *
     * - "web" = Message sent using a classic SDK
     *
     * To track more detailed information about where a message comes from, such as browser vs mobile app, use message custom data.
     *
     * The "rest" and "web" values are confusingly named. This is for historical reasons and to maintain backwards compatibility.
     */
    readonly origin: "rest" | "import" | "email" | "web";
    /**
     * The contents of the message, as a plain text string without any formatting or attachments.
     * Useful for showing in a conversation list or in notifications.
     */
    readonly plaintext: string;
    /**
     * The main body of the message, as a list of blocks that are rendered top-to-bottom.
     */
    readonly content: ContentBlock[];
    /**
     * All the emoji reactions that have been added to this message.
     */
    readonly reactions: ReactionsSummarySnapshot[];
}

/**
 * A snapshot of search results in a given moment in time.
 * contains a message and the conversation it from.
 *
 * @public
 */
export declare interface SearchMessageSnapshot {
    /**
     * The conversation that the message was found in.
     */
    conversation: ConversationSnapshot;
    /**
     * The message that was found in the search.
     */
    message: MessageSnapshot;
}

/**
 * @public
 * Event data triggered from {@link Inbox.onSelectConversation}.
 */
export declare interface SelectConversationEvent {
    /**
     * The current TalkJS User
     */
    me: UserSnapshot;
    /**
     * @deprecated When you are the only participant in the conversation, this property includes the current user.
     * This incorrect behavior is maintained for backwards compatibility.
     * Use `participants` and filter out the current user instead.
     *
     * The other participants in the conversation that are not the current user
     */
    others: Array<UserSnapshot>;
    /**
     * The participants in the conversation, including the current user
     */
    participants: Array<UserSnapshot>;
    /**
     * The current conversation object
     */
    conversation: ConversationData;
    /**
     * The id of the message to scroll to (This property only exists when a message search result has been selected)
     */
    messageId?: string;
    /**
     * Prevents the clicked conversation from being selected.
     */
    preventDefault(): void;
}

/**
 * @public
 * Selection parameters.
 */
export declare interface SelectConversationOptions {
    /**
     * can be used to select the conversation as a guest, with limited functions
     */
    asGuest?: boolean;
    /**
     * can be used to scroll to a specific message
     */
    messageId?: string;
}

/**
 * The version of {@link ContentBlock} that is used when sending or editing messages.
 *
 * @remarks
 * This is the same as {@link ContentBlock} except it uses {@link SendFileBlock} instead of {@link FileBlock}
 *
 * `SendContentBlock` is a subset of `ContentBlock`.
 * This means that you can re-send the `content` from an existing message without any issues:
 *
 * ```ts
 * const existingMessage: MessageSnapshot = ...;
 *
 * const convRef = session.conversation('example_conversation_id');
 * convRef.send({ content: existingMessage.content });
 * ```
 *
 * @public
 */
export declare type SendContentBlock = TextBlock | SendFileBlock | LocationBlock;

/**
 * @public
 */
export declare interface SenderPredicate {
    /**
     * Only show messages from a sender(s) with a given id.
     *
     * @example Don't show messages sent by user with ID 1
     * ```json
     * { sender: { id: ["!=", "1"] } }
     * ```
     */
    id?: FieldPredicate<string>;
    /**
     * Only show messages from senders with a given locale.
     *
     * @example Only show messages from senders with locale: en-GB or en-US
     * ```json
     * { sender: { locale: ["oneOf", ["en-GB", "en-US"] } }
     * ```
     */
    locale?: FieldPredicate<string>;
    /**
     * Only show messages from senders who have a particular role.
     *
     * @example Only show messages from senders with role: Admin and locale: en-GB
     * ```json
     * { sender: { role: ["==", "Admin"], locale: ["==", "en-GB"] } }
     * ```
     */
    role?: FieldPredicate<string>;
    /**
     * Only show messages from senders who have particular custom fields set to particular values.
     *
     * @remarks
     * Every key must correspond to a key in a user's custom data that you have set. It is not necessary for all
     * senders to have these keys.
     *
     * Each value must be either:
     *
     * A string, equal to `"exists"` or `"!exists"`
     *
     * A 2-element array of `[operator, operand]` structure. The operand must be either a
     * string or an array of strings (for the `oneOf` operators). Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * @example Only show messages from senders that have the custom `alternateRole` property set
     * ```json
     * { custom: {alternateRole: "exists" } }
     * ```
     *
     * @example Only show messages from senders that have "support" `alternateRole` in their custom data
     * ```json
     * { custom: { alternateRole: ["==", "support"] } }
     * ```
     */
    custom?: {
        [key: string]: CustomFieldPredicate;
    };
}

/**
 * The version of {@link FileBlock} that is used when sending or editing messages.
 *
 * @remarks
 * When a user receives the message you send with `SendFileBlock`, this block will have turned into one of the {@link FileBlock} variants.
 *
 * For information on how to obtain a file token, see {@link FileToken}.
 *
 * The `SendFileBlock` interface is a subset of the `FileBlock` interface.
 * If you have an existing `FileBlock` received in a message, you can re-use that block to re-send the same attachment:
 *
 * ```ts
 * const existingFileBlock = ...;
 * const imageToShare = existingFileBlock.content[0] as ImageBlock
 *
 * const convRef = session.conversation('example_conversation_id');
 * convRef.send({ content: [imageToShare] });
 * ```
 *
 * @public
 */
export declare interface SendFileBlock {
    type: "file";
    /**
     * The encoded identifier for the file, obtained by uploading a file with {@link Session.sendFile}, or taken from another message.
     */
    fileToken: FileToken;
}

/**
 * @public
 * The event triggered when listening for the sendMessage event on the {@link Inbox}, {@link Chatbox} and {@link Popup}.
 * This event is triggered before the message is sent to TalkJS, allowing you to modify the contents of the message or its metadata by
 * using `override()`.
 */
export declare interface SendMessageEvent {
    /**
     * The message that was sent
     */
    message: SentMessage;
    /**
     * The current TalkJS user
     */
    me: UserSnapshot;
    /**
     * The current conversation object
     */
    conversation: ConversationData;
    /**
     * This function allows you to modify the contents of the message or its
     * metadata before the message is sent.
     *
     * @remarks Pass an object with `text` and/or `custom` fields, see
     * {@link SendMessageOverrideParams}.
     *
     * You can either pass the overridden data directly, or a (possibly async)
     * function that computes it.
     *
     * You may also pass `{ cancel: true }` and then the message will not be sent
     * at all. Note that the message field will still be cleared, as if the
     * message were sent.
     *
     * Note that if you pass an async function, it must resolve as quickly as
     * possible, because the chat UI cannot update before it does. This may make
     * chat UX feel sluggish. If it does not resolve within 5 seconds, the message
     * is sent unmodified.
     */
    override: (params: SendMessageOverrideParams | (() => SendMessageOverrideParams | Promise<SendMessageOverrideParams>)) => void;
}

/**
 * @public
 */
export declare interface SendMessageOptions {
    /**
     * An object with any custom data that you may wish to associate with this message. The custom data is sent back to you via webhooks and the REST API.
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom?: CustomData;
}

/**
 * @public
 */
export declare interface SendMessageOverrideParams {
    /** Overrides the text content of the message */
    text?: string;
    /** Adds custom fields to the message */
    custom?: CustomData;
    /** Set to true prevent the message from being sent at all. */
    cancel?: boolean;
}

/**
 * Parameters you can pass to {@link ConversationRef.send}.
 *
 * @remarks
 * Properties that are `undefined` will be set to the default.
 *
 * This is the more advanced method for editing a message, giving full control over the message content.
 * You can decide exactly how a text message should be formatted, edit an attachment, or even turn a text message into a location.
 *
 * @public
 */
export declare interface SendMessageParams {
    /**
     * Custom metadata to set on the message.
     * Default = no custom metadata
     */
    custom?: Record<string, string>;
    /**
     * The message that you are replying to.
     * Default = not a reply
     */
    referencedMessage?: string | MessageRef;
    /**
     * The most important part of the message, either some text, a file attachment, or a location.
     *
     * @remarks
     * By default users do not have permission to send {@link LinkNode}, {@link ActionLinkNode}, or {@link ActionButtonNode}, as they can be used to trick the recipient.
     *
     * Currently, each message can only contain a single {@link SendContentBlock}.
     */
    content: [SendContentBlock];
}

/**
 * Parameters you can pass to {@link ConversationRef.send}.
 *
 * @remarks
 * Properties that are `undefined` will be set to the default.
 *
 * This is a simpler version of {@link SendMessageParams} that only supports text messages.
 *
 * @public
 */
export declare interface SendTextMessageParams {
    /**
     * Custom metadata to set on the message.
     * Default = no custom metadata
     */
    custom?: Record<string, string>;
    /**
     * The message that you are replying to.
     * Default = not a reply
     */
    referencedMessage?: string | MessageRef;
    /**
     * The text to send in the message.
     *
     * @remarks
     * This is parsed the same way as the text entered in the message field. For example, `*hi*` will appear as `hi` in bold.
     *
     * See the {@link https://talkjs.com/docs/Features/Messages/Formatting/ | message formatting documentation} for more details.
     */
    text: string;
}

/**
 * @public
 * A message that was sent to TalkJS
 */
export declare interface SentMessage {
    /**
     * The message ID of the message that was sent
     */
    id: string | undefined;
    /**
     * The ID of the conversation that the message belongs to
     */
    conversationId: string;
    /**
     * Identifies the message as either a {@link https://talkjs.com/docs/Concepts/Messages | User message} or
     * {@link https://talkjs.com/docs/Concepts/System_Messages/ | System message}
     */
    type: "UserMessage" | "SystemMessage";
    /**
     * Contains an Array of {@link User.id}'s that have read the message
     */
    readBy: string[];
    /**
     * Contains the user ID for the person that sent the message
     */
    senderId: string;
    /**
     * Contains the message's text
     */
    text?: string;
    /**
     * Only given if the message contains a file. An object with the URL and filesize (in bytes) of the given file. Attachment dimensions (in px) are sometimes available for image and video attachments, used to set the size of the thumbnail before loading, to prevent content shift when loading media on slower connections.
     */
    attachment?: Attachment;
    /**
     * Only given if the message contains a location.
     * An array of two numbers which represent the longitude and latitude of this location, respectively.
     * Only given if this message is a shared location.
     * For example: `[51.481083, -3.178306]`.
     */
    location?: [number, number];
}

/**
 * A session represents a user's active browser tab. It also authenticates your app
 * with TalkJS.
 *
 * @public
 */
export declare class Session {
    private readonly _onEventSubscription;
    private readonly _eventEmitter;
    private _uiBoxes;
    /**
     * Whether the session is active and in a valid state.
     *
     * @remarks
     * When false, calling methods on this Session instance will throw errors.
     *
     * This field is false when {@link Session.destroy} has been called in the
     * past. Once a session has been destroyed, you cannot revive it. Instead,
     * create a new session.
     */
    isAlive: boolean;
    /**
     * Holds information about unread conversations. Lets your app be notified
     * when the active user receives a new message.
     */
    readonly unreads: Unreads;
    /** The TalkJS {@link User} associated with the current user in your application. */
    readonly me: User;
    /**
     * A reference to the current user.
     *
     * @remarks
     * The current user is the one you passed to the session constructor as `userId` or `me`.
     * This is a short-hand for `session.user(session.me.id)`.
     *
     * The returned UserRef is part of the {@link https://talkjs.com/docs/JavaScript_Data_API/Users/ | Data API}, which is included in the Chat SDK.
     * You can use references to get, edit, and subscribe to your data.
     *
     * @see {@link Session.user} which lets you get a reference to any user.
     */
    readonly currentUser: UserRef;
    /**
     * Get a reference to a user.
     *
     * @remarks
     * The returned UserRef is part of the {@link https://talkjs.com/docs/JavaScript_Data_API/Users/ | Data API}, which is included in the Chat SDK.
     * This is the entry-point for all Data API operations that affect a user globally, such as editing their name.
     * You can use references to get, edit, and subscribe to your data.
     *
     * Calling this method multiple times with the same ID reuses the same {@link UserRef} object.
     *
     * @see {@link Session.currentUser} which is a short-hand for `session.user(session.me.id)`.
     *
     * @example Initialising a user
     * ```ts
     * const userRef = session.user("test");
     * userRef.createIfNotExists({ name: "Alice" });
     * ```
     *
     * @example Subscribing to changes
     * ```ts
     * const userRef = session.user("test");
     * const userSub = userRef.subscribe(snapshot => console.log(snapshot));
     *
     * // Changing the user's name emits a snapshot and triggers the `console.log`
     * await userRef.set({ name: "Bob" });
     * ```
     *
     * @param id - The ID of the user that you want to reference
     * @returns A UserRef for the user with that ID
     * @throws If the id is not a string or is an empty string
     * @public
     */
    user(id: string): UserRef;
    /**
     * Get a reference to a conversation.
     *
     * @remarks
     * The returned ConversationRef is part of the {@link https://talkjs.com/docs/JavaScript_Data_API/Conversations/ | Data API}, which is included in the Chat SDK.
     * You can use references to get, edit, and subscribe to your data.
     *
     * Calling this method multiple times with the same ID reuses the same {@link ConversationRef} object.
     *
     * @example Ensure that the conversation exists and you are a participant
     * ```ts
     * session.conversation("test").createIfNotExists();
     * ```
     *
     * @example Set the conversation's subject
     * ```ts
     * session.conversation("test").set({ subject: "Power tools" });
     * ```
     *
     * @example Stop receiving notifications for this conversation
     * ```ts
     * session.conversation("test").set({ notify: false });
     * ```
     *
     * @example Send a message
     * ```ts
     * session.conversation("test").send("Hello");
     * ```
     *
     * @param id - The ID of the conversation that you want to reference
     * @returns A ConversationRef for the conversation with that ID
     * @throws If the id is not a string or is an empty string
     * @public
     */
    conversation(id: string): ConversationRef;
    /**
     * Subscribes to your most recently active conversations.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called whenever the conversation snapshots change.
     * This includes when you join or leave a conversation, when the conversation attributes change, and when you load more conversations.
     * It also includes when nested data changes, such as when `snapshot[0].lastMessage.referencedMessage.sender.name` changes.
     * Be careful when doing heavy computation inside `onSnapshot`, and consider caching the result. `onSnapshot` is called extremely often.
     * `loadedAll` is true when `snapshot` contains all your conversations, and false if you could load more.
     *
     * The `snapshot` list is ordered chronologically with the most recently active conversations at the start.
     * The last activity of a conversation is either when the last message was sent or when you joined, whichever is later.
     * In other words, it's the max of `lastMessage.createdAt` and `joinedAt`.
     * If you join a new conversation, or you receive a message in a conversation, that conversation will appear at the start of the list.
     *
     * The snapshot is an empty list if the current user does not exist yet.
     *
     * Initially, you will be subscribed to the 20 most recently active conversations and any conversations that have activity after you subscribe.
     * Call `loadMore` to load additional older conversations. This will trigger `onSnapshot`.
     *
     * You can optionally provide an `options` object as the first argument.
     * If you provide `options` with a `filter`, only conversations matching the filter will be included in the snapshot.
     * See {@link ConversationFilter} for more details on what filter options are supported.
     * Note that this filter is part of the JS Data API - it is slightly different to the `ConversationPredicate` used in the classic JS SDK's `setFeedFilter`.
     *
     * Tip: `ConversationSnapshot` has a `lastMessage` property. Whenever you are sent a message, that message will be at `snapshot[0].lastMessage`.
     * If you just want to react to newly received messages, you can use this instead of calling `ConversationRef.subscribeMessages`.
     * This is much easier and more efficient.
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     *
     * @example Subscribe to all your conversations and log them
     * ```ts
     * session.subscribeConversations(snapshots => console.log(snapshots));
     * ```
     *
     * @example Subscribe to conversations with a custom field
     * ```ts
     * session.subscribeConversations({
     *   filter: { custom: { category: ["==", "support"] } }
     * }, onSnapshot);
     * ```
     *
     * @example Subscribe to conversations with recent activity (last 7 days)
     * ```ts
     * const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
     * session.subscribeConversations({
     *   filter: { lastActivityAt: [">", sevenDaysAgo] }
     * }, onSnapshot);
     * ```
     *
     * @public
     */
    subscribeConversations(onSnapshot?: (snapshot: ConversationSnapshot[], loadedAll: boolean) => void): ConversationListSubscription;
    /**
     * Subscribes to your most recently active conversations, using the specified options.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called whenever the conversation snapshots change.
     * This includes when you join or leave a conversation, when the conversation attributes change, and when you load more conversations.
     * It also includes when nested data changes, such as when `snapshot[0].lastMessage.referencedMessage.sender.name` changes.
     * Be careful when doing heavy computation inside `onSnapshot`, and consider caching the result. `onSnapshot` is called extremely often.
     * `loadedAll` is true when `snapshot` contains all your conversations, and false if you could load more.
     *
     * The `snapshot` list is ordered chronologically with the most recently active conversations at the start.
     * The last activity of a conversation is either when the last message was sent or when you joined, whichever is later.
     * In other words, it's the max of `lastMessage.createdAt` and `joinedAt`.
     * If you join a new conversation, or you receive a message in a conversation, that conversation will appear at the start of the list.
     *
     * The snapshot is an empty list if the current user does not exist yet.
     *
     * Initially, you will be subscribed to the 20 most recently active conversations and any conversations that have activity after you subscribe.
     * Call `loadMore` to load additional older conversations. This will trigger `onSnapshot`.
     *
     * If you provide a `filter` in your options, only conversations matching the filter will be included in the snapshot.
     * See {@link ConversationFilter} for more details on what filter options are supported.
     * Note that this filter is part of the JS Data API - it is slightly different to the `ConversationPredicate` used in the classic JS SDK's `setFeedFilter`.
     *
     * Tip: `ConversationSnapshot` has a `lastMessage` property. Whenever you are sent a message, that message will be at `snapshot[0].lastMessage`.
     * If you just want to react to newly received messages, you can use this instead of calling `ConversationRef.subscribeMessages`.
     * This is much easier and more efficient.
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     *
     * @example Subscribe to all your conversations and log them
     * ```ts
     * session.subscribeConversations(snapshots => console.log(snapshots));
     * ```
     *
     * @example Subscribe to conversations with a custom field
     * ```ts
     * session.subscribeConversations({
     *   filter: { custom: { category: ["==", "support"] } }
     * }, onSnapshot);
     * ```
     *
     * @example Subscribe to conversations with recent activity (last 7 days)
     * ```ts
     * const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
     * session.subscribeConversations({
     *   filter: { lastActivityAt: [">", sevenDaysAgo] }
     * }, onSnapshot);
     * ```
     *
     * @public
     */
    subscribeConversations(options: {
        filter?: ConversationFilter;
    }, onSnapshot?: (snapshot: ConversationSnapshot[], loadedAll: boolean) => void): ConversationListSubscription;
    /**
     * Creates a search for messages in all the current user's conversations.
     *
     * @remarks
     * The search feature is available on the Growth plan or higher. On the Basic plan, this method will return an error.
     *
     * Search is a two-step process. After calling `searchMessages`, call {@link MessageSearch.setQuery} to specify a search query and begin the search.
     *
     * As search can be quite slow, there are two different ways of using search:
     *
     * Option 1: Processing each search result as soon as it is received:
     *
     * ```ts
     * const search = session.searchMessages((results, status) => {
     *   console.log("Found a new message. All messages found so far:", results);
     * });
     * search.setQuery("Hello");
     * ```
     *
     * Option 2: Wait until the full page is received (up to 60s delay) before processing:
     *
     * ```ts
     * const search = session.searchMessages();
     * const { results, loadedAll } = await search.setQuery("Hello");
     * console.log("Search completed, first page of messages:", results);
     * ```
     *
     * @param onResults - Callback to run whenever we receive new results or the status changes. Status `searching` means we are actively searching for more messages. `canLoadMore` means that the search is idle, but you can load older results with {@link MessageSearch.loadMore}. `loadedAll` means that there are no more messages to load.
     * @returns A search object. Call {@link MessageSearch.setQuery} to specify the string to search for, and begin receiving results.
     *
     * @example Basic UI integration (search-on-keypress)
     * ```ts
     * const search = session.searchMessages((results, status) => {
     *   render(results, status);
     * });
     *
     * const searchInput = document.querySelector("#searchInput");
     * searchInput.addEventListener("change", () => {
     *   search.setQuery(searchInput.value);
     * });
     * ```
     */
    searchMessages(onResults: (results: SearchMessageSnapshot[], status: "searching" | "canLoadMore" | "loadedAll") => void): MessageSearch;
    /**
     * Creates a search for all the current user's conversations.
     *
     * @remarks
     * The search feature is available on the Growth plan or higher. On the Basic plan, this method will return an error.
     *
     * Search is a two-step process. After calling `searchConversations`, call {@link ConversationSearch.setQuery} to specify a search query and begin the search.
     *
     * As search can be quite slow, there are two different ways of using search:
     *
     * Option 1: Processing each search result as soon as it is received:
     *
     * ```ts
     * const search = session.searchConversations((results, status) => {
     *   console.log("Found a new conversation. All conversations found so far:", results);
     * });
     * search.setQuery("Hello");
     * ```
     *
     * Option 2: Wait until the full page is received (up to 60s delay) before processing:
     *
     * ```ts
     * const search = session.searchConversations();
     * const { results, loadedAll } = await search.setQuery("Hello");
     * console.log("Search completed, first page of conversations:", results);
     * ```
     *
     * @param onResults - Callback to run whenever we receive new results or the status changes. Status `searching` means we are actively searching for more conversations. `canLoadMore` means that the search is idle, but you can load older results with {@link ConversationSearch.loadMore}. `loadedAll` means that there are no more conversations to load.
     * @returns A {@link ConversationSearch}. Call {@link ConversationSearch.setQuery} to specify the string to search for, and begin receiving results.
     *
     * @example Basic UI integration (search-on-keypress)
     * ```ts
     * const search = session.searchConversations((results, status) => {
     *   render(results, status);
     * });
     *
     * const searchInput = document.querySelector("#searchInput");
     * searchInput.addEventListener("change", () => {
     *   search.setQuery(searchInput.value);
     * });
     * ```
     */
    searchConversations(onResults: (results: ConversationSnapshot[], status: "searching" | "canLoadMore" | "loadedAll") => void): ConversationSearch;
    /** Your TalkJS `AppId` that can be found on the "Settings" page of your TalkJS {@link https://talkjs.com/dashboard | dashboard}. */
    readonly appId: string;
    private readonly _sessionId;
    /**
     * Creates a TalkJS Session.
     * @public
     */
    constructor(options: SessionOptions);
    /**
     * Verifies whether the `appId` is valid.
     *
     * @remarks
     * Returns a Promise of a boolean, never rejects.
     */
    hasValidCredentials(): Promise<boolean>;
    private _maybeRestorePopup;
    private _trackWindowFocus;
    /**
     * @deprecated This will keep being supported, but new projects should use {@link ConversationRef} via {@link Session.conversation|Session.conversation()} instead.
     *
     * @param other - A `User` object that identifies the person to converse with.
     * The user is uniquely identified by their id; all other fields (name, photo
     * etc) are overwritten in the TalkJS database each  time they change.
     * @param options - Options used for getOrStartConversation
     *
     * @returns a `Conversation` object that encapsulates a conversation between
     * `me` (given in the constructor) and `other`.
     *
     * @hidden
     */
    getOrStartConversation(other: User, options?: GetOrStartOptionsA): Conversation;
    /**
     * @deprecated This will keep being supported, but new projects should use {@link ConversationRef} via {@link Session.conversation|Session.conversation()} instead.
     *
     * @param conversationId - A unique identifier for this conversation. Any user with access to
     *                         this ID can join this conversation.
     *
     * @param options - Options used for getOrStartConversation
     *
     * @returns a `Conversation` object that encapsulates a conversation between `me` (given in the
     * constructor) and zero or more other `participants`.
     *
     * @hidden
     */
    getOrStartConversation(conversationId: string, options?: GetOrStartOptionsB): Conversation;
    private _maybeAddMyParticipant;
    /**
     * A method used to either fetch or create a conversation.
     *
     * @remarks
     * Returns a `ConversationBuilder` object that encapsulates a conversation
     * between `me` (given in the constructor) and zero or more other `participants`.
     * Use {@link ConversationBuilder.setParticipant} and {@link ConversationBuilder.setAttributes}
     * on the returned object to further set up your conversation.
     *
     * @param conversationId - A unique identifier for this conversation, such as a channel name or topic ID.
     * Any user with access to this ID can join this conversation. {@link https://talkjs.com/docs/Concepts/Conversations | Read about how to choose a good conversation ID for your use case}.
     * If you want to make a simple one-on-one conversation, consider using {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Talk_Object/#Talk.oneOnOneId | oneOnOneId} to generate one.
     *
     * @classic This method is part of the {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Classic_Data_API/ | Classic Data API}.
     * New TalkJS integrations should use {@link Session.conversation} instead, which is part of the simpler and more powerful {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API}.
     */
    getOrCreateConversation(conversationId: string): ConversationBuilder;
    /**
     * Creates an Inbox UI
     *
     * @remarks
     * The Inbox is TalkJS's most versatile component. It combines a
     * {@link Chatbox} with a panel showing a a list of conversations where the
     * user is a participant.
     *
     * Call `createInbox` on the messaging page of your app.
     * You typically want to call {@link Inbox.mount} after creating the inbox to make it visible on your app.
     *
     * @example Create an inbox, select a conversation, and mount the UI
     * ```ts
     * const inbox = session.createInbox();
     * inbox.select(conversation);
     * inbox.mount(talkJsContainerElement);
     * ```
     *
     * @param options - Optional. Use these to finetune the behavior of the Inbox.
     */
    createInbox(options?: InboxOptions): Inbox;
    /**
     * Creates a Chatbox UI.
     *
     * @remarks
     * The Chatbox is a slimmer version of the Inbox. It shows a single conversation,
     * without giving the user a way to switch between conversations.
     *
     * Call `createChatbox` on any page you want to show a chatbox of a single conversation.
     * You typically want to call {@link Chatbox.mount} after creating the chatbox to make it visible on your app.
     *
     * Note: A deprecated two-parameter form of this method, `createChatbox(selectedConversation, options)`, also exists. This form will keep being supported but we recommend not using it new codebases. Instead, call {@link Chatbox.select} immediately after `mount`.
     *
     * @example Create a chatbox, select a conversation, and mount the UI
     * ```ts
     * const chatbox = session.createChatbox();
     * chatbox.select(conversation);
     * chatbox.mount(talkJsContainerElement);
     * ```
     *
     * @param options - Optional, Use these to finetune the behavior of the Chatbox.
     */
    createChatbox(options?: ChatboxOptions): Chatbox;
    /**
     * @public
     * @deprecated Instead, do `const chatbox = session.createChatbox(options); chatbox.select(conversation);`.
     * @hidden
     */
    createChatbox(conversation: Conversation | ConversationBuilder | null | undefined, options?: ChatboxOptions): Chatbox;
    /**
     * @public
     * @deprecated Instead, do `const popup = session.createPopup(options); popup.select(conversation);`.
     * @hidden
     */
    createPopup(conversation: Conversation | ConversationBuilder | null | undefined, options?: PopupOptions): Popup;
    /**
     * Creates a Popup UI.
     *
     * @remarks
     * The Popup is a positioned box containing a conversation. It shows a single conversation,
     * without means to switch between conversations.
     *
     * Call `createPopup` on any page you want to show a popup of a single conversation.
     * You typically want to call {@link Popup.mount} after creating the popup to make it visible on your app.
     *
     * Note: A deprecated two-parameter form of this method, `createPopup(selectedConversation, options)`, also exists. This form will keep being supported but we recommend not using it new codebases. Instead, call {@link Popup.select} immediately after `mount`.
     * In order to have a popup on each site you need to call
     * `createPopup` on any page you want to show a popup with the conversation.
     *
     * @example Create a popup, select a conversation, and mount the UI
     * ```ts
     * const popup = session.createPopup();
     * popup.select(conversation);
     * popup.mount();
     * ```
     *
     * @param options - Optional, Use these to finetune the behavior of the Popup.
     */
    createPopup(options?: PopupOptions): Popup;
    /**
     * Used to configure TalkJS to use a legacy theme hosted on the same location
     * as your application for development.
     *
     * @remarks
     * Tells TalkJS to use a theme hosted on the same location as your application
     * (e.g. localhost:8000/). e.g. Call
     * `talkSession.syncThemeForLocalDev("/assets/css/talkjs-theme.css")` just
     * before you call `createInbox` or `createChatbox`. TalkJS will then use the
     * specified file instead of using a theme created in the dashboard.
     *
     * @param path - The path to the legacy theme's CSS file
     *
     * @deprecated We recommend switching to
     * {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Themes/Theme_Editor/ | Custom Themes},
     * which are substantially more powerful and do not have a practical need for
     * a method like this.
     */
    syncThemeForLocalDev(path: string): void;
    /**
     * Sets desktop notification on or off.
     *
     * @remarks
     * Has the same effect as toggling the "Desktop notification" toggle in the
     * TalkJS Inbox UI. Use this function to replicate that toggle elsewhere in
     * your UI if you're using TalkJS in a mode that doesn't show this toggle.
     *
     * When desktop notifications are enabled for the first time, the browser will
     * show a prompt to ask the user for permission. The call will only succeed if
     * the user accepts it.
     *
     * We recommend only calling this function in response to user action, so
     * users know that they can expect a permission prompt. This significantly
     * increases the percentage of users that click "Allow".
     *
     * Notably, we strongly recommend that you do not call this function
     * immediately when the page loads, because many browsers auto block
     * notifications when permission is requested on page load. This is likely a
     * measure to prevent overly aggressive news sites from being able to spam
     * past visitors.
     *
     * @param isEnabled - Whether notifications should be enabled.
     * @param alertOnFailure - Whether to show an alert message when enabling
     * notifications fails. Defaults to `true`, unless you add a handler for
     * {@link Session.onBrowserPermissionDenied}, which emits an event when the
     * permission request fails. If there's a handler for that event, then this
     * defaults to false.
     *
     * @returns a promise that'll resolve if the change succeeds. If anything goes
     * wrong, the promise will reject with a {@link TalkError}, which has a `code`
     * property to indicate what went wrong. Possible values in this case are:
     *
     * - `Talk.ErrorCode.NOTIFICATIONS_PERMISSION_DENIED`: The browser or the user
     *   didn't grant you permission to send notifications.
     *
     * - `Talk.ErrorCode.NOTIFICATIONS_NOT_SUPPORTED`: The browser doesn't support
     *   desktop notifications.
     */
    setDesktopNotificationEnabled(isEnabled: boolean, { alertOnFailure }?: {
        alertOnFailure?: boolean;
    }): Promise<void>;
    private _cleanUIBoxes;
    /**
     * @deprecated This method will keep being supported, but for new projects,
     * we recommend that you use {@link Session.setPushRegistration}.
     *
     * Registers mobile device, one user can be connected to one mobile device.
     *
     * @remarks
     * Related method: {@link Session.unregisterDevice | Session.unregisterDevice}
     *
     * Note that you must ensure that the user exists in the TalkJS database before you call this
     * method. The simplest way to do that is to call it after you mount a chatbox, inbox or popup.
     */
    registerDevice({ platform, pushRegistrationId, }: {
        platform: "ios" | "android";
        pushRegistrationId: string;
    }): Promise<void>;
    /**
     * @deprecated This method will keep being supported, but for new projects,
     * we recommend that you use {@link Session.unsetPushRegistration} or {@link Session.clearPushRegistrations}.
     *
     * Unregisters mobile device, one user can be connected to one mobile device.
     *
     * @remarks
     * Related method: {@link Session.registerDevice | Session.registerDevice}
     */
    unregisterDevice(): Promise<void>;
    /**
     * Registers a single mobile device, as one user can be connected to multiple mobile devices.
     *
     * @remarks
     * Related methods: {@link Session.unsetPushRegistration} {@link Session.clearPushRegistrations}
     *
     * Note that you must ensure that the user exists in the TalkJS database before you call this
     * method. The simplest way to do that is to call it after you mount a chatbox, inbox or popup.
     */
    setPushRegistration(options: PushRegistrationOptions): Promise<void>;
    /**
     * Unregisters a single mobile device, as one user can be connected to multiple mobile devices.
     *
     * @remarks
     * Related methods: {@link Session.setPushRegistration} {@link Session.clearPushRegistrations}
     *
     * Note that you must ensure that the user exists in the TalkJS database before you call this
     * method. The simplest way to do that is to call it after you mount a chatbox, inbox or popup.
     */
    unsetPushRegistration(options: PushRegistrationOptions): Promise<void>;
    /**
     * Unregisters all the mobile devices for the user.
     *
     * @remarks
     * Related methods: {@link Session.setPushRegistration} {@link Session.unsetPushRegistration}
     *
     * Note that you must ensure that the user exists in the TalkJS database before you call this
     * method. The simplest way to do that is to call it after you mount a chatbox, inbox or popup.
     */
    clearPushRegistrations(): Promise<void>;
    private _onNotificationClick;
    /**
     * Listens for an event
     *
     * @remarks
     * A `"message"` event is fired every time a message is sent or received by the
     * current user (even if no TalkJS UI is visible). Your `handler` function is passed
     * a {@link Message} object with some information about each message and its conversation.
     *
     * For an example, see {@link https://gist.github.com/eteeselink/607e585eb40be76f2ed150d4090e5261}
     *
     * Note that this event does not get triggered for conversations where the current user is a {@link https://talkjs.com/docs/Concepts/Guests/ | guest}.
     * It only applies to users who were added as participants.
     *
     * Related method: {@link Session.off}
     *
     * @deprecated Please use the `onXyz` methods instead.
     */
    on(eventType: "message", handler: (message: Message) => void): void;
    /**
     * Listens for an event
     *
     * @remarks
     * A `"desktopNotificationClicked"` event is fired every time a user clicks on a desktop notification
     * generated by TalkJS.
     *
     * When a user clicks on a notification, these things will happen:
     *
     * 1. The browser tab will be selected (note, this works in most browsers but cannot be guaranteed);
     *
     * 2. If you provided one or more "desktopNotificationClicked" handlers, they will be invoked in order;
     *
     * 3. If you did not, then the currently active inbox (if any) will jump to the conversation corresponding to the notification.
     *
     * See also {@link Session.setDesktopNotificationEnabled} and {@link Session.off}
     *
     * @deprecated Please use the `onXyz` methods instead.
     */
    on(eventType: "desktopNotificationClicked", handler: (event: DesktopNotificationClickedEvent) => void): void;
    /**
     * Used to stop listening to specific TalkJS session events.
     *
     * @remarks
     * Call this with the same `eventType` and `handler` to stop receiving events.
     *
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by `onXyz` instead.
     */
    off(eventType: "message", handler: (message: Message) => void): void;
    /**
     * Used to stop listening to specific TalkJS session events.
     *
     * @remarks
     * Call this with the same `eventType` and `handler` to stop receiving events.
     *
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by `onXyz` instead.
     */
    off(eventType: "desktopNotificationClicked", handler: (event: DesktopNotificationClickedEvent) => void): void;
    /**
     * Triggered when a message is sent in a conversation the current user is in.
     *
     * @remarks
     * A `"message"` event is fired every time a message is sent or received by the
     * current user (even if no TalkJS UI is visible). Your `handler` function is passed
     * a {@link Message} object with some information about each message and its conversation.
     *
     * Note that this event does not get triggered for conversations where the current user is a {@link https://talkjs.com/docs/Concepts/Guests/ | guest}.
     * It only applies to users who were added as participants.
     */
    onMessage(handler: (message: Message) => void): Subscription;
    /**
     * Listen for when a user clicks a desktop notification.
     *
     * @remarks
     * A `"desktopNotificationClicked"` event is fired every time a user clicks on a desktop notification
     * generated by TalkJS.
     *
     * When a user clicks on a notification, these things will happen:
     *
     * 1. The browser tab will be selected (note, this works in most browsers but cannot be guaranteed);
     *
     * 2. If you provided one or more "desktopNotificationClicked" handlers, they will be invoked in order;
     *
     * 3. If you did not, then the currently active inbox (if any) will jump to the conversation corresponding to the notification.
     *
     * See also {@link Session.setDesktopNotificationEnabled}
     */
    onDesktopNotificationClicked(handler: (event: DesktopNotificationClickedEvent) => void): Subscription;
    /**
     * Triggered when a browser permission prompt is about to be shown.
     *
     * @remarks
     * Certain features, such as sharing location, sending voice messages, or
     * receiving notificatons, only work if the user has granted your app the
     * relevant permissions. By default, TalkJS will trigger the browser's
     * built-in permissions dialog the first time such a feature is used.
     *
     * This event is triggered *just before* this browser permissions dialog is
     * shown. This lets you show custom UI elements that let you show the user
     * where to look, or explain that it's all safe.
     *
     * If you return a promise from your event handler, then TalkJS will wait
     * until this promise resolves before showing the permission dialog.
     *
     * Note that it is not guaranteed that this event will trigger: It will only
     * trigger if we are certain that a permission prompt is about to show, and
     * unfortunately we can't be certain of that in all browsers. More explicitly,
     * it will only trigger when the browser supports the [Permissions
     * API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) with
     * the given notification type.
     *
     * Notably:
     *
     * * Safari below 15.6 (2022) does not support the Permissions API at all
     *
     * * Firefox does not support querying the "microphone" permission, which
     *   TalkJS needs for voice messages.
     *
     * In these situations, this event will never trigger.
     *
     * @see {@link Session.onBrowserPermissionDenied} for a way to receive an event when the browser or the user denies the requested permission.
     */
    onBrowserPermissionNeeded(handler: (event: BrowserPermissionNeededEvent) => Promise<any> | void): Subscription;
    /**
     * Triggered when the user tried to do an action that requires explicit
     * browser permission, but this permission was denied.
     *
     * @remarks
     * This can be caused by user actions such as the sharing a location, enabling
     * desktop notifications, or trying to record a voice message. These features
     * require the user to explicitly grant the browser permission.
     *
     * This event can be triggered in two situations:
     *
     * 1. The browser showed the user a permission prompt, and the user picked
     *    "Deny". In this case, this event will have been preceded by
     *    {@link Session.onBrowserPermissionNeeded}.
     *
     * 2. The user has denied the same permission in the past and the browser
     *    remembered this decision. In this case, the action will fail immediately
     *    and an {@link Session.onBrowserPermissionNeeded} event will not have
     *    been emitted.
     *
     * In either case, the user may be able to allow the permission in their
     * browser settings. The intended use of this event is to show the user an
     * alert or dialog telling them how.
     *
     * Note: by default, TalkJS may display an error message in an `alert` if a
     * permission is denied. If you listen to this event, then these messages are
     * suppressed under the assumption that you will provide your own UI for this.
     */
    onBrowserPermissionDenied(handler: (event: BrowserPermissionNeededEvent) => void): Subscription;
    /**
     * Disconnects all websockets, removes all UIs, and invalidates this session.
     *
     * @remarks
     * You cannot use any objects that were created in this session after you destroy it.
     *
     * If you want to use TalkJS after having called `destroy()` you must instantiate a new
     * Talk.Session instance.
     */
    destroy(): void;
    /**
     * Returns a list of all active {@link Popup} objects linked to this
     * session.
     *
     * @remarks
     * Includes popups actively created using {@link Session.createPopup}, and also
     * popups created on page load, if {@link PopupOptions.keepOpen} was set to
     * `true` on an earlier page.
     *
     * Only includes popups that are still mounted in the DOM. So if you call
     * `createPopup()` but later remove its container element (or an ancestor of
     * the container), then the `Popup` object will have been made invalid and
     * is therefore not included in the results.
     */
    getPopups(): Popup[];
    /**
     * Returns a list of all active {@link Inbox} objects linked to this
     * session.
     *
     * @remarks
     * Only includes inboxes that are still mounted in the DOM. So if you call
     * `createInbox()` but later remove its container element (or an ancestor of
     * the container), then the `Inbox` object will have been made invalid and
     * is therefore not included in the results.
     */
    getInboxes(): Inbox[];
    /**
     * Returns a list of all active {@link Chatbox} objects linked to this
     * session.
     *
     * @remarks
     * Only includes chatboxes that are still mounted in the DOM. So if you call
     * `createChatbox()` but later remove its container element (or an ancestor of
     * the container), then the `Chatbox` object will have been made invalid and
     * is therefore not included in the results.
     */
    getChatboxes(): Chatbox[];
    /**
     * Upload a generic file without any additional metadata.
     *
     * @remarks
     * This function does not send any message, it only uploads the file and returns a file token.
     * To send the file in a message, pass the file token in a {@link SendFileBlock} when calling {@link ConversationRef.send}.
     *
     * {@link https://talkjs.com/docs/Concepts/Message_Content/#sending-message-content | See the documentation} for more information about sending files in messages.
     *
     * If the file is a video, image, audio file, or voice recording, use one of the other functions like {@link uploadImage} instead.
     *
     * @param data The binary file data. Usually a {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File}.
     * @param metadata Information about the file
     * @returns A file token that can be used to send the file in a message.
     */
    uploadFile(data: Blob, metadata: GenericFileMetadata): Promise<FileToken>;
    /**
     * Upload an image with image-specific metadata.
     *
     * @remarks
     * This is a variant of {@link Session.uploadFile} used for images.
     *
     * @param data The binary image data. Usually a {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File}.
     * @param metadata Information about the image.
     * @returns A file token that can be used to send the image in a message.
     */
    uploadImage(data: Blob, metadata: ImageFileMetadata): Promise<FileToken>;
    /**
     * Upload a video with video-specific metadata.
     *
     * @remarks
     * This is a variant of {@link Session.uploadFile} used for videos.
     *
     * @param data The binary video data. Usually a {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File}.
     * @param metadata Information about the video.
     * @returns A file token that can be used to send the video in a message.
     */
    uploadVideo(data: Blob, metadata: VideoFileMetadata): Promise<FileToken>;
    /**
     * Upload an audio file with audio-specific metadata.
     *
     * @remarks
     * This is a variant of {@link Session.uploadFile} used for audio files.
     *
     * @param data The binary audio data. Usually a {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File}.
     * @param metadata Information about the audio file.
     * @returns A file token that can be used to send the audio file in a message.
     */
    uploadAudio(data: Blob, metadata: AudioFileMetadata): Promise<FileToken>;
    /**
     * Upload a voice recording with voice-specific metadata.
     *
     * @remarks
     * This is a variant of {@link Session.uploadFile} used for voice recordings.
     *
     * @param data The binary audio data. Usually a {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File}.
     * @param metadata Information about the voice recording.
     * @returns A file token that can be used to send the audio file in a message.
     */
    uploadVoice(data: Blob, metadata: VoiceRecordingFileMetadata): Promise<FileToken>;
}

/**
 * @public
 */
export declare interface SessionOptions {
    /** Your app's unique TalkJS ID. Get it from the "Settings" page of your dashboard. */
    appId: string;
    /**
     * A `User` object that identifies the currently active user.
     * The user is uniquely identified by their id; all other fields
     * (name, photo, etc) are overwritten in the TalkJS database each
     * time they change, unless the user has been created with the alternate
     * constructor.
     *
     * @classic `User` is part of the {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Classic_Data_API/ | Classic Data API}.
     * New TalkJS integrations should use `userId` instead and manually create the user with `Session.currentUser.set({ ... })`.
     * {@link UserRef.set | UserRef.set()} is part of the simpler and more powerful {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API}.
     */
    me?: User;
    /**
     * The ID of the currently active user.
     *
     * @remarks
     * It is permitted to pass the ID of a user that does not exist yet.
     * However, you cannot mount a Chat UI before creating your user.
     *
     * {@link Session.currentUser} will be a reference to the user with this ID.
     *
     * This is the recommended alternative to {@link SessionOptions.me}.
     */
    userId?: string;
    /**
     * A token to authenticate the session with.
     *
     * {@link https://talkjs.com/docs/Features/Security/Authentication/ | See the how-to guide} on generating authentication tokens, and many examples in different programming languages.
     *
     * {@link https://talkjs.com/docs/Features/Security/Advanced_Authentication/#token-reference | See the reference documentation} for full details on the technical requirements for the JWT.
     */
    token?: string;
    /**
     * A function that fetches and returns a new authentication token from your server.
     * TalkJS calls this function whenever the current token is about to expire.
     * This callback is designed to work with any backend setup.
     *
     * TalkJS will not retry your `tokenFetcher` if the callback throws an error.
     * Your callback should implement its own retry functionality.
     *
     * {@link https://talkjs.com/docs/Features/Security/Advanced_Authentication/#refreshable-tokens | See the how-to guide} on refreshable authentication tokens, and many examples in different programming languages.
     */
    tokenFetcher?: () => string | Promise<string>;
    /**
     * Legacy alternative to JWT authentication.
     * A HMAC-SHA256 hash of the current user ID, signed with your TalkJS secret key.
     *
     * {@link https://talkjs.com/docs/Features/Security/Advanced_Authentication/#signature-based-verification-legacy | See the documentation} for examples of how to generate a signature in different programming languages.
     *
     * @deprecated This will keep being supported, but for new projects, use {@link SessionOptions.token} instead.
     * JWT authentication is recommended because signatures never expire, meaning there is no way to revoke access.
     */
    signature?: string;
}

/**
 * Parameters you can pass to {@link ConversationRef.set}.
 *
 * Properties that are `undefined` will not be changed.
 * To clear / reset a property to the default, pass `null`.
 *
 * @public
 */
export declare interface SetConversationParams {
    /**
     * The conversation subject to display in the chat header.
     * Default = no subject, list participant names instead.
     */
    subject?: string | null;
    /**
     * The URL for the conversation photo to display in the chat header.
     * Default = no photo, show a placeholder image.
     */
    photoUrl?: string | null;
    /**
     * System messages which are sent at the beginning of a conversation.
     * Default = no messages.
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessages?: string[] | null;
    /**
     * Custom metadata you have set on the conversation.
     * This value acts as a patch. Remove specific properties by setting them to `null`.
     * Default = no custom metadata
     */
    custom?: Record<string, string | null> | null;
    /**
     * Your access to the conversation.
     * Default = "ReadWrite" access.
     */
    access?: "Read" | "ReadWrite" | null;
    /**
     * Your notification settings.
     * Default = `true`
     */
    notify?: boolean | "MentionsOnly" | null;
}

/**
 * Parameters you can pass to {@link ParticipantRef.set} or {@link ParticipantRef.edit}.
 *
 * @remarks
 * Properties that are `undefined` will not be changed.
 * To clear / reset a property to the default, pass `null`.
 *
 * @public
 */
export declare interface SetParticipantParams {
    /**
     * The level of access the participant should have in the conversation.
     * Default = "ReadWrite" access.
     */
    access?: "ReadWrite" | "Read" | null;
    /**
     * When the participant should be notified about new messages in this conversation.
     * Default = true.
     *
     * @remarks
     * `false` means no notifications, `true` means notifications for all messages, and `"MentionsOnly"` means that the user will only be notified when they are mentioned with an `@`.
     */
    notify?: boolean | "MentionsOnly" | null;
}

/**
 * Parameters you can pass to {@link UserRef.set}.
 *
 * @remarks
 * Properties that are `undefined` will not be changed.
 * To clear / reset a property to the default, pass `null`.
 *
 * @public
 */
export declare interface SetUserParams {
    /**
     * The user's name which will be displayed on the TalkJS UI
     */
    name?: string;
    /**
     * Custom metadata you have set on the user.
     * This value acts as a patch. Remove specific properties by setting them to `null`.
     * Default = no custom metadata
     */
    custom?: Record<string, string | null> | null;
    /**
     * An {@link https://www.w3.org/International/articles/language-tags/ | IETF language tag}.
     * See the {@link https://talkjs.com/docs/Features/Language_Support/#localization | localization documentation}
     * Default = null, will use the locale set on the dashboard
     */
    locale?: string | null;
    /**
     * An optional URL to a photo which will be displayed as the user's avatar.
     * Default = no photo
     */
    photoUrl?: string | null;
    /**
     * TalkJS supports multiple sets of settings, called "roles". These allow you to change the behavior of TalkJS for different users.
     * You have full control over which user gets which configuration.
     * Default = the `default` role
     */
    role?: string | null;
    /**
     * The default message a person sees when starting a chat with this user.
     * Default = no welcome message
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessage?: string | null;
    /**
     * A single email address or an array of email addresses associated with the user.
     * Default = no email addresses
     */
    email?: string | string[] | null;
    /**
     * A single phone number or an array of phone numbers associated with the user.
     * Default = no phone numbers
     */
    phone?: string | string[] | null;
    /**
     * An object of push registration tokens to use when notifying this user.
     *
     * Keys in the object have the format `'provider:token_id'`,
     * where `provider` is either `"fcm"` for Android (Firebase Cloud Messaging),
     * or `"apns"` for iOS (Apple Push Notification Service).
     *
     * The value for each key can either be `true` to register the device for push notifications, or `null` to unregister that device.
     *
     * Setting pushTokens to null unregisters all the previously registered devices.
     *
     * Default = no push tokens
     */
    pushTokens?: Record<string, true | null> | null;
}

/**
 * Allows you to filter conversations in a subscription, only showing those that match this filter.
 *
 * @remarks
 * Multiple conversation filters can be OR-ed together using {@link CompoundFilter}.
 *
 * @example Only include conversations with unread messages
 * ```ts
 * session.subscribeConversations(onSnapshot, {
 *   filter: { isUnread: true }
 * });
 * ```
 *
 * @public
 */
export declare interface SimpleConversationFilter {
    /**
     * Only select conversations that the current user as specific access to.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * The operand must be either a string (one of `"ReadWrite"` or `"Read"`) or an array of strings (for the `oneOf` operators).
     *
     * @example Hide conversations that the user cannot send messages to
     * ```json
     * { access: ["!=", "ReadWrite"] }
     * ```
     */
    access?: StringFilter<"ReadWrite" | "Read">;
    /**
     * Only select conversations that have particular custom fields set to particular values.
     *
     * @remarks
     * Every key must correspond to a key in the custom conversation data that you set (by passing
     * `custom` to {@link ConversationBuilder.setAttributes}). It is not necessary for all
     * conversations to have these keys.
     *
     * Each value must be one of the following:
     *
     * A string, equal to `"exists"` or `"!exists"`
     *
     * A 2-element array of `[operator, operand]` structure.  The operand must be either a
     * string or an array of strings (for the `oneOf` operators). Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * @example Only show messages that have no custom `category` set
     * ```json
     * { custom: { category: "!exists" } }
     * ```
     *
     * @example Only show messages of that have the custom category "shoes"
     * ```json
     * { custom: { category: ["==", "shoes"] } }
     * ```
     *
     * @example Only show messages that have a 'topic' of either "inquiry" or "reservation"
     * ```json
     * {
     *   custom: {
     *     topic: ["oneOf", ["inquiry", "reservation"]]
     *   }
     * }
     * ```
     *
     * @example Only show messages about shoes that are marked visible
     * ```json
     * {
     *   custom: {
     *     category: ["==", "shoes"],
     *     visibility: ["==", "visible"]
     *   }
     * }
     * ```
     */
    custom?: CustomFilter;
    /**
     * Set this field to only select conversations that have, or don't have any, unread messages.
     */
    isUnread?: boolean;
    /**
     * Only select conversations that have the subject set to particular values.
     *
     * @remarks
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * The operand must be either a string or an array of strings (for the `oneOf` operators).
     *
     * @example Only show conversations with "Black leather boots" or "Hair Wax 5 Gallons" as the subject
     * ```json
     * { subject: ["oneOf", ["Black leather boots", "Hair Wax 5 Gallons"]] }
     * ```
     */
    subject?: StringFilter<string | null>;
    /**
     * Only select conversations that have the last message sent in a particular time interval.
     *
     * @remarks
     * If the conversation has no messages, this falls back to using `joinedAt` instead.
     * This matches the default sort order for conversations in a conversation list.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `">"`, `"<"`, `">="`, `"<="`, `"between"`, and `"!between"`.
     *
     * The operand must be either a number or a 2-element array of numbers (for the `between` operators).
     *
     * @example Only show conversations that had messages sent after the UNIX timestamp 1679298371586
     * ```json
     * { lastMessageTs: [">", 1679298371586] }
     * ```
     */
    lastActivityAt?: NumberFilter;
    /**
     * Only select conversations that have been created in a particular time interval.
     *
     * @remarks
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `">"`, `"<"`, `">="`, `"<="`, `"between"`, and `"!between"`.
     *
     * The operand must be either a number or a 2-element array of numbers (for the `between` operators).
     *
     * @example Only show conversations that were created after the UNIX timestamp 1679298371586
     * ```json
     * { createdAt: [">", 1679298371586] }
     * ```
     */
    createdAt?: NumberFilter;
    /**
     * Only select conversations that have, or do not have messages.
     *
     * @example Only show conversations that have at least one message
     * ```json
     * { hasMessages: true }
     * ```
     *
     * @example Only show empty conversations
     * ```json
     * { hasMessages: false }
     * ```
     */
    hasMessages?: boolean;
    /**
     * Only select conversations that the current user joined in a particular time interval.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `">"`, `"<"`, `">="`, `"<="`, `"between"`, and `"!between"`.
     *
     * The operand must be either a number or a 2-element array of numbers (for the `between` operators).
     *
     * @example Only show conversations joined after the UNIX timestamp 1679298371586
     * ```json
     * { joinedAt: [">", 1679298371586] }
     * ```
     */
    joinedAt?: NumberFilter;
}

/**
 * Allows you to filter conversations down to a specific subset.
 *
 * @remarks
 * Use with {@link Inbox.setFeedFilter} or pass {@link InboxOptions.feedFilter} to
 * {@link Session.createInbox}.
 *
 * @example Only show unread conversations
 * ```ts
 * inbox.setFeedFilter({ isUnread: true });
 * ```
 *
 * @example Show everything (disable the filter)
 * ```ts
 * inbox.setFeedFilter({});
 * ```
 *
 * @public
 */
export declare interface SimpleConversationPredicate {
    /**
     * Only select conversations that the current user as specific access to.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * The operand must be either a string (one of `"ReadWrite"`, `"Read"` or `"None"`) or an array of strings (for the `oneOf` operators).
     *
     * @example Hide conversations that the user cannot send messages to
     * ```json
     * { access: ["!=", "ReadWrite"] }
     * ```
     */
    access?: FieldPredicate<ConversationAccessLevel>;
    /**
     * Only select conversations that have particular custom fields set to particular values.
     *
     * @remarks
     * Every key must correspond to a key in the custom conversation data that you set (by passing
     * `custom` to {@link ConversationBuilder.setAttributes}). It is not necessary for all
     * conversations to have these keys.
     *
     * Each value must be one of the following:
     *
     * A string, equal to `"exists"` or `"!exists"`
     *
     * A 2-element array of `[operator, operand]` structure.  The operand must be either a
     * string or an array of strings (for the `oneOf` operators). Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * @example Only show conversations that have no custom `category` set
     * ```json
     * { custom: { category: "!exists" } }
     * ```
     *
     * @example Only show conversations of that have the custom category "shoes"
     * ```json
     * { custom: { category: ["==", "shoes"] } }
     * ```
     *
     * @example Only show conversations that have a 'topic' of either "inquiry" or "reservation"
     * ```json
     * { custom: { topic: ["oneOf", ["inquiry", "reservation"] ] } }
     * ```
     *
     * @example Only show conversations about shoes that are marked visible
     * ```json
     * { custom: { category: ["==", "shoes"], visibility: ["==", "visible" ] } }
     * ```
     */
    custom?: {
        [key: string]: CustomFieldPredicate;
    };
    /**
     * Only show conversations that are either "read" or "unread".
     * Conversations are "unread" if they have unread messages or if they were manually marked as unread.
     */
    isUnread?: boolean;
    /**
     * @deprecated Renamed to `isUnread` to make it clearer that it includes conversations that were manually marked as unread.
     * For back-compat, this is maintained as an alias for `isUnread`.
     */
    hasUnreadMessages?: boolean;
    /**
     * Only select conversations that have the subject set to particular values.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * The operand must be either a string or an array of strings (for the `oneOf` operators).
     *
     * @example Only show conversations with "Black leather boots" or "Hair Wax 5 Gallons" as the subject
     * ```json
     * { subject: ["oneOf", ["Black leather boots", "Hair Wax 5 Gallons"]] }
     * ```
     */
    subject?: FieldPredicate<string | null>;
    /**
     * Only select conversations that have the last message sent in a particular time interval.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `">"`, `"<"`, `">="`, `"<="`, `"between"`, and `"!between"`.
     *
     * The operand must be either a number or a 2-element array of numbers (for the `between` operators).
     *
     * @example Only show conversations that had messages sent after the UNIX timestamp 1679298371586
     * ```json
     * { lastMessageTs: [">", 1679298371586] }
     * ```
     */
    lastMessageTs?: NumberPredicate;
    /**
     * Only select conversations that have been created in a particular time interval.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `">"`, `"<"`, `">="`, `"<="`, `"between"`, and `"!between"`.
     *
     * The operand must be either a number or a 2-element array of numbers (for the `between` operators).
     *
     * @example Only show conversations that were created after the UNIX timestamp 1679298371586
     * ```json
     * { createdAt: [">", 1679298371586] }
     * ```
     */
    createdAt?: NumberPredicate;
}

/**
 * Lets you show only specific messages in the chat panel of a Chatbox, Inbox or Popup.
 *
 * @remarks
 * Used in methods like {@link Chatbox.setMessageFilter}
 *
 * @example To hide all system messages (only show user messages)
 * ```ts
 * chatbox.setMessageFilter({ type: ["==", "UserMessage"] });
 * ```
 *
 * @example To show all messages (disable the filter)
 * ```ts
 * chatbox.setMessageFilter({});
 * ```
 *
 * @public
 */
export declare interface SimpleMessagePredicate {
    /**
     * Only show messages that are sent by a sender that has all of the given properties
     *
     * @example Only show messages sent by users with the role of 'admin' and if the user ID is 1
     * ```json
     * { sender: { role: ["==", "admin"], id: ["==", "1"] } }
     * ```
     */
    sender?: SenderPredicate;
    /**
     * Only show messages of a given type (system message or user message)
     *
     * @example Only show system messages
     * ```json
     * { type: ["==", "SystemMessage"] }
     * ```
     *
     */
    type?: FieldPredicate<"UserMessage" | "SystemMessage">;
    /**
     * Only show messages that were created in a certain way.
     * See {@link Message.origin} for a list of possible origin values.
     *
     * @example Don't show messages that were sent as replies to email notifications
     * ```json
     * { origin: ["!=", "email"] }
     * ```
     */
    origin?: FieldPredicate<"web" | "rest" | "import" | "email">;
    /**
     * Only select messages that have particular custom fields set to particular values.
     *
     * @remarks
     * Every key must correspond to a key in the custom message data that you have set. It is not necessary for all
     * messages to have these keys.
     *
     * Each value must be one of the following:
     *
     * A string, equal to `"exists"` or `"!exists"`
     *
     * A 2-element array of `[operator, operand]` structure.  The operand must be either a
     * string or an array of strings (for the `oneOf` operators). Valid operators are:
     * `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.
     *
     * @example Only show messages that have no custom `category` set
     * ```json
     * { custom: { category: "!exists" } }
     * ```
     *
     * @example Only show messages of that have the custom category "shoes"
     * ```json
     * { custom: { category: ["==", "shoes"] } }
     * ```
     *
     * @example Only show messages that have a 'topic' of either "inquiry" or "reservation"
     * ```json
     * { custom: { topic: ["oneOf", ["inquiry", "reservation"] ] } }
     * ```
     *
     * @example Only show messages about shoes that are marked visible
     * ```json
     * { custom: { category: ["==", "shoes"], visibility: ["==", "visible" ] } }
     * ```
     */
    custom?: {
        [key: string]: CustomFieldPredicate;
    };
    /**
     * Only select messages that have been sent in a particular time interval.
     *
     * Must be an 2-element array of `[operator, operand]` structure. Valid operators are:
     * `">"`, `"<"`, `">="`, `"<="`, `"between"`, and `"!between"`.
     *
     * The operand must be either a number or a 2-element array of numbers (for the `between` operators).
     *
     * @example Only show messages sent after the UNIX timestamp 1679298371586
     * ```json
     * { createdAt: [">", 1679298371586] }}
     * ```
     */
    createdAt?: NumberPredicate;
}

/**
 * The state of a participant subscription when it is actively listening for changes
 *
 * @public
 */
declare interface SingleParticipantActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the participant, or `null` if they are not a participant in that conversation.
     */
    readonly latestSnapshot: ParticipantSnapshot | null;
}

/**
 * A subscription to a specific participant.
 *
 * @remarks
 * Get a SingleParticipantSubscription by calling {@link ParticipantRef.subscribe}
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
declare interface SingleParticipantSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot: ParticipantSnapshot | null`, the current state of the participant.
     * `latestSnapshot` is `null` when the user is not a participant or the conversation does not exist.
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | SingleParticipantActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     */
    readonly connected: Promise<SingleParticipantActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * A snapshot of a user's reaction to a message.
 *
 * @remarks
 * Returned from {@link ReactionsRef.getFirstReactions} and {@link ReactionsRef.subscribe}
 *
 * @public
 */
export declare interface SingleReactionSnapshot {
    /**
     * Which user added the reaction
     */
    readonly user: UserSnapshot;
    /**
     * The timestamp of when the user added this reaction to the message
     */
    readonly createdAt: number;
}

/**
 * @public
 * A two-element array that forms a predicate about a field.
 *
 * @remarks
 * Used in {@link MessagePredicate} and {@link ConversationPredicate}.
 * Possible forms:
 *
 * - `["==", "someValue"]`
 *
 * - `["!=", "someValue"]`
 *
 * - `["oneOf", ["someValue", "someOtherValue"]]`
 *
 * - `["!oneOf", ["someValue", "someOtherValue"]]`
 */
export declare type StringFilter<T = string> = ["==" | "!=", T] | ["oneOf" | "!oneOf", T[]];

/**
 * A subscription to an event
 * @public
 */
export declare interface Subscription {
    /**
     * Stop receiving events for this subscription
     */
    unsubscribe(): void;
}

/**
 * TalkJS Error class, inherits from the global Error class.
 *
 * @remarks
 * TalkJS methods may throw (or reject promises with) instances of this class
 * if specific catchable information can be provided through the `code` property.
 *
 * @public
 */
export declare class TalkError extends Error {
    /**
     * Machine-readable error code
     */
    code: ErrorCode;
    /**
     * Human-readable error message
     */
    message: string;
}

/**
 * A block of formatted text in a message's content.
 *
 * @remarks
 * Each TextBlock is a tree of {@link TextNode} children describing the structure of some formatted text.
 * Each child is either a plain text string, or a `node` representing some text with additional formatting.
 *
 * For example, if the user typed:
 *
 * > *This first bit* is bold, and *_the second bit_* is bold and italics
 *
 * Then this would become a Text Block with the structure:
 *
 * ```json
 * {
 *   type: "text",
 *   children: [
 *      {
 *       type: "text",
 *       children: [
 *         { type: "bold", children: ["This first bit"] },
 *         " is bold, and ",
 *         {
 *           children: [
 *             { type: "italic", children: ["the second bit"] }
 *           ],
 *           type: "bold",
 *         },
 *         " is bold and italics",
 *       ],
 *     },
 *   ],
 * }
 * ```
 *
 * Rather than relying on the automatic message parsing, you can also specify the `TextBlock` directly using {@link ConversationRef.send} with {@link SendMessageParams}.
 *
 * @public
 */
export declare interface TextBlock {
    readonly type: "text";
    readonly children: TextNode[];
}

/**
 * Any node that can exist inside a {@link TextBlock}.
 *
 * @remarks
 * The simplest `TextNode` is a plain text string.
 * Using "hello" as an example message, the `TextBlock` would be:
 *
 * ```ts
 * {
 *   type: 'text';
 *   children: ['hello'];
 * }
 * ```
 *
 * Other than plain text, there are many different kinds of node which render some text in a specific way or with certain formatting.
 *
 * ```ts
 * type TextNode =
 *     | string
 *     | MarkupNode
 *     | BulletListNode
 *     | BulletPointNode
 *     | CodeSpanNode
 *     | LinkNode
 *     | AutoLinkNode
 *     | ActionLinkNode
 *     | ActionButtonNode
 *     | CustomEmojiNode
 *     | MentionNode;
 * ```
 *
 * If the text node is not a plain string, it will have a `type` field indicating what kind of node it is, and either a property `text: string` or a property `children: TextNode[]`.
 * This will be true for all nodes added in the future as well.
 *
 * @public
 */
export declare type TextNode = string | MarkupNode | BulletListNode | BulletPointNode | CodeSpanNode | LinkNode | AutoLinkNode | ActionLinkNode | ActionButtonNode | CustomEmojiNode | MentionNode;

/**
 * @public
 */
export declare interface ThemeOptions {
    /**
     * The name of the theme to use in this widget
     * If no theme name is given, TalkJS will use the theme set in the user's role,
     * falling back to the default theme if the user has no role.
     */
    name?: string;
    /**
     * A map of values that will be available to your theme under the `theme.custom` namespace.
     * The values can be anything that can be JSON-serialized.
     * String and numeric values will also be made available as CSS custom properties in themes, available as `var(--theme-<key>)`. where `<key>` is the value's key in the object.
     */
    custom?: {
        [key: string]: JsonSerializable;
    };
}

/**
 * @public
 * Used to configure supported third-party integrations with TalkJS. See
 * {@link https://talkjs.com/docs/Guides/JavaScript/Classic/Integrations/ | third party integrations }
 *
 */
export declare interface ThirdPartyOptions {
    fullstory?: FullStoryOptions;
}

/**
 * @public
 * This event is triggered when the user toggles real-time message translation using the built-in toggle.
 */
export declare interface TranslationToggledEvent {
    /**
     * Boolean indicating if translation is enabled or not
     */
    isEnabled: boolean;
    /**
     * Conversation for which translation has been toggled
     */
    conversation: ConversationData;
}

/**
 * The state of a typing subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface TypingActiveState {
    readonly type: "active";
    /**
     * The most recently received typing indicator snapshot, or `null` if you are not a participant in the conversation (including when the conversation does not exist).
     */
    readonly latestSnapshot: TypingSnapshot | null;
}

/**
 * A snapshot of the typing indicators in a conversation at a given moment in time.
 * Will be either {@link FewTypingSnapshot} when only a few people are typing, or {@link ManyTypingSnapshot} when many people are typing.
 *
 * @remarks
 * Currently {@link FewTypingSnapshot} is used when there are 5 or less people typing in the conversation, and {@link ManyTypingSnapshot} is used when more than 5 people are typing.
 * This limit may change in the future, which will not be considered a breaking change.
 *
 * @example Converting a TypingSnapshot to text
 * ```ts
 * function formatTyping(snapshot: TypingSnapshot): string {
 *   if (snapshot.many) {
 *     return "Several people are typing";
 *   }
 *
 *   const names = snapshot.users.map(user => user.name);
 *
 *   if (names.length === 0) {
 *     return "";
 *   }
 *
 *   if (names.length === 1) {
 *     return names[0] + " is typing";
 *   }
 *
 *   if (names.length === 2) {
 *     return names.join(" and ") + " are typing";
 *   }
 *
 *   // Prefix last name with "and "
 *   names.push("and " + names.pop());
 *   return names.join(", ") + " are typing";
 * }
 * ```
 */
export declare type TypingSnapshot = FewTypingSnapshot | ManyTypingSnapshot;

/**
 * A subscription to the typing status in a specific conversation
 *
 * @remarks
 * Get a TypingSubscription by calling {@link ConversationRef.subscribeTyping}.
 *
 * When there are "many" people typing (meaning you received {@link ManyTypingSnapshot}), the next update you receive will be {@link FewTypingSnapshot} once enough people stop typing.
 * Until then, your {@link ManyTypingSnapshot} is still valid and does not need to changed, so `onSnapshot` will not be called.
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface TypingSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot: TypingSnapshot | null`. It is the current state of the typing indicators, or null if you're not a participant in the conversation
     *
     * When `type` is "error", includes the `error: Error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | TypingActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     *
     * @remarks
     * Wait for this promise if you want to perform some action as soon as the subscription is active.
     *
     * The promise rejects if the subscription is terminated before it connects.
     */
    readonly connected: Promise<TypingActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * @public
 * @hidden
 */
export declare interface UIBox {
    /**
     * The conversation currently shown in the UI.
     *
     * @remarks
     * This field is `null` when the UI does not currently show a conversation (eg
     * because `null` was passed to {@link UIBox.select} or the selected
     * conversation could not be found).
     */
    readonly currentConversation: ConversationData | null;
    /**
     * Whether the object is active and in a valid state.
     *
     * @remarks
     * When false, calling methods on this instance will throw errors.
     *
     * This field is false when {@link UIBox.destroy} has been called in the past.
     * It is also false if {@link Session.destroy} has been called, because
     * destroying a session destroys all its UI widgets.
     *
     * Finally, an instance may also be considered if its previously mounted
     * iframe has been removed from the DOM by some external library.
     *
     * Once this instance has been destroyed, you cannot revive it. Instead,
     * create a new instance.
     */
    readonly isAlive: boolean;
    /**
     * Switches the active conversation.
     *
     * @remarks
     * `conversation` can be either a {@link ConversationBuilder} object or a TalkJS
     * conversation id. Passing `null` means that the conversation will be de-selected in the UI and the message list will disappear.
     * Passing `undefined` means that the last conversation (or "no chats yet" page if there are no other conversations) will be rendered in the message list component.
     *
     * @returns A promise that resolves once the new conversation has been selected.
     */
    select(conversation: string | Conversation | ConversationBuilder | ConversationRef | null | undefined, params?: SelectConversationOptions): Promise<void>;
    /**
     * Encapsulates the message entry field tied to the currently selected conversation.
     */
    messageField: MessageField;
    /**
     * Upload a file attachment to the currently active conversation.
     *
     * @remarks
     * The behaviour of this method is similar to if the user clicked the attachment button, in that the confirmation
     * dialog is shown to the user.
     *
     * Ensure that the {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File} object's name property has
     * an appropriate file extension.
     *
     * @param file - The {@link https://developer.mozilla.org/en-US/docs/Web/API/File | File} object to be uploaded.
     *
     * @classic This method is part of the {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Classic_Data_API/ | Classic Data API}.
     * You can also {@link ConversationRef.send | send files} with the simpler and more powerful {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API}, which bypasses the file preview popup and sends the file immediately.
     */
    sendFile(file: File): Promise<void>;
    /**
     * Send the user's current location to the currently active conversation.
     *
     * @remarks
     * The behaviour of this method is identical to the user clicking the location button in message field i.e the confirmation
     * dialog is shown.
     *
     * Note: If the user had not previously granted location access to your website, calling this method will
     * trigger the browser's popup asking them for permission to access their location. The user's location will only be
     * shared if they allow.
     *
     * @classic This method is part of the {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/Classic_Data_API/ | Classic Data API}.
     * You can also {@link ConversationRef.send | send locations} with the simpler and more powerful {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API}, which is not limited to only sharing the user's current GPS location, but can share any lat/long coordinates.
     */
    sendLocation(): Promise<void>;
    /**
     * Listens for an event.
     *
     * @remarks
     * Triggers when the user sends a message using the TalkJS UI
     *
     * @deprecated Please use the `onXyz` methods on {@link Chatbox} instead.
     */
    on(eventType: "sendMessage", handler: (event: SendMessageEvent) => void): void;
    /**
     * Listens for an event.
     *
     * @remarks
     * Emits an event when the user clicks/taps anywhere inside the chat UI.
     *
     * @deprecated Please use the `onXyz` methods on {@link Chatbox} instead.
     */
    on(eventType: "focus", handler: () => void): void;
    /**
     * Listens for an event.
     *
     * @remarks
     * Emits an event when the user clicks/taps anywhere outside the chat UI.
     *
     * @deprecated Please use the `onXyz` methods on {@link Chatbox} instead.
     */
    on(eventType: "blur", handler: () => void): void;
    /**
     * Listens for an event.
     *
     * @remarks
     * Triggers when the user toggles translation in a conversation
     *
     * @deprecated Please use the `onXyz` methods on {@link Chatbox} instead.
     */
    on(eventType: "translationToggled", handler: (event: TranslationToggledEvent) => void): void;
    /**
     * Listens for an event.
     *
     * @remarks
     * This event is only emitted when {@link ChatboxOptions.captureKeyboardEvents} is enabled. In
     * that case, it is emitted for every keypress, including regular letters typed into text fields.
     *
     * `event.isInputFocused` is true when a TalkJS input area is focused (eg the message field, the
     * search box, or adjacent buttons). When this is the case, keypresses are likely to cause changes
     * inside the chat UI. We recommend that you discard these events except when implementing global
     * shortcuts that should take effect regardless of whether the user is typing a message or
     * otherwise interacting with the chat UI using the keyboard.
     *
     * Note: by design, TalkJS does not handle special multi-key shortcuts other than those provided
     * by the user's device (eg ctrl+v for paste). This means that it is usually safe to assign
     * special behavior to unused keyboard shortcuts with one or more modifier keys (like alt, shift
     * or ctrl), even when `isInputFocused` is true.
     *
     * All other event fields are the same as the corresponding fields in the browser's
     * {@link https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent | KeyboardEvent}.
     *
     * @example Listen for `1` and `ctrl+q`
     * ```ts
     * myChatbox.on("keyup", event => {
     *   if(event.shiftKey || event.altKey || event.metaKey) {
     *     return;
     *   }
     *   if(!event.isInputFocused && event.key === "1") {
     *     // let the 1 key switch to our app's main panel, except if the user is typing
     *     myApp.selectMainPanel();
     *   }
     *   if(event.ctrlKey && event.key === "q") {
     *     // quit if the user hits ctrl+q, irrespective of whether they're typing.
     *     myApp.quit();
     *   }
     * });
     * ```
     *
     * @deprecated Please use the `onXyz` methods on {@link Chatbox} instead.
     */
    on(eventType: "keyup", handler: (event: KeyEvent) => void): void;
    /**
     * Stops emitting events registered with {@link UIBox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("sendMessage")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Chatbox} `onXyz` instead.
     */
    off(eventType: "sendMessage", handler: (event: SendMessageEvent) => void): void;
    /**
     * Stops emitting events registered with {@link UIBox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("focus")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Chatbox} `onXyz` instead.
     */
    off(eventType: "focus", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link UIBox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("blur")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Chatbox} `onXyz` instead.
     */
    off(eventType: "blur", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link UIBox.on}.
     *
     * @param eventType -
     * @param handler - The handler function must be the same handler function that was passed to `on("translationToggled")`
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Chatbox} `onXyz` instead.
     */
    off(eventType: "translationToggled", handler: () => void): void;
    /**
     * Stops emitting events registered with {@link UIBox.on}.
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Chatbox} `onXyz` instead.
     */
    off(eventType: "keyup", handler: (event: KeyEvent) => void): void;
    /**
     * @hidden
     */
    onCustomMessageAction(handler: (event: MessageActionEvent) => void): Subscription;
    /**
     * Triggers when a user launches a custom action on a message within the TalkJS UI.
     *
     * @remarks
     * To set up a custom action, you can either create it on the "Chat UI" page in your dashboard,
     * add an action button to your messages,
     * or add an action button to the `UserMessage`, `SystemMessage`,
     * or `MessageBody` components of your theme in the Theme Editor,
     * which you can access from the "Themes" page in your dashboard.
     * If an action is allowed on a particular message, it'll show up in that message's action menu.
     * The name you specify when setting up the action, is also the name you should pass in here (case sensitive).
     * The event you get contains information about the message on which the action was called, including its ID, so you can look it up later via our REST API.
     * @param action - Optional. The action you want to listen for. Omit to listen for any action.
     * @param handler - The handler to be called
     * @returns A subscription you can use to unsubscribe.
     */
    onCustomMessageAction(action: string, handler: (event: MessageActionEvent) => void): Subscription;
    /**
     * @hidden
     */
    onCustomConversationAction(handler: (event: ConversationActionEvent) => void): Subscription;
    /**
     * Triggers when a user launches a custom action on a conversation within the
     * TalkJS UI.
     *
     * @remarks
     * To set up a custom action, you can either create it on the "Chat UI" page in
     * your dashboard or add an action button to the `ChatHeader`, `MessageField`,
     * `ConversationListHeader` or `ConversationListItem` components of your theme
     * in the Theme Editor, which you can access from the "Themes" page in your dashboard.
     * If an action is allowed on a particular conversation, it'll show up in that
     * conversation's action menu. The name you specify when setting up the
     * action, is also the name you should pass in here (case sensitive). The
     * event you get contains information about the conversation on which the
     * action was called, including its ID, so you can look it up later via our
     * REST API.
     * @param action - Optional. The action you want to listen for. Omit to listen for any action.
     * @param handler - The handler to be called
     * @returns A subscription you can use to unsubscribe.
     */
    onCustomConversationAction(action: string, handler: (event: ConversationActionEvent) => void): Subscription;
    /**
     * Triggers when the user sends a message using the TalkJS UI
     */
    onSendMessage(handler: (event: SendMessageEvent) => void): Subscription;
    /**
     * Triggers when the user clicks on the "Leave conversation" action
     *
     * @remarks
     * This event triggers *before* the user actually leaves the conversation. You
     * can call `event.preventDefault()` to disallow the user from actually
     * leaving.
     *
     * This event only triggers when the user performs a Leave action from inside
     * the chat UI. Notably, when a user leaves the conversation through other
     * means (for example, they're removed from the conversation using the REST
     * API), this event does not trigger.
     */
    onLeaveConversation(handler: (event: LeaveConversationEvent) => void): Subscription;
    /**
     * Triggers when the user clicks on the "Mark as unread" action
     *
     * @remarks
     * This event triggers *before* the user actually marks the conversation as
     * unread. You can call `event.preventDefault()` to disallow the user from
     * actually marking it as unread.
     *
     * This event only triggers when the user performs a "Mark as unread" action
     * from inside the chat UI. Notably, when a user marks the conversation as
     * unread through other means (for example, via the REST API), this event does
     * not trigger.
     */
    onMarkConversationAsUnread(handler: (event: MarkConversationAsUnreadEvent) => void): Subscription;
    /**
     * Triggers when the chat UI is focussed.
     */
    onFocus(handler: () => void): Subscription;
    /**
     * Triggers when focus moves out of the chat UI.
     *
     * @remarks
     * Emits an event when the user clicks/taps anywhere outside the chat UI.
     */
    onBlur(handler: () => void): Subscription;
    /**
     * Triggers when the user toggles message translation in the TalkJS UI.
     */
    onTranslationToggled(handler: (event: TranslationToggledEvent) => void): Subscription;
    /**
     * Triggers a {@link KeyEvent} when the user releases a key.
     *
     * @remarks
     * This event is only emitted when
     * {@link ChatboxOptions.captureKeyboardEvents} is enabled. In that case, it
     * is emitted for every keypress, including regular letters typed into text
     * fields.
     *
     * Note that there's a notorious system limitation on macOS: `metaKey` is not
     * set in keyup events when hitting keystrokes (eg Cmd+p). Consider using
     * {@link UIBox.onKeydown} if you need to support `Cmd`.
     *
     * `event.isInputFocused` is true when a TalkJS input area is focused (eg the
     * message field, the search box, or adjacent buttons). When this is the case,
     * keypresses are likely to cause changes inside the chat UI. We recommend
     * that you discard these events except when implementing global shortcuts
     * that should take effect regardless of whether the user is typing a message
     * or otherwise interacting with the chat UI using the keyboard.
     *
     * Note: by design, the TalkJS UI does not handle special multi-key shortcuts
     * other than those provided by the user's device (eg ctrl+v for paste). This
     * means that it is usually safe to assign special behavior to unused keyboard
     * shortcuts with one or more modifier keys (like alt, shift or ctrl), even
     * when `isInputFocused` is true.
     *
     * All other event fields are the same as the corresponding fields in the
     * browser's
     * {@link https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent | KeyboardEvent}.
     *
     * @example Listen for `1` and `ctrl+q`
     * ```ts
     * myChatbox.onKeyup(event => {
     *   if(event.shiftKey || event.altKey || event.metaKey) {
     *     return;
     *   }
     *
     *   // let the 1 key switch to our app's main panel, except if the user is typing
     *   if(!event.isInputFocused && event.key === "1") {
     *     myApp.selectMainPanel();
     *   }
     *
     *   // quit if the user hits ctrl+q, irrespective of whether they're typing.
     *   if(event.ctrlKey && event.key === "q") {
     *     myApp.quit();
     *   }
     * });
     * ```
     */
    onKeyup(handler: (event: KeyEvent) => void): Subscription;
    /**
     * Triggers a {@link KeyEvent} when the user presses a key.
     *
     * @remarks
     * See {@link UIBox.onKeyup} for more details.
     */
    onKeydown(handler: (event: KeyEvent) => void): Subscription;
    /**
     * Puts custom HTML just above the message field.
     *
     * @remarks
     * Using HTML Panels, you can extend TalkJS UIs to have anything from credit card payments to lead
     * collection forms, or, for instance, to show the product details of a marketplace transaction
     * between your users. See our
     * {@link https://talkjs.com/docs/Guides/JavaScript/Classic/HTML_Panels/ | HTMLPanels documentation}
     * for more info.
     */
    createHtmlPanel(options: HtmlPanelOptions): Promise<HtmlPanel>;
    /**
     * Sets metadata for the current session.
     *
     * @remarks
     * <b>Note:</b> If you want to mount UI that is already hidden, set
     *  {@link ChatboxOptions.presence | presence when creating the UI} or call
     * `setPresence({ visible: false })` before calling {@link UIBox.mount}.
     *
     * Also, important to note, is that the {@link Popup} internally calls this method
     * when a user opens or closes it. `visible` is set to `true` or `false` respectively.
     *
     */
    setPresence(presence: UserPresence): void;
    /**
     * Destroys the component and removes it from the DOM
     *
     * @remarks
     * Destroys the component, removes it from the DOM and removes all event listeners it has running. Call this before removing
     * the the component container from the DOM.
     */
    destroy(): void;
    /**
     * Toggles desktop notifications
     *
     * @remarks
     * This method will keep being supported, but for new projects,
     * we recommend that you use {@link Session.setDesktopNotificationEnabled}.
     *
     * Sets desktop notification on or off. Has the same effect as toggling the
     * "Desktop notification" toggle in the TalkJS Inbox UI. Use this function to replicate that
     * toggle elsewhere in your UI if you're using TalkJS in a mode that doesn't show this toggle.
     *
     * @deprecated Please use {@link Session.setDesktopNotificationEnabled} instead.
     */
    toggleDesktopNotifications(isEnabled: boolean): void;
    /**
     * Used to control which messages are shown in the message list
     *
     * @remarks
     * Lets you filter messages depending on a type, origin or custom message attributes.
     *
     * Note: Messages are only filtered in the message list. The inbox UI's conversation feed will
     * always show the last message sent to the conversation, regardless of the message filter set.
     *
     * See {@link MessagePredicate} for all available options.
     *
     * @example Only show messages sent by users with the "admin" role
     * ```ts
     * chatbox.setMessageFilter({
     *   sender: {
     *     role: ["==", "admin"],
     *   }
     * });
     * ```
     *
     * @param filter - A predicate object that controls which messages are shown.
     */
    setMessageFilter(filter: MessagePredicate): void;
    /**
     * Enable or disable translation for a conversation.
     *
     * @param conversation - The conversation for which this should be set. If not specified, the setting will be applied to the currently selected conversation.
     * @param enabled - Whether translation should be enabled
     */
    setTranslationEnabledForConversation(conversation: string | ConversationBuilder, enabled: boolean): void;
    /**
     * Enable/disable translation by default.
     *
     * @remarks
     * This setting is applied to any conversation for which you haven't set a specific value.
     *
     * @param enabled - Whether conversations should be translated by default or not. Pass "auto" to
     *                  enable translation for conversations with users with different locales.
     */
    setTranslationEnabledDefault(enabled: boolean | "auto"): void;
    /**
     * Highlights certain words in messages
     *
     * @remarks
     * The TalkJS search feature includes the ability to highlight certain words in messages. Call
     * this method to highlight certain words without having the user invoke the search feature.
     * Call again with an empty array to disable highlighting.
     *
     * The returned {@link HighlightControls} object lets you scroll the UI to show next and previous search results.
     *
     * Note: like the search feature, this option only works on the Growth plan and up.
     *
     * Also see {@link ChatboxOptions.highlightedWords}
     */
    setHighlightedWords(words: string[]): HighlightControls;
}

/**
 * @public
 * Used as part of {@link Unreads.on}.
 */
export declare interface UnreadConversation {
    /**
     * The {@link ConversationData} of the unread conversation.
     *
     * @remarks
     * Always identical to `lastMessage.conversation`, which is maintained for
     * compatibility reasons.
     */
    conversation: ConversationData;
    /**
     * Contains the last {@link Message} for this conversation.
     */
    lastMessage: Message;
    /**
     *
     * The number of unread messages in this conversation.
     *
     * Note: Conversations with last activity before 15 June 2023 will have `unreadMessageCount` value set to 0 on initial load. It will be properly set after the next refresh
     */
    unreadMessageCount: number;
}

/**
 * This object can notify you when the amount of unread conversations changes.
 * You can't instantiate it - instead, get an instance via {@link Session.unreads}.
 *
 * @public
 */
export declare interface Unreads {
    /**
     * A "change" event is fired on startup right after TalkJS loads, as well as every time the
     * amount of unread conversations changed. The `handler` is invoked with an array of objects with
     * limited information about each conversation, see {@link UnreadConversation}.
     *
     * @remarks
     * Note that conversations where the user is a {@link https://talkjs.com/docs/Concepts/Guests/ | guest}
     * do not keep track of unread messages. This is only done for users who are added as participants.
     *
     * Related methods: {@link Unreads.off}
     *
     * @deprecated Please use {@link Unreads.onChange} instead.
     */
    on(eventType: "change", handler: (unreadConversations: UnreadConversation[]) => void): void;
    /**
     * Call this with the same `eventType` and `handler` that you used for `on` to
     * stop receiving events.
     *
     * @remarks
     * Related methods: {@link Unreads.on}
     *
     * @deprecated Please use the {@link Subscription.unsubscribe} method on the object returned by {@link Unreads.onChange} instead.
     */
    off(eventType: "change", handler: (unreadConversations: UnreadConversation[]) => void): void;
    /**
     * Triggered when the list of unread conversations changes.
     *
     * @remarks
     * A "change" event is fired on startup right after TalkJS loads, as well as every time the
     * amount of unread conversations changed. The `handler` is invoked with an array of objects with
     * limited information about each conversation, see {@link UnreadConversation}.
     *
     * Note that conversations where the user is a {@link https://talkjs.com/docs/Concepts/Guests/ | guest}
     * do not keep track of unread messages. This is only done for users who are added as participants.
     */
    onChange(handler: (unreadConversations: UnreadConversation[]) => void): Subscription;
}

/**
 * The state of a subscription after you have manually unsubscribed
 *
 * @public
 */
export declare interface UnsubscribedState {
    readonly type: "unsubscribed";
}

/**
 * A user of your app. TalkJS uses the `id` to uniquely identify this user.
 * All other fields of a User are allowed to vary over time and the TalkJS database will update its fields accordingly.
 *
 * @classic New TalkJS integrations should use {@link UserRef} via {@link Session.user|Session.user()} instead.
 * `UserRef` is part of the simpler and more powerful {@link https://talkjs.com/docs/JavaScript_Data_API/ | Data API}.
 * @public
 */
export declare class User {
    /**
     * The unique ID which is used to identify the user in TalkJS
     */
    readonly id: string;
    /**
     * The User's name which will be displayed on the TalkJS UI
     */
    readonly name: string;
    /**
     * One or more email address belonging to the User. The email addresses will be used for {@link https://talkjs.com/docs/Features/Notifications/Email_Notifications/ | Email Notifications}
     * if they are enabled.
     */
    readonly email?: string | Array<string> | null;
    /**
     * One or more phone numbers belonging to the User. The phone number will be used for {@link https://talkjs.com/docs/Features/Notifications/SMS_Notifications/ | SMS Notifications }
     * (this feature requires standard plan and up).
     */
    readonly phone?: string | Array<string> | null;
    /**
     * The default message a user sees when starting a chat with that person
     */
    readonly welcomeMessage?: string | null;
    /**
     * An optional URL to a photo which will be displayed as the user's avatar
     */
    readonly photoUrl?: string | null;
    /**
     * TalkJS supports multiple sets of settings, called "roles". These allow you to change the behavior of TalkJS for different users.
     * You have full control over which user gets which configuration.
     */
    readonly role?: string | null;
    /**
     * @deprecated Please use {@link User.role} instead.
     */
    readonly configuration?: string | null;
    /**
     * Allows you to set custom metadata for the User
     *
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    readonly custom?: {
        [name: string]: string | null;
    } | null;
    /**
     * Availability acts similarly to {@link User.welcomeMessage} but appears as a {@link https://talkjs.com/docs/Concepts/System_Messages | system message}.
     *
     */
    readonly availabilityText?: string | null;
    /**
     * The locale field expects an {@link https://www.w3.org/International/articles/language-tags/ | IETF language tag}.
     * See the {@link https://talkjs.com/docs/Features/Language_Support/#localization | localization documentation}.
     */
    readonly locale?: string | null;
    /**
     * Create a TalkJS User
     *
     * @param options
     * Use this overload to create or update user data.
     * The user is {@link https://talkjs.com/docs/Features/Security/Browser_Synchronization/ | synchronized}
     * with the TalkJS backend if they are the current user in a session.
     * If they are not the current user, and they are part of an existing conversation,
     * they will be synchronized when the UI is mounted.
     *
     * The fields `id`, `name` and `email` are required.
     * A warning will be emitted if `role` is not specified.
     *
     * Set `email` to `null` if you want to use TalkJS without email fallback.
     */
    constructor(options: UserOptions);
    /**
     * Create a TalkJS User
     *
     * @param id
     * Only use this overload if you're sure
     * that a user by the given `id` already exists in TalkJS (for instance, because you
     * synchronized it via the REST API). Otherwise use the `new User(options: object):` constructor instead.
     */
    constructor(id: string | number);
}

/**
 * The state of a user subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface UserActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot for the user, or `null` if the user does not exist yet.
     */
    readonly latestSnapshot: UserSnapshot | null;
}

/**
 * The state of a user online subscription when it is actively listening for changes
 *
 * @public
 */
export declare interface UserOnlineActiveState {
    readonly type: "active";
    /**
     * The most recently received snapshot
     */
    readonly latestSnapshot: UserOnlineSnapshot | null;
}

/**
 * A snapshot of a user's online status at a given moment in time.
 *
 * @remarks
 * Snapshots are immutable and we try to reuse them when possible. You should only re-render your UI when `oldSnapshot !== newSnapshot`.
 *
 * @public
 */
export declare interface UserOnlineSnapshot {
    /**
     * The user this snapshot relates to
     */
    readonly user: UserSnapshot;
    /**
     * Whether the user is connected right now
     *
     * @remarks
     * Users are considered connected whenever they have an active websocket connection to the TalkJS servers.
     * In practice, this means:
     *
     * People using the {@link https://talkjs.com/docs/JavaScript_Data_API/ | JS Data API} are considered connected if they are subscribed to something, or if they sent a request in the last few seconds.
     * Creating a `TalkSession` is not enough to appear connected.
     *
     * People using {@link https://talkjs.com/docs/UI_Components/ | Components}, are considered connected if they have a UI open.
     *
     * People using the {@link https://talkjs.com/docs/UI_Components/JavaScript/Classic/ | JavaScript SDK}, {@link https://talkjs.com/docs/UI_Components/React/Classic/ | React SDK}, {@link https://talkjs.com/docs/UI_Components/React_Native/ | React Native SDK}, or {@link https://talkjs.com/docs/UI_Components/Flutter/ | Flutter SDK} are considered connected whenever they have an active `Session` object.
     */
    readonly isConnected: boolean;
}

/**
 * A subscription to the online status of a user
 *
 * @remarks
 * Get a UserOnlineSubscription by calling {@link UserRef.subscribeOnline}.
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface UserOnlineSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot: UserOnlineSnapshot | null`
     * `null` means the user does not exist.
     *
     * When `type` is "error", includes the `error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | UserOnlineActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     *
     * @remarks
     * Wait for this promise if you want to perform some action as soon as the subscription is active.
     *
     * The promise rejects if the subscription is terminated before it connects.
     */
    readonly connected: Promise<UserOnlineActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * @public
 */
export declare interface UserOptions {
    /**
     * The unqiue ID which is used to identify the user in TalkJS
     */
    id: string | number;
    /**
     * The User's name which will be displayed on the TalkJS UI
     */
    name: string;
    /**
     * One or more email address belonging to the User. The email addresses will be used for {@link https://talkjs.com/docs/Features/Notifications/Email_Notifications/ | Email Notifications}
     * if they are enabled.
     * @remarks
     * Set to `null` to delete the existing value(s) (if any). When omitted or `undefined`, the existing value(s) remain unchanged.
     */
    email?: string | Array<string> | null;
    /**
     * One or more phone numbers belonging to the User. The phone number will be used for {@link https://talkjs.com/docs/Features/Notifications/SMS_Notifications/ | SMS Notifications }
     * (this feature requires standard plan and up).
     * @remarks
     * Set to `null` to delete the existing value(s) (if any). When omitted or `undefined`, the existing value(s) remain unchanged.
     */
    phone?: string | Array<string> | null;
    /**
     * An optional URL to a photo which will be displayed as the user's avatar
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    photoUrl?: string | null;
    /**
     * The default message a user sees when starting a chat with that person
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     *
     * Welcome messages are rendered in the UI as messages, but they are not real messages.
     * This means they do not appear when you list messages using the REST API or JS Data API, and you cannot reply or react to them.
     */
    welcomeMessage?: string | null;
    /**
     * TalkJS supports multiple sets of settings, called "roles". These allow you to change the behavior of TalkJS for different users.
     * You have full control over which user gets which configuration.
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    role?: string | null;
    /**
     * @deprecated Please use {@link UserOptions.role} instead.
     */
    configuration?: string | null;
    /**
     * Allows you to set custom metadata for the User
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom?: {
        [name: string]: string | null;
    } | null;
    /**
     * Availability acts similarly to {@link User.welcomeMessage} but appears as a {@link https://talkjs.com/docs/Concepts/System_Messages | system message}.
     *
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     *
     * @deprecated Please use {@link Conversation.welcomeMessages} instead.
     */
    availabilityText?: string | null;
    /**
     * The locale field expects an {@link https://www.w3.org/International/articles/language-tags/ | IETF language tag}.
     * See the {@link https://talkjs.com/docs/Features/Language_Support/#localization | localization documentation}.
     *
     * @remarks
     * Set to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    locale?: string | null;
}

/**
 * @public
 */
export declare interface UserPresence {
    /**
     * Manually sets the information about the visibility of TalkJS.
     * This is useful when TalkJS is hidden with CSS. TalkJS will assume that UIs
     * marked `visible: false` cannot be seen, and thus messages arriving on this UI will
     * not be marked as read until you set `visible` to true again.
     * @remarks
     * When omitted or `undefined`, the existing value remains unchanged.
     */
    visible?: boolean;
    /**
     * This is an additional parameter to store the custom fields that you
     * may want to use in the REST API call.
     * @remarks
     * Set any property to `null` to delete the existing value (if any). When omitted or `undefined`, the existing value remains unchanged.
     */
    custom?: {
        [name: string]: string | null;
    } | null;
}

/**
 * References the user with a given user ID.
 *
 * @remarks
 * Used in all Data API operations affecting that user, such as creating the user, fetching or updating user data, or adding a user to a conversation.
 * Created via {@link Session.user}.
 *
 * @public
 */
export declare interface UserRef {
    /**
     * The ID of the referenced user.
     *
     * @remarks
     * Immutable: if you want to reference a different user, get a new UserRef instead.
     */
    readonly id: string;
    /**
     * Fetches a snapshot of the user.
     *
     * @remarks
     * This contains all of a user's public information.
     * Fetching a user snapshot doesn't require any permissions. You can read the public information of any user.
     * Private information, such as email addresses and phone numbers, aren't included in the response.
     *
     * @returns A snapshot of the user's public attributes, or null if the user doesn't exist.
     */
    get(): Promise<UserSnapshot | null>;
    /**
     * Sets properties of this user. The user is created if a user with this ID doesn't already exist.
     *
     * @remarks
     * `name` is required when creating a user. The promise will reject if you don't provide a `name` and the user does not exist yet.
     *
     * @returns A promise that resolves when the operation completes. The promise will reject if the request is invalid or if client-side user syncing is disabled.
     */
    set(params: SetUserParams): Promise<void>;
    /**
     * Creates a user with this ID, or does nothing if a user with this ID already exists.
     *
     * @remarks
     * If the user already exists, this operation is still considered successful and the promise will still resolve.
     *
     * @returns A promise that resolves when the operation completes. The promise will reject if client-side user syncing is disabled and the user does not already exist.
     */
    createIfNotExists(params: CreateUserParams): Promise<void>;
    /**
     * Subscribe to this user's state.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called when the user is created or the snapshot changes.
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     *
     * @returns A subscription to the user
     */
    subscribe(onSnapshot?: (event: UserSnapshot | null) => void): UserSubscription;
    /**
     * Subscribe to this user and their online status.
     *
     * @remarks
     * While the subscription is active, `onSnapshot` will be called when the user is created or the snapshot changes (including changes to the nested UserSnapshot).
     *
     * Remember to call `.unsubscribe` on the subscription once you are done with it.
     *
     * @returns A subscription to the user's online status
     */
    subscribeOnline(onSnapshot?: (event: UserOnlineSnapshot | null) => void): UserOnlineSubscription;
}

/**
 * A snapshot of a user's attributes at a given moment in time.
 *
 * @remarks
 * Users also have private information, such as email addresses and phone numbers, but these are only exposed on the {@link https://talkjs.com/docs/REST_API/ | REST API}.
 *
 * Snapshots are immutable and we try to reuse them when possible. You should only re-render your UI when `oldSnapshot !== newSnapshot`.
 *
 * @public
 */
export declare interface UserSnapshot {
    /**
     * The unique ID that is used to identify the user in TalkJS
     */
    readonly id: string;
    /**
     * The user's name, which is displayed on the TalkJS UI
     */
    readonly name: string;
    /**
     * Custom metadata you have set on the user
     */
    readonly custom: Record<string, string>;
    /**
     * An {@link https://www.w3.org/International/articles/language-tags/ | IETF language tag}.
     * For more information, see: {@link https://talkjs.com/docs/Features/Language_Support/#localization | Localization}.
     *
     * When `locale` is null, the app's default locale will be used
     */
    readonly locale: string | null;
    /**
     * An optional URL to a photo that is displayed as the user's avatar
     */
    readonly photoUrl: string | null;
    /**
     * TalkJS supports multiple sets of settings for users, called "roles". Roles allow you to change the behavior of TalkJS for different users.
     * You have full control over which user gets which configuration.
     */
    readonly role: string;
    /**
     * The default message a person sees when starting a chat with this user
     *
     * @remarks
     * Welcome messages are rendered in the UI as messages, but they are not real
     * messages. This means they do not appear when you list messages using the
     * REST API or JS Data API, and you cannot reply or react to them.
     *
     * Note: User welcome messages are only supported by the Classic SDKs, and in
     * the Components-based SDKs, this field is ignored. To show welcome messages
     * in the Components-based SDK, see
     * {@link https://talkjs.com/docs/Guides/React/Welcome_Messages/ | Welcome Messages}.
     *
     * @deprecated
     */
    readonly welcomeMessage: string | null;
}

/**
 * A subscription to a specific user
 *
 * @remarks
 * Get a UserSubscription by calling {@link UserRef.subscribe}
 *
 * Remember to `.unsubscribe` the subscription once you are done with it.
 *
 * @public
 */
export declare interface UserSubscription {
    /**
     * The current state of the subscription
     *
     * @remarks
     * An object with the following fields:
     *
     * `type` is one of "pending", "active", "unsubscribed", or "error".
     *
     * When `type` is "active", includes `latestSnapshot: UserSnapshot | null`. It is the current state of the user, or null if they don't exist.
     *
     * When `type` is "error", includes the `error: Error` field. It is a JS `Error` object explaining what caused the subscription to be terminated.
     */
    state: PendingState | UserActiveState | UnsubscribedState | ErrorState;
    /**
     * Resolves when the subscription starts receiving updates from the server.
     */
    readonly connected: Promise<UserActiveState>;
    /**
     * Resolves when the subscription permanently stops receiving updates from the server.
     *
     * @remarks
     * This is either because you unsubscribed or because the subscription encountered an unrecoverable error.
     */
    readonly terminated: Promise<UnsubscribedState | ErrorState>;
    /**
     * Unsubscribe from this resource and stop receiving updates.
     *
     * @remarks
     * If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
     */
    unsubscribe(): void;
}

/**
 * A FileBlock variant for a video attachment, with additional video-specific metadata.
 *
 * @remarks
 * You can identify this variant by checking for `subtype: "video"`.
 *
 * Includes metadata about the height and width of the video in pixels, and the duration of the video in seconds, where available.
 *
 * Videos that you upload with the TalkJS UI will include the dimensions and duration as long as the sender's browser can preview the file.
 * Videos that you upload with the REST API or {@link Session.uploadVideo} will include this metadata if you specified it when uploading.
 * Videos attached in a reply to an email notification will not include any metadata.
 *
 * @public
 */
export declare interface VideoBlock {
    readonly type: "file";
    readonly subtype: "video";
    /**
     * An encoded identifier for this file. Use in {@link SendFileBlock} to send this video in another message.
     */
    readonly fileToken: FileToken;
    /**
     * The URL where you can fetch the file.
     */
    readonly url: string;
    /**
     * The size of the file in bytes.
     */
    readonly size: number;
    /**
     * The name of the video file, including file extension.
     */
    readonly filename: string;
    /**
     * The width of the video in pixels, if known.
     */
    readonly width?: number;
    /**
     * The height of the video in pixels, if known.
     */
    readonly height?: number;
    /**
     * The duration of the video in seconds, if known.
     */
    readonly duration?: number;
}

/**
 * @public
 */
export declare interface VideoFileMetadata {
    /**
     * The name of the file including extension.
     */
    filename: string;
    /**
     * The width of the video in pixels, if known.
     */
    width?: number;
    /**
     * The height of the video in pixels, if known.
     */
    height?: number;
    /**
     * The duration of the video in seconds, if known.
     */
    duration?: number;
}

/**
 * A FileBlock variant for a voice recording attachment, with additional voice-recording-specific metadata.
 *
 * @remarks
 * You can identify this variant by checking for `subtype: "voice"`.
 *
 * The same file could be uploaded as either a voice block, or as an {@link AudioBlock}.
 * The same data will be available either way, but they will be rendered differently in the UI.
 *
 * Includes metadata about the duration of the recording in seconds, where available.
 *
 * Voice recordings done in the TalkJS UI will always include the duration.
 * Voice recordings that you upload with the REST API or {@link Session.uploadVoice} will include this metadata if you specified it when uploading.
 *
 * Voice recordings will never be taken from a reply to an email notification.
 * Any attached audio file will become an {@link AudioBlock} instead of a voice block.
 *
 * @public
 */
export declare interface VoiceBlock {
    readonly type: "file";
    readonly subtype: "voice";
    /**
     * An encoded identifier for this file. Use in {@link SendFileBlock} to send this voice recording in another message.
     */
    readonly fileToken: FileToken;
    /**
     * The URL where you can fetch the file
     */
    readonly url: string;
    /**
     * The size of the file in bytes
     */
    readonly size: number;
    /**
     * The name of the file, including file extension
     */
    readonly filename: string;
    /**
     * The duration of the voice recording in seconds, if known
     */
    readonly duration?: number;
}

/**
 * @public
 */
export declare interface VoiceRecordingFileMetadata {
    /**
     * The name of the file including extension.
     */
    filename: string;
    /**
     * The duration of the recording in seconds, if known.
     */
    duration?: number;
}

export { }
