Docs Pricing

Roomlio Embed JS API

BASICS

Embedding a room on your site is as simple as copy and pasting the embed code from the settings page into your site’s HTML. Some javascript will run on your site that will add a secure iframe containing your room where your users can begin conversing with others.

The embed code consists of three parts:

  1. A Roomlio div that you will place where you want the room to show (we offer different modes that don’t require you to add a div to your HTML).
  2. Two Roomlio javascript method calls, rml('config') and either rml('register') or rml('registerSecure'). rml('config') is where you can make modifications to your room on the client side (position, languages, styles, etc). rml('register') or rml('registerSecure') notifies our backend about the user and room so Roomlio will be ready to send and receive messages.
  3. The Roomlio javascript that runs the room on your site.

That’s it! Keep on reading below to learn more specifics about embedding a room onto your site. Please don't hesitate to reach out to Roomlio support if you have any question or need some help.

AUTHENTICATION

Roomlio provides two authentication modes. Simple and Secure (advanced)

Simple mode (i.e. calling rml('register')) is useful for testing out Roomlio and some use cases where you don't need to be absolutely sure a user is who they say they are.

Secure Auth mode (i.e. calling rml('registerSecure')) is highly recommended for production environments where you need to guarantee the authenticity of users. Since we use a javascript API to register the users, when not using secure mode nothing prevents a malicious user from pretending to be another user by using a browser's dev console. To implement Secure mode, use the shared HMAC secret key (provided in the Embed Code tab of the settings page for your widget) on your backend to generate a HMAC hash before registering the user. Base64 encode the generated HMAC hash and then pass the result to our rml('registerSecure') API call. If all this sounds confusing, make sure to look at the examples we provide in the Embed Code tab for your widget for securely generating a HMAC hash in most of the popular server-side programming languages. IMPORTANT: treat your HMAC secret key like a password or API secret key, because it is a secret that should not be made public.

Please don't hesitate to reach out to Roomlio support for help.

METHODS

Roomlio provides you with API methods that allow you to configure your rooms, pass in your user information, and more.

rml('config')

Use this to configure your Roomlio room. rml('config') must be called prior to rml('register'). This api call allows you to dynamically set configuration for widget. If values are not set here, we use the settings from the Roomlio App for the widget called by the embed code. Reasons you may want to set the configuration values dynamically would be to support multiple languages, change labels programatically and anything else you want to customize with code.

