UNPKG

talkjs

Version:

Build the perfect messaging experience in 10 minutes.

1,275 lines (1,242 loc) 245 kB
/** * A node in a {@link TextBlock} that renders its children as a clickable {@link https://talkjs.com/docs/Features/Customizations/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 { type: "actionButton"; /** * The name of the custom action to invoke when the button is clicked. */ action: string; /** * The parameters to pass to the custom action when the button is clicked. */ params: Record<string, string>; 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/Features/Customizations/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 { type: "actionLink"; /** * The name of the custom action to invoke when the link is clicked. */ action: string; /** * The parameters to pass to the custom action when the link is clicked. */ params: Record<string, string>; 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 { type: "file"; subtype: "audio"; /** * An encoded identifier for this file. Use in {@link SendFileBlock} to send this file in another message. */ fileToken: FileToken; /** * The URL where you can fetch the file */ url: string; /** * The size of the file in bytes */ size: number; /** * The name of the audio file, including file extension */ filename: string; /** * The duration of the audio in seconds, if known */ 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/Reference/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 { type: "autoLink"; /** * The URL to open when a user clicks this node. */ url: string; /** * The text to display in the link. */ 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 { type: "bulletList"; 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 { type: "bulletPoint"; 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 "rtl". */ dir?: "rtl" | "ltr"; /** * 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/Features/Themes/Legacy_Themes_(limited_CSS)/ | 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/Features/Themes/Legacy_Themes_(limited_CSS)/ | 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 { type: "codeSpan"; 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[] ]; /** * 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; 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 { 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). */ 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. */ 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/Reference/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. */ 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/Reference/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/Reference/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/Reference/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/Reference/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.subject}. */ photoUrl: string | null; /** * One or more welcome messages that will display to the user as a SystemMessage */ 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"; }>; } /** * The state of a conversation list subscription when it is actively listening for changes * * @public */ export declare interface ConversationListActiveState { type: "active"; /** * The most recently received snapshot for the conversations */ latestSnapshot: ConversationSnapshot[]; /** * True if `latestSnapshot` contains all conversations you are in. * Use {@link ConversationListSubscription.loadMore} to load more. */ 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. * * @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. */ 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. */ terminated: Promise<UnsubscribedState | ErrorState>; /** * Expand the window to include older conversations * * @remarks * Calling `loadMore` multiple times in parallel will still only load one page of conversations. * * @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 conversation with a given conversation ID, from the perspective of the current user. * * @remarks * Used in all Data API operations affecting that conversation, such as fetching or updating conversation attributes. * Created via {@link Session.conversation|Session.conversation()}. * * @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 {@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 {@linkcode 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. * To fetch the most recent messages in this conversation, use {@link ConversationRef.subscribeMessages} instead. * * @param id - The ID of the message that you want to reference * @returns A {@linkcode 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 your participation in it. * * @remarks * The conversation is created if a conversation with this ID doesn't already exist. * You are added as a participant if you are not already a participant in the conversation. * * @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 * Initially, you will be subscribed to the 30 most recent messages and any new messages. * Call `loadMore` to load additional older messages. * * 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 is null if you are not a participant in the conversation (including when the conversation doesn't exist) */ subscribeMessages(onSnapshot?: (snapshot: MessageSnapshot[] | null, loadedAll: boolean) => void): MessageSubscription; /** * Subscribes to the participants in the conversation. * * @remarks * Initially, you will be subscribed to the 10 participants who joined most recently, and any new participants. * Call `loadMore` to load additional older participants. * * 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 is null if you are not a participant in the conversation (including when the conversation doesn't exist) */ 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) */ 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) */ 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(); * * // Don't mark as typing more than once every 5s * 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>; } /** @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. 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 */ id: string; /** * Contains the conversation subject, or `null` if the conversation does not have a subject specified. */ 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. */ photoUrl: string | null; /** * One or more welcome messages that will display to the user as a SystemMessage */ welcomeMessages: string[]; /** * Custom metadata you have set on the conversation */ custom: Record<string, string>; /** * The date that the conversation was created, as a unix timestamp in milliseconds. */ createdAt: number; /** * The date that the current user joined the conversation, as a unix timestamp in milliseconds. */ joinedAt: number; /** * The last message sent in this conversation, or null if no messages have been sent. */ lastMessage: MessageSnapshot | null; /** * The number of messages in this conversation that the current user hasn't read. */ 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. */ 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. */ 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. */ isUnread: boolean; /** * The current user's permission level in this conversation. */ 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