Custom Addon Builder

In addition to simply embedding your website in Userlike, it’s also possible to use the Custom Add-on Frontend API to communicate between the Message Center and your application. For example, it’s possible to get real-time data from Userlike or update Userlike’s contact information from your application.

Getting started

To define a custom add-on, go to Settings > Add-ons > Custom Add-ons and click on the Add button.
You can then specify the name of the add-on, the URL where it is hosted, and the URL of the icon that will be displayed in the conversation details sidebar.
It is recommended to use an icon with a 1:1 aspect ratio, a transparent background and no padding for optimal results.

Content policy

To ensure cross-origin usage of your add-on, set a
plain text
frame-ancestors
plain text
Content-Policy
directive.
Additional information can be found at the following link:
Example:
plain text
Content-Security-Policy: frame-ancestors https://userlike.com;

Local development

If the content policy is set correctly, you can develop your add-on on a local server and use its URL, such as 127.0.0.1.

Life-cycle

Custom add-ons are loaded as soon as the operator opens a conversation.
Once the operator leaves or changes the conversation, the add-on is unmounted, resulting in the loss of its state.

Listening to Message Center events

Communication with your add-on will be done through the JavaScript
.
Upon loading your add-on, we will provide you with initial events, including contact information, conversation information, operator information and the transcript.
Continue to listen for incoming events using the postMessage API to receive real-time data.
Example:
plain text
window.addEventListener("message", (message) => { if (message.origin !== "https://userlike.com") return; switch (message.data.name) { case "contact_information": setContactInfo(message.data.payload); break; } });

Triggering Message Center actions

Your add-on can trigger actions within the Message Center, such as replacing the chat input text or displaying a toast.
Example:
plain text
window.parent.postMessage( { name: "toast", payload: { message: "Hello from the add-on!", status: "warning", }, }, "https://userlike.com" );

Events

Transcript

This event is triggered once when the add-on becomes active and every time a new text message is added to the conversation.
It includes all the messages the operator can see, depending on how much they've scrolled back in the conversation's history.
plain text
type Sender = { type: "contact" | "operator"; }; type TextMessage = { type: "message"; body: string; textFormat: "markdown_v1" | "plain_text"; sender: Sender; }; type TranscriptEvent = { name: "transcript"; payload: { transcript: TextMessage[]; }; }; const example: TranscriptEvent = { name: "transcript", payload: { transcript: [ { sender: { type: "contact" }, body: "Hello, I have a question about your product.", textFormat: "plain_text", type: "message", }, { sender: { type: "operator" }, body: "Hello, how can I help you?", textFormat: "plain_text", type: "message", }, ], }, };

Contact information

This event is triggered once when the add-on becomes active and every time the contact information is updated.
Note that the contact information may be null if not specified by the operator or the contact.
plain text
type ContactEvent = { name: "contact_information"; payload: { id: string; name: string | null; email: string | null; locale: string | null; mobileNumber: string | null; phoneNumber: string | null; salutation: "mr" | "ms" | "pr" | "prof" | null; street: string | null; city: string | null; country: string | null; company: string | null; gender: "m" | "f" | "d" | null; customFieldData: Record<string, string | string[] | null>; }; }; const example: ContactEvent = { name: "contact_information", payload: { id: "1111", name: "Jane Doe", email: "jane@gmail.com", locale: "en_US", mobileNumber: "+325920392947", phoneNumber: "+325920392947", salutation: "ms", street: "Aachenerstr. 7000", city: "Köln", country: "DE", company: "Userlike", gender: null, custom_field_data: null, }, };

Conversation

This event is triggered once when the add-on becomes active and every time the conversation information is updated.
It contains meta information about the current conversation.
Note that some information may be null.
plain text
type ConversationEvent = { name: "conversation_information"; payload: { id: string | null; topics: { text: string }[]; locale: string | null; subject: string | null; customFieldData: Record<string, string | string[] | null>; }; }; const example: ConversationEvent = { name: "conversation_information", payload: { id: "1111", topics: [{ text: "Support" }, { text: "Support" }], locale: "en_US", subject: "IT Support", customFieldData: null, }, };

Operator

This event is triggered once when the add-on becomes active and every time the operator information is updated.
plain text
type OperatorEvent = { name: "operator_information"; payload: { id: string; name: string; email: string; locale: string; }; }; const example: OperatorEvent = { name: "operator_information", payload: { id: "1111", name: "Jane Doe", email: "jane@userlike.com", locale: "en_US", }, };

Actions

Actions refer to events that can be triggered by the add-on to perform specific tasks in the Message Center.

Replace chat input

Send text to the operator's chat input.
plain text
type ReplaceChatInputAction = { name: "replace_chat_input"; payload: { textFormat: "plain_text" | "markdown_v1"; message: string; }; }; const example: ReplaceChatInputAction = { name: "replace_chat_input", payload: { textFormat: "markdown_v1", message: "For more information [check out Userlike](https://userlike.com).", }, };

Toast

Display a
.
plain text
type ToastAction = { name: "toast"; payload: { status: "info" | "error" | "success" | "warning"; message: string; }; }; const example: ToastAction = { name: "toast", payload: { status: "error", message: "An unexpected error has occurred.", }, };

Update contact information

Partially update contact information.
plain text
type UpdateContactAction = { name: "update_contact_information"; payload: Partial<{ name: string | null; email: string | null; locale: string | null; mobileNumber: string | null; phoneNumber: string | null; salutation: "mr" | "ms" | "pr" | "prof" | null; street: string | null; city: string | null; country: string | null; company: string | null; gender: "m" | "f" | "d" | null; customFieldData: Record<string, string | string[] | null>; }>; }; const example: UpdateContactAction = { name: "update_contact_information", payload: { name: "Jane Doe", customFieldData: { "dd23-4dfd-f23f-s3rf": "Hello world!" }, }, };

Update conversation information

Update conversation information.
plain text
type UpdateConversationAction = { name: "update_conversation_information"; payload: { customFieldData: Record<string, string | string[] | null>; }; }; const example: UpdateConversationAction = { name: "update_conversation_information", payload: { customFieldData: { "dd23-4dfd-f23f-s3rf": "Hello world!" }, }, };