NOTE: Must be called before you call rml('register') or rml('registerSecure').

  • pk
    The pk is your "publishable key" for your Roomlio account. It identifies your embed code with your Roomlio account. It is not a secret value, but it is unique per Roomlio account. To fetch your pk select the "Get Embed Code" link for the appropriate widget on the Settings page. In the Embed Code tab you will find the pk in the Client Embed Code rml('config') call HTML.

    NOTE: Required when you set embedPosition: 'inline'.

  • roomElementID
    The "id" of the div that you have in your markup that Roomlio will replace with an embedded room. This value must be the same on all rml calls for the same widget. When embedPosition is set to bottomRight, bottomLeft, dockRight, or dockLeft, this value still needs to be present, but you do not need a corresponding div in your markup with that ID.
  • options:embedPosition
    embedPosition can be inline, bottomRight, bottomLeft, dockRight, or dockLeft.
    inlineInserts a roomlio room where you tell Roomlio to place it. In order to communicate to Roomlio where to insert the inline room, you must put a div in the page with the ID that matches the ID passed in roomElementID.
    bottomRightDisplays the embedded room in the bottom right of your webpage. By default, a chip/tab (see collapsedMode below) will appear when the room is collapsed that can be used to open the room when selected. The room will be "on top" of your page; open or collapsed.
    bottomLeftInserts the embedded room in the bottom left of your webpage. By default, a chip/tab (see collapsedMode below) will appear when the room is collapsed that can be used to open the room when selected. The room will be "on top" of your page; open or collapsed.
    dockRightTells Roomlio to put the embedded room on the right side spanning the entire height of the page. An open room will shift your page over to the left and will sit on the same plain as your page. By default, a chip/tab (see collapsedMode below) will appear when the room is collapsed that can be used to open the room when selected. The chip/tab will be "on top" of your page.
    dockLeftTells Roomlio to put the embedded room on the left side spanning the entire height of the page. An open room will shift your page over to the right and will sit on the same plain as your page. By default, a chip/tab (see collapsedMode below) will appear when the room is collapsed that can be used to open the room when selected. The chip/tab will be "on top" of your page.

    NOTE: For all embedPositions, with the exception of inline, you can hide the default chip/tab (see collapsedMode below) and use your own button/link in combination with our JS API to open and close it.

  • options:collapsedMode
    Style of the room when it's collapsed (i.e. closed). chip, tab, and hidden are the options. hidden will hide the default chip/tab in case you want to use your own button/link in combination with our JS API to open and close it. Not applicable when the embedPosition is inline.
  • options:collapsedModeOnlineLabel
    The online label of the collapsed room. Not applicable when the embedPosition is inline or collapsedMode is set to hidden.
  • options:collapsedModeOfflineLabel
    The offline label of the collapsed room. Not applicable when the embedPosition is inline or collapsedMode is set to hidden.
  • options:startHidden
    Will hide the room when the page loads. Handy when you want your users to select a custom button/link in your UI to reveal the room. This will require you to use the rml('show') API call when your custom button/link is selected.
  • options:autoExpand
    Auto expand a collapsed room when a new message comes into the room. Not applicable when the embedPosition is inline or collapsedMode is set to hidden. Defaults to true.
  • options:chatLayout
    This option changes the position of the room's messages. Choose between stacked and sideBySide. stacked messages are left justified and stack on top of each other as they come into the room. The sideBySide layout places the user's messages on the right side of the room and everyone else's on the left side. Default is stacked.
  • options:showGreetingMessage
    (optional) Set to false if you don't want to render the greeting message (the first message shown in a room). Defaults to true.
  • options:showRoomMemberList
    (optional) Set to false if you don't want to render the room member list chip. Defaults to true.
  • options:unfocusedUnreadAlert
    (optional) Set to true if you want to render a visual alert in embedded room when the room has a new message and is not in focus. Default is false. The alert will disappear after the user focuses on the room.
  • options:unfocusedUnreadAlertMessage
    (optional) Message on the unread message alerts above. Defaults to "Unread Messages".
  • options:unfocusedUnreadAlertFlashTime
    (optional) The time in seconds before the unread alert flashes. Default is 30 seconds. Set to large number if you don't want flashing alerts.
  • options:greetingMessageUsername
    (optional) This is the username displayed in the greeting message. (first message displayed to a user on an embedded chat room).
  • options:greetingMessage
    (optional) The first messages shown when a user opens an embedded chat room.
  • options:offlineGreetingMessage
    (optional) Text shown above the offline message form telling the user that you're offline.
  • options:offlineMessageFields
    (optional) You can change the labels of the offline form fields, make them required or not-required, and show or hide them. Each field has a label, required, and enabled property that can be adjusted. The presence of offlineMessageFields in the rml('config') call will override all fields set in your widget's "Offline Mode" tab in the app settings. An example of the offlineMessageFields object can be found in the rml('config') code block.
  • options:offlineSendButton
    (optional) Text of the offline message form submit button.
  • options:offlineThankYou
    (optional) Message displayed in the room after a visitor submits the offline form.
  • options:offlineForwardingEmail
    (optional) Email to forward offline messages.
  • options:offlineSubject
    (optional) Subject of the email sent to the offlineForwardingEmail.
  • options:selfIdentifyGreetingMsg
    (optional) Text shown above the self/user identify form telling the user about the form.
  • options:selfIdentifyFormFields
    (optional) You can change the labels of the self/user identify form fields, make them required or not-required, and show or hide them. Each field has a label, required, and enabled property that can be adjusted. The presence of selfIdentifyFormFields in the rml('config') call will turn on the form and override all fields set in your widget's "User Identify Form" tab in the app settings. An example of the selfIdentifyFormFields object can be found in the rml('config') code block. displayName, first, last, email, opt1, and opt2 are the only fields that can be used. You can change the label to fit your scenario.

    NOTE: selfIdentifyFormFields is only for the insecure register call, rml('register'), and will be ignored if used with rml('registerSecure').

    NOTE: opt1 and opt2 will be displayed in the room's user info sidebar.

    NOTE: Do not supply any user options (i.e. userID, displayName, traits, etc) in the rml('register') API call if using self identify since the register call, which is called everytime the page loads, will override any matching fields provided in the self identify form.

  • options:selfIdentifyButtonLabel
    (optional) Text of the self/user identify form submit button.
  • options:topBarNotificationsToggle
    (optional) Display an email notifications toggle in the room's top bar. Defaults to true.

    NOTE: Only displays if the user has an email assigned to their account. Either send in their email in the rml('register') call or use the self identify feature to capture your user's email.

  • options:topBarNotificationsToggleType
    (optional) Use either a switch or bell icon to toggle email notifications on or off. topBarNotificationsToggle needs to be true for this setting to work. Defaults to switch.
  • options:roles
    (optional) You can define a set of user roles that will be displayed next to your user's message display name (aka "role chip"). You can customize each role chip's appearance in this roles object. The roles object just defines which roles will be available. You will have to include a role option when you register your user in either the rml('register') or rml('registerSecure') API call. For example if you have a "staff" role defined in this roles object (like the one in the supplied code block example) you would include role: 'staff' in the options object of your register call.

    NOTE: Name is the only required field for each role. The other field values are standard CSS values.

    name(required) Name of the role that will be displayed in the role chip
    backgroundColor(optional) Background color of role chip. Default is #aaaaaa.
    color(optional) Font color of role chip text. Default is #ffffff.
    fontSize(optional) Font size of role chip text. Default is 10px.
    fontFamily(optional) Font family of role chip text. Default is -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, Ubuntu, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol.
    borderRadius(optional) Border radius of role chip. Default is 2px.
    padding(optional) Padding around role chip. Default is 0 3px 1px.
  • options:styles
    (optional) You can override certain styles in the embedded room. Here are the allowed overrides:
    --rml-btn-primary-background-colorBackground color of primary buttons (i.e. offline form submit button)
    --rml-btn-primary-background-color-hoverBackground color of hovered primary buttons
    --rml-btn-primary-background-color-activeBackground color of selected primary buttons
    --rml-btn-primary-text-colorText color of primary buttons
    --rml-btn-secondary-background-colorBackground color of secondary buttons (i.e. message edit buttons)
    --rml-btn-secondary-background-color-hoverBackground color of a hovered secondary buttons
    --rml-btn-secondary-background-color-activeBackground color of selected/active secondary buttons
    --rml-btn-secondary-text-colorText color of secondary buttons
    --rml-collapsed-background-colorBackground color of the chip or tab of the collapsed room
    --rml-collapsed-background-color-hoverBackground color of the hovered chip or tab of the collapsed room
    --rml-collapsed-background-color-activeBackground color of the selected/active chip or tab of the collapsed room
    --rml-collapsed-text-colorText color of the chip or tab of the collapsed room
    --rml-font-familyFont-family for the room
    --rml-icon-themeChoose between dark or light themed icons in the room
    --rml-link-colorColor of links and link URLs
    --rml-link-color-hoverColor of hovered links and link URLs
    --rml-msg-text-colorColor of the msg text
    --rml-msg-background-colorColor of the msg background
    --rml-msg-background-color-hoverBackground color of a hovered msg
    --rml-msg-system-text-colorColor of the msg system text (i.e. timestamp)
    --rml-msg-system-text-background-colorBackground color of the msg system text
    --rml-msg-system-font-familyFont family of the msg system text
    --rml-msg-system-font-sizeFont size of the msg system text
    --rml-msg-system-border-radiusBorder radius of the msg system text
    --rml-ui-chrome-background-colorBackground color of the room chrome
    --rml-ui-chrome-text-colorText color of the room chrome
    --rml-ui-chrome-active-background-colorActive background color of elements in the room chrome
    --rml-ui-chrome-active-text-colorActive text color of elements in the room chrome
    --rml-unfocused-unread-background-colorBackground color of the alert that displays if the room has a new message and isn't focused.
    Only applies when unfocusedUnreadAlert: true
    --rml-unfocused-unread-colorText color of the alert that displays if the room has a new message and isn't focused.
    Only applies when unfocusedUnreadAlert: true
    --rml-side-by-side-them-text-colorText color of other users' messages.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-them-link-colorText color of other users' links.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-them-background-colorBackground color of other users' messages.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-me-text-colorText color of the user's messages.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-me-link-colorText color of the user's links.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-me-background-colorBackground color of the user's messages.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-border-radiusBorder radius for all side-by-side messages.
    Only applies when chatLayout: 'sideBySide'
    --rml-side-by-side-paddingPadding on all side-by-side messages.
    Only applies when chatLayout: 'sideBySide'

    NOTE: styles keys and values need to be strings. Styles that have color values can be hexidecimal, rgb, rgba, hsl, or color keywords (i.e. just like CSS).

    NOTE: --rml-collapsed-... overrides do not apply to inline rooms (aka embedPosition: 'inline').

    NOTE: CSS styles will not work for --rml-icon-theme

    NOTE: If you would like to override something not in this list, feel free to reach out and request an override!

rml('config', {
  pk: '<your pk here>', // REQUIRED 
  roomElementID: 'rml-room-1', // REQUIRED only if embedPosition: 'inline'
  widgetID: '<your widgetID here>',
  options: {
    embedPosition: 'inline', // 'inline', 'bottomRight', 'bottomLeft', 'dockRight', or 'dockLeft'
    collapsedMode: 'tab', // 'chip', 'tab', or 'hidden'; not used for embedPosition: 'inline'
    collapsedModeOnlineLabel: 'How can we help you?', // not used for embedPosition: 'inline'
    collapsedModeOfflineLabel: 'Contact Us.', // not used for embedPosition: 'inline'
    startHidden: false, // defaults to false
    autoExpand: true, // defaults to true
    chatLayout: 'stacked', // 'stacked' or 'sideBySide'
    showGreetingMessage: true, // defaults to true, if false, no need to provide greetingMessageUsername/greetingMessage
    showRoomMemberList: true, // defaults to true, false will hide the chip and sidebar showing users in a room
    unfocusedUnreadAlert: true, // optionally show an alert in room if there is a new message and room not in focus
    unfocusedUnreadAlertMessage: 'Unread Messages', // label on optional unread alert 
    unfocusedUnreadAlertFlashTime: 30, // time in seconds before alert starts to flash
    greetingMessageUsername: 'Support Team',
    greetingMessage: 'Welcome to Example. :wave: Type a message below if you have any questions!',
    offlineGreetingMessage: 'Hi, we are not around right now. Leave us a message and we will get back to you.',
    offlineMessageFields: {
      message: { label: 'Message', required: true, enabled: true },
      email: { label: 'Email', required: true, enabled: true },
      name: { label: 'Name', required: false, enabled: true },
      opt1: { label: 'Company', required: false, enabled: true },
      opt2: { label: 'Favorite Band', required: false, enabled: true },
      opt3: { label: 'Address', required: false, enabled: true },
    },
    offlineSendButton: 'Send',
    offlineThankYou: 'Thank you for sending your message! We will get back to you shortly!',
    offlineForwardingEmail: '<your email address>',
    offlineSubject: 'New Roomlio offline message',
    selfIdentifyFormFields: {
      displayName: { label: 'Display Name', required: true, enabled: true }, // always required and enabled
      first: { label: 'First Name', required: false, enabled: true },
      last: { label: 'Last Name', required: false, enabled: true },
      email: { label: 'Email', required: false, enabled: true }, // email will not be seen by other embedded chat users
      opt1: { label: 'Company', required: false, enabled: true },
      opt2: { label: 'City', required: false, enabled: true },
    },
    selfIdentifyGreetingMsg: 'Your public chat info.',
    selfIdentifyButtonLabel: 'Start chatting now',
    topBarNotificationsToggle: true, // defaults to true
    topBarNotificationsToggleType: 'switch', // 'switch' or 'bellIcon'
    roles: {
      staff: {
        name: 'Staff', // required if you choose to use roles
        backgroundColor: 'blue', // defaults to #aaaaaa
        borderRadius: '2px', // defaults to 2px
        color: 'white', // defaults to #ffffff
        fontSize: '10px', // defaults to 10px
        fontFamily:
          '-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, Ubuntu, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol',
        padding: '0px 3px 1px', // defaults to '0 3px 1px'
      },
      fan: {
        name: 'Fan',
        ...
      },
    },
    styles: { 
      // button styles
      '--rml-btn-primary-background-color': 'purple',
      '--rml-btn-primary-background-color-hover': 'darkPurple',
      '--rml-btn-primary-background-color-active': 'lightPurple',
      '--rml-btn-primary-text-color': '#fff',
      '--rml-btn-secondary-background-color': 'lightGray',
      '--rml-btn-secondary-background-color-hover': 'gray',
      '--rml-btn-secondary-background-color-active': '#222222',
      '--rml-btn-secondary-text-color': 'white',
      // collapsed mode styles (do not apply when embedPosition equals 'inline')
      '--rml-collapsed-background-color': 'rgba(255, 0, 0, 1)',
      '--rml-collapsed-background-color-hover': 'darkRed',
      '--rml-collapsed-background-color-active': '#8e4e4e',
      '--rml-collapsed-text-color': 'rgb(255, 255, 255)',
      // font styles
      '--rml-font-family': 'Courier, monospace, serif',
      '--rml-icon-theme': 'light', // 'light' or 'dark'
      '--rml-link-color': 'rgba(0, 255, 0, 1)',
      '--rml-link-color-hover': 'darkGreen',
      // message styles
      '--rml-msg-text-color': '#212121',
      '--rml-msg-background-color': '#fff',
      '--rml-msg-background-color-hover': '#dddddd',
      // message system styles (i.e. timestamps, 'edited' label)
      '--rml-msg-system-text-color': 'white', 
      '--rml-msg-system-text-background-color': 'gray',
      '--rml-msg-system-text-font-family': 'Courier, monospace, serif',
      '--rml-msg-system-text-font-size': '9px',
      '--rml-msg-system-text-border-radius': '4px',
      // UI chrome styles
      '--rml-ui-chrome-background-color': 'gray',
      '--rml-ui-chrome-text-color': '#212121',
      // unread message alert styles
      '--rml-unfocused-unread-background-color': 'red',
      '--rml-unfocused-unread-color': 'black',
      // side-by-side styles (only apply when chatLayout: 'sideBySide')
      '--rml-side-by-side-them-text-color': 'white',
      '--rml-side-by-side-them-link-color': '#ccc',
      '--rml-side-by-side-them-background-color': '#ff0000',
      '--rml-side-by-side-me-text-color': '#fff',
      '--rml-side-by-side-me-link-color': 'gray',
      '--rml-side-by-side-me-background-color': '#0000ff',
      '--rml-side-by-side-border-radius': '4px',
      '--rml-side-by-side-padding': '2px 6px',
    },
  },
});
rml('register')

Insecurely registers the user and room. If possible, it is best to use the rml('registerSecure') API call over rml('register') because it ensures that Roomlio embed data cannot be tampered with by a malicious user. rml('register') is good for quick testing or where user authentication is not important. rml('register') must be called after rml('config'). All "options" are optional for rml('register'). You can use the Embed Code tab via the "Get Embed Code" link for the appropriate widget on the Settings page for different combinations.

INSECURE GEOLOCATION NAMED USERS

You can leave the naming of your users to Roomlio if you do not know who your users are going to be. Do not pass in any of the user options (i.e. displayName, userID, first, last name, email, and traits) in the options object of the rml('register') call, and we will automatically create a name for your users based on their geolocation. The geolocation name (e.g. seattle-wa-us-63f918) will be displayed in the room when the user sends a message. In other words, roomName and roomKey are the only options you might want to provide in the rml('register') call if you plan on using Roomlio's geolocation names. It is important to know that Roomlio creates a new geolocation when your user switches to another device or browser, or clears their browser's cookies and localStorage

INSECURE USERS SPECIFIED BY YOU

There might be a scenario where you know who your users will be and you will want to insecurely pass in their user data (i.e. displayName, userID, first and last name, email, and other traits that you feel are important to be available in the room) via the rml('register') options object. The simplest way is to just provide a displayName in the options object and we will display it when the user sends a message. You can also send in the user's userID and Roomlio will use it as the unique key for your user so we can keep your user updated as you maintain them in the future. Roomlio creates the unique key for your user behind the scenes when you don't supply a userID. As in the case of geolocation named users, when you don't pass in a userID, Roomlio will create a new user when the user switches to another device or browser, or clears their browser's cookies and localStorage. Remember, it is best to use the rml('registerSecure') API call over rml('register') because it ensures that Roomlio user and room data cannot be tampered with by a malicious user.

  • roomElementID
    The "id" of the div that you have in your markup that Roomlio will replace with an embedded room. This value must be the same on all rml calls for the same widget. When embedPosition is set to bottomRight, bottomLeft, dockRight, or dockLeft, this value still needs to be present, but you do not need a corresponding div in your markup with that ID.
  • options:roomKey
    A unique key to identify a room. Different keys mean different rooms. If a room key is changed, the embed code will generate an entirely new room. Generally your room keys should never change, but you can change roomName and maintain same room. Eg. If you have different rooms for each account in your system, your account ID would be the room key. You can omit roomKey and Roomlio will create a unique key behind the scenes for you.
  • options:roomName
    Display name of the room shown to users in the sidebar of the Roomlio App. Will show up in the email notification if you utilize our email notifications feature.
  • options:userID
    Your internal user id, or something that uniquely identifies the user to Roomlio.

    NOTE: Do not use userID if you're going to be using our geolocation names (e.g. you're not going to know who your users will be).

  • options:displayName
    Display name of user, will be shown if no first/last name provided
  • options:first
    First name of user
  • options:last
    Last name of the user
  • options:email
    Email of user. Providing email will allow us to prepopulate the email field on the offline and user identify forms. NOTE: It will not be visible to other users.
  • options:role
    Role of the user. Use the key of the role defined in the rml('config') roles option.

    NOTE: Use the key of the role defined in the roles object, not the role name.

  • options:roomKey
    A unique key to identify a room. Different keys mean different rooms. If a room key is changed, the embed code will generate an entirely new room. Generally your room keys should never change, but you can change roomName and maintain same room. Eg. If you have different rooms for each account in your system, your account ID would be the room key.
  • options:roomName
    Display name of the room shown to users in the sidebar of the Roomlio App
  • options:traits
    Traits are the place to send in your custom data. They can be anything you want to display in users' profiles.

    NOTE: Don't supply a traits object here if you plan on using the self/user identify form to get data from your users. Using traits here will override the self identify form info.

rml('register', {
  roomElementID: 'your-div-id-to-replace-with-embedded-room',
  // All options are "optional" for `register`. See https://app.roomlio.dev/#/settings for different combinations
  options: {
    // Room options
    roomKey: 'kraken1234', // needs to be unique per room
    roomName: 'Kraken-Hockey',

    // User options
    userID: 'abc1234', // needs to be unique per user
    displayName: 'jsmith99',
    first: 'John',
    last: 'Smith',
    email: '<user email here>',
    role: 'staff', // corresponds to a role key defined in the rml('config') roles option
    traits: {
      color: 'purple',
      account: 'acct1234',
      plan: 'pro',
    },
  },
});
rml('registerSecure')

Securely registers the user and room. If possible, it is best to use this API call over rml('register'). It ensures that Roomlio embed data cannot be tampered with by a malicious user. Must be called after rml('config'). This API call will require you to securely build and sign your payload on the server side of your site. Your client (i.e. frontend code) will call your server (i.e. backend) to retrieve the register payload that contains an HMAC (authentication code) generated using a shared secret (usually on an API endpoint that requires authentication). Then make the registerSecure API call with payload and HMAC. Again, we highly recommend registering Roomlio users securely. Doing so will guarantee that all user info is accurate and authentic because you sign the payload with a shared secret.

All "options" are optional for registerSecure. See the Embed Code tab via the "Get Embed Code" link for the appropriate widget on the Settings page for different combinations. If you just provide a displayName, we will display that for the user. If you provide first/last name as well, we will use that for display name instead. If roomKey/roomName is left off, we will name the room after the geo location of the user. Again, it is best to refer to the Embed Code tab for the widget on the Settings page for all the different combinations.

GENERATING NEW ROOMS AUTOMATICALLY

See options:roomKey below.

  • roomElementID
    The "id" of the div that you have in your markup that Roomlio will replace with an embedded room. This value must be the same on all rml calls for the same widget. When embedPosition is set to bottomRight, bottomLeft, dockRight, or dockLeft, this value still needs to be present, but you do not need a corresponding div in your markup with that ID.
  • payloadMAC
    Signed HMAC authentication code. Use the HMAC key provided in the Embed Code tab of the settings page for your widget to create a hash of the payload, and then base64 encode it so the payload is a string when you send it in the registerSecure call. NOTE: Protect your HMAC key like an API key or password.
  • options:roomKey
    A unique key to identify a room. Different keys mean different rooms. If a room key is changed, the embed code will generate an entirely new room. Generally your room keys should never change, but you can change roomName and maintain same room. Eg. If you have different rooms for each account in your system, your account ID would be the room key.
  • options:roomName
    Display name of the room shown to users in the sidebar of the Roomlio App. Will show up in the email notification if you utilize our email notifications feature.
  • options:allowInsecureUsers
    Boolean. By default we do not allow insecure users to enter rooms that contain secure users. However, sometimes this situation is okay and you can set allowInsecureUsers: true to allow both secure and insecure users to chat in the same room. Default is false.
  • options:userID
    Your internal user id, or something that uniquely identifies the user to Roomlio
  • options:isModerator
    Allows a user to moderate chat content, including removing spam messages or banning abusive users.
  • options:displayName
    Display name of user, will be shown if no first/last name provided
  • options:first
    First name of user
  • options:last
    Last name of the user
  • options:email
    Email of user. Providing email will allow us to prepopulate the email field on the offline and user identify forms. NOTE: It will not be visible to other users.
  • options:role
    Role of the user. Use the key of the role defined in the rml('config') roles option.

    NOTE: Use the key of the role defined in the roles object, not the role name.

  • options:roomKey
    A unique key to identify a room. Different keys mean different rooms. If a room key is changed, the embed code will generate an entirely new room. Generally your room keys should never change, but you can change roomName and maintain same room. Eg. If you have different rooms for each account in your system, your account ID would be the room key.
  • options:roomName
    Display name of the room shown to users in the sidebar of the Roomlio App
  • options:traits
    Traits are the place to send in your custom data. They can be anything you want to display in users' profiles.

    NOTE: Don't supply a traits object here if you plan on using the self/user identify form to get data from your users. Using traits here will override the self identify form info.

Node
Python3
PHP
Go
Ruby
Java
// SERVER SIDE - NODE
const express = require('express');
const app = express();
const crypto = require('crypto');
const cors = require('cors');

module.exports = function (app) {
  app.get('/registerParams', cors(), function (request, response) {
    // This would be based on your app authentication, hard coded for
    // this demo. ID and username should be unique across your app.
    var currentUser = {
      id: '123456',
      displayName: 'jsmith',
      firstName: 'John',
      lastName: 'Smith',
      role: 'staff', // corresponds to a role defined in the rml('config') roles option
      isModerator: true, // optional
      email: '<user email here>', // optional
    };

    var rmlPayload = {
      apiName: 'register',
      userID: currentUser.id,
      displayName: currentUser.displayName,
      first: currentUser.firstName, // optional
      last: currentUser.lastName, // optional
      role: currentUser.role, // optional
      isModerator: currentUser.isModerator, // optional
      email: currentUser.email, // optional

      // Replace with desired roomKey and roomName values
      roomKey: 'abc1234',
      roomName: 'Smith Inc',
      allowInsecureUsers: false, // default is false
    };

    var payloadStr = JSON.stringify(rmlPayload);

    var hmacKey = '<your HMAC key>';
    var message = JSON.stringify(rmlPayload);

    var hash = crypto.createHmac('sha256', hmacKey).update(message);
    var payloadMAC = hash.digest('base64');

    response.json({
      payloadMAC: payloadMAC,
      payloadStr: payloadStr,
    });
  });
};
# SERVER SIDE - PYTHON 3
# main.py
# where your Python app starts

import hashlib
import hmac
import base64
import json

from flask import Flask, jsonify
app=Flask(__name__, static_folder='..')

@app.route('/registerParams')
def register_params():
    # This would be based on your app authentication, hard coded for
    # this demo. ID and username should be unique across your app.
    current_user = {
        'id': '123456',
        'displayName': 'jsmith',
        'firstName': 'John',
        'lastName': 'Smith',
        'role': 'staff', # corresponds to a role defined in the rml('config') roles option
        'isModerator': true,
        'email: '<user email here>',
    }

    rml_payload = {
        'apiName': 'register',
        'userID': current_user['id'],
        'displayName': current_user['displayName'],
        'first': current_user['firstName'], # optional
        'last': current_user['lastName'], # optional
        'role': current_user['role'], # optional
        'isModerator': current_user['isModerator'], # optional
        'email': current_user['email'], # optional

        # Replace with desired roomKey and roomName values
        'roomKey': 'abc1234',
        'roomName': 'Smith Inc',
        'allowInsecureUsers': false, # default is false
    }

    payload_str = json.dumps(rml_payload)

    hash = hmac.new(
        bytes('<your HMAC key>', 'utf-8'),
        bytes(payload_str, 'utf-8'),
        hashlib.sha256)

    payload_mac = str(base64.b64encode(hash.digest()), 'utf-8')

    response = {
        'payloadStr': payload_str,
        'payloadMAC': payload_mac,
    }

    return jsonify(response)

// SERVER SIDE - PHP
<?php

if ($_SERVER['REQUEST_URI'] == '/registerParams') {
  // This would be based on your app authentication, hard coded for
  // this demo. ID and username should be unique across your app.
  $current_user = array(
    'id' => '123456',
    'displayName' => 'jsmith',
    'firstName' => 'John',
    'lastName' => 'Smith',
    'isModerator' => true,
    'email' => '<user email here>',
    'role' => 'staff', // corresponds to a role key defined in the rml('config') roles option
  );

  $rml_payload = array(
    'apiName' => 'register',
    'userID' => $current_user['id'],
    'displayName' => $current_user['displayName'],
    'first' => $current_user['firstName'],  // optional
    'last' => $current_user['lastName'],  // optional
    'role' => $current_user['role'],  // optional
    'isModerator' => $current_user['isModerator'],  // optional
    'email' => $current_user['email'], // optional

    // Replace with desired roomKey and roomName values
    'roomKey' => 'abc1234',
    'roomName' => 'Smith Inc',
    'allowInsecureUsers' => false, // default is false
  );

  $payload_str = json_encode($rml_payload);

  $payload_mac = base64_encode(hash_hmac('sha256', $payload_str, '<your HMAC key', true));

  $response = array(
    'payloadStr' => $payload_str,
    'payloadMAC' => $payload_mac,
  );

  header('Content-Type: application/json');
  echo json_encode($response);

}
?>
// SERVER SIDE - GO
package main

import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/base64"
  "encoding/json"
  "net/http"
)

func registerParamsHandler(w http.ResponseWriter, r *http.Request) {
  // This would be based on your app authentication, hard coded for
  // this demo. ID and displayName should be unique across your app.
  var currentUser = struct {
    ID          string
    DisplayName string
    FirstName   string
    LastName    string
    Role        string
    IsModerator bool
    Email       string
  }{
    ID:           "123456",
    DisplayName:  "jsmith",
    FirstName:    "John",
    LastName:     "Smith",
    Role:         "staff", // corresponds to a role key defined in the rml('config') roles option
    IsModerator:  true,
    Email:        "<user email here>",
  }

  var rmlPayload = struct {
    APIName             string  `json:"apiName"`
    UserID              string  `json:"userID"`
    DisplayName         string  `json:"displayName"`
    First               string  `json:"first,omitempty"`
    Last                string  `json:"last,omitempty"`
    IsModerator         bool    `json:"isModerator,omitempty"`
    Role                string  `json:"role,omitempty"`
    Email               string  `json:"email,omitempty"`
    AllowInsecureUsers  bool    `json:"allowInsecureUsers"`
    RoomKey             string  `json:"roomKey"`
    RoomName            string  `json:"roomName"`
  }{
    APIName:      "register",
    UserID:       currentUser.ID,
    DisplayName:  currentUser.DisplayName,
    First:        currentUser.FirstName, // not required
    Last:         currentUser.LastName,  // not required
    IsModerator   currentUser.IsModerator // not required
    Role:         currentUser.Role, // not required
    Email         currentUser.Email, // not required
    AllowInsecureUsers: false, // default is false
    RoomKey:            "abc1234", // Replace with desired roomKey and roomName values
    RoomName:           "Smith Inc",
  }

  payloadStr, _ := json.Marshal(rmlPayload)

  HMACKey := "<your HMAC key>"
  h := hmac.New(sha256.New, []byte(HMACKey))
  h.Write(payloadStr)
  hsum := h.Sum(nil)
  payloadMAC := base64.StdEncoding.EncodeToString(hsum)

  result := struct {
    PayloadStr string `json:"payloadStr"`
    PayloadMAC string `json:"payloadMAC"`
  }{
    string(payloadStr),
    payloadMAC,
  }

  js, _ := json.Marshal(result)

  w.Header().Set("Content-Type", "application/json")
  w.Write(js)
}
# SERVER SIDE - RUBY
require 'sinatra'
require 'openssl'
require 'base64'
require 'json'

get '/registerParams' do
  # This would be based on your app authentication, hard coded for
  # this demo. ID and username should be unique across your app.
  current_user = {
    'id' => "123456",
    'displayName' => "jsmith",
    'firstName' => "John",
    'lastName' => "Smith",
    'role' => "staff", # corresponds to a role key defined in the rml('config') roles option
    'isModerator' => true,
    'email' => '<user email here>',
  }

  rml_payload = {
    'apiName' => 'register',
    'userID' => current_user['id'],
    'displayName' => current_user['displayName'],
    'first' => current_user['firstName'],  # optional
    'last' => current_user['lastName'],  # optional
    'role' => current_user['role'], # optional
    'isModerator' => current_user['isModerator'],  # optional
    'email' => current_user['email'], # optional

    # Replace with desired roomKey and roomName values
    'roomKey' => 'abc1234',
    'roomName' => 'Smith Inc',
    'allowInsecureUsers' => false # default is false
  }

  payload_str = rml_payload.to_json

  payload_mac = Base64.encode64(
    OpenSSL::HMAC.digest(
      'sha256',
      '<your HMAC key',
      payload_str,
    ))

  {'payloadStr' => payload_str, 'payloadMAC' => payload_mac}.to_json
end
// SERVER SIDE - JAVA
package com.rmlhmac.controller;

import java.util.HashMap;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.core.io.ByteArrayResource;

import java.io.IOException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.json.JSONObject;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import javax.xml.bind.DatatypeConverter;


@Controller
public class MyController {

    @GetMapping(value = "/registerParams", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Object> registerParams() {
        HashMap<String, String> currentUser = new HashMap<>();

        // This would be based on your app authentication, hard coded for
        // this demo. ID and displayName should be unique across your app.
        currentUser.put("id", "123456");
        currentUser.put("displayName", "jsmith");
        currentUser.put("firstName", "John");
        currentUser.put("lastName", "Smith");
        currentUser.put("role", "staff"); // corresponds to a role key defined in the rml('config') roles option
        currentUser.put("isModerator", true);
        currentUser.put("email", "<user email here>");

        JSONObject rmlPayload = new JSONObject();

        rmlPayload.put("apiName", "register");
        rmlPayload.put("userID", currentUser.get("id"));
        rmlPayload.put("displayName", currentUser.get("displayName"));
        rmlPayload.put("first", currentUser.get("firstName")); // optional
        rmlPayload.put("last", currentUser.get("lastName")); // optional
        rmlPayload.put("role", currentUser.get("role")); // optional
        rmlPayload.put("isModerator", currentUser.get("isModerator")); // optional
        rmlPayload.put("email", currentUser.get("email")); // optional

        // Replace with desired roomKey and roomName values
        rmlPayload.put("roomKey", "abc1234");
        rmlPayload.put("roomName", "Smith Inc");
        rmlPayload.put("allowInsecureUsers", false) // default is false

        String payloadStr = rmlPayload.toString();
        String payloadMac = "";

        try {
            String hmacKey = "<your HMAC key";
            Mac hasher = Mac.getInstance("HmacSHA256");
            hasher.init(new SecretKeySpec(hmacKey.getBytes(), "HmacSHA256"));

            byte[] hash = hasher.doFinal(payloadStr.getBytes());

            payloadMac = DatatypeConverter.printBase64Binary(hash);
        }
        catch (NoSuchAlgorithmException e) {}
        catch (InvalidKeyException e) {}

        HashMap<String, String> response = new HashMap<>();
        response.put("payloadStr", payloadStr);
        response.put("payloadMAC", payloadMac);

        return new ResponseEntity<Object>(response, HttpStatus.OK);
    }

}
// CLIENT SIDE
(async () => {
  // Replace with the URL of the registerParams endpoint of your
  // server (see the server embed code for more info).
  const signedPayload = await fetch(
    `<your server endpoint domain>/registerParams`,
  );
  const jsonPayload = await signedPayload.json();

  rml('registerSecure', {
    roomElementID: 'your-div-id-to-replace-with-embedded-room',
    payloadMAC: jsonPayload.payloadMAC,
    options: jsonPayload.payloadStr,
  });
})();
rml('open')

Open the room. Handy if you decide to use your own button/link to open the room. Not applicable if you set embedPosition: 'inline'. This call will be a must if you set collapsedMode: 'hidden'.

rml('open', {
  roomElementID: 'rml-room-1', // id of room you want to open
});
rml('close')

Close the room. Handy if you decide to use your own button/link to close the room. Not applicable if you set embedPosition: 'inline'.

rml('close', {
  roomElementID: 'rml-room-1', // id of room you want to close
});
rml('reset')

Clears local cache settings in the embedded room which may be useful for debugging Roomlio embed code as a developer.

rml('reset', {
  roomElementID: 'rml-room-1', // id of room in which you want clear the local cache.
});
rml('show')

Show the room on the page. Handy if you want to use your own UI to show the Roomlio room. Can be used in tandem with rml('hide'). Use the startHidden: true in the rml('config') call if you want the room hidden initially.

rml('show', {
  roomElementID: 'rml-room-1', // id of room in which you want to show.
});
rml('hide')

Hides the room on the page. Handy if you want to use your own UI to hide the Roomlio room. Can be used in tandem with rml('show').

rml('hide', {
  roomElementID: 'rml-room-1', // id of room in which you want to hide.
});
EVENTS
rml-event

Roomlio will emit a rml-event event when certain actions relating to a room occur that will aid you in integrating a room into your website. You just have to add an event listener and listen for what type of event it is (see below).

// Example of how to listen for the rml-event
document.addEventListener('rml-event', (event) => {
  switch (event.detail.type) {
    case 'rml_opened':
      // Do something...
      break;
    case 'rml_closed':
      // Do something...
      break;
    case 'rml_state_change':
      // Do something...
      break;
    case 'rml_new_msg':
      // Do something...
      break;
    case 'rml_new_focus':
      // Do something...
      break;
    case 'rml_new_focusout':
      // Do something...
      break;
  }
});