Salesforce Common Customizations

Buttons and components that open Quiq from Salesforce records with data already filled in: Send Notification, Start Conversation and the QuiqData event.

Overview

Once Quiq is running inside your Salesforce Lightning console, you can add buttons and components that open Quiq
from a Salesforce record, with that record's data already filled in. This article covers four common
customizations:

CustomizationWhat it does
Send Notification for a single recordOpens Quiq's Send Notification window from a Contact or Lead with the phone number filled in. It can also fill message variables in Catalog Messages with fields from the record.
Send Notifications for a list of ContactsSends one notification to the Contacts selected in a list view.
Start Conversation for a custom objectOpens Quiq's Start Conversation window from any object with Start Conversation fields filled in.
Pass data with the QuiqData eventSends the current record's phone number to the Quiq Messaging component, so new conversations start with it filled in.

The first three work the same way. A Visualforce page reads fields from the record using Salesforce merge fields
(for example {!Contact.FirstName}). It puts them on the address of a Quiq page as URL parameters and shows that
page in a frame. A Salesforce action puts the Visualforce page on the record as a button.

🚧

Before you start

Complete the Salesforce Lightning Console Integration first, including
installing the Quiq package and setting Quiq URL in the Quiq Settings custom setting. Every example below
reads the Quiq URL from that setting as {!$Setup.goquiq__quiqSettings__c.goquiq__quiqUrl__c}.

Building these pages requires a Salesforce administrator who is comfortable editing Visualforce. Quiq can help:
contact your Quiq implementation specialist.

Send Notification for a Single Record

This adds a Send Notification button to a Contact or Lead. It opens Quiq's Send Notification window with the
record's phone number filled in. The agent picks a Catalog Message and sends it.

The button can also pass any fields from the record into the message. A Catalog Message that says
Hi {{firstname}}, your appointment at {{location}} is confirmed. will arrive in the Send Notification window with
the record's first name and location already filled in.

1. Set up the Catalog Messages

Skip this step if you don't have variable replacement needs.

For each value you want to pass from Salesforce:

  1. In Quiq, open the Message Catalog and edit the message the agents will send.
  2. Add a message variable to the text with a simple name, for example {{firstname}}.
  3. Open the variable's settings with the button. Leave Field empty. When a variable has no Field, Quiq
    fills it from the value Salesforce passes. If you pick a Field, the Field is used and the Salesforce value is
    ignored.
  4. Set a Fallback for any value that might be blank in Salesforce. A variable with no value and no Fallback is
    sent as the literal text, for example {{firstname}}.
  5. Save the variable settings, then save the message.

A variable with no Field shows as a yellow chip, and the button turns yellow. That is expected here.

Rules for variable names:

  • Names must match exactly, including upper and lower case. {{guestId}} and {{guestid}} are different
    variables.
  • Don't use a period in the name of a variable you fill from Salesforce. Quiq reads a name with a period, like
    {{appointment.date}}, as a reference to a Quiq field, so the value from Salesforce isn't used. Use
    {{appointmentdate}} instead. Periods are fine in other message variables.
  • Don't use these names, which the Send Notification window uses for other purposes: phoneNumbers,
    integrations, topic, widgetMode.

2. Create the Visualforce page

  1. In Salesforce Setup, search for visual and select Visualforce Pages under Custom Code.
  2. Select New.
  3. For Label, enter Send Notification. For Name, enter QuiqSendNotification.
  4. Check Available for Lightning Experience, Experience Builder sites, and the mobile app.
  5. Paste in the code below and edit the variables list for your messages.
  6. Select Save.
<apex:page standardController="Contact">
  <iframe id="sendNotification" height="500" style="width: 99%; border: none; overflow: hidden;" src=""></iframe>
  <script>
    // One line per message variable: ['variableName', '{!JSENCODE(Contact.FieldName)}']
    // The variable name must match the Catalog Message variable exactly (case-sensitive).
    var variables = [
      ['firstname', '{!JSENCODE(Contact.FirstName)}'],
      ['lastname',  '{!JSENCODE(Contact.LastName)}'],
      ['agentname', '{!JSENCODE($User.FirstName)}'],
      // Custom fields and related records work too:
      // ['location', '{!JSENCODE(Contact.Location__c)}'],
      // ['accountname', '{!JSENCODE(Contact.Account.Name)}'],
    ];

    // The first phone number that is filled in
    var phone = '{!JSENCODE(Contact.MobilePhone)}' || '{!JSENCODE(Contact.Phone)}' ||
                '{!JSENCODE(Contact.HomePhone)}' || '{!JSENCODE(Contact.OtherPhone)}';

    var params = new URLSearchParams();
    variables.forEach(function (v) {
      var value = (v[1] || '').trim();
      if (value) {
        params.set(v[0], value);
      }
    });
    phone = phone.replace(/[\[\]\s]/g, '');
    if (phone) {
      params.set('phoneNumbers', phone);
    }

    document.getElementById('sendNotification').src =
      '{!$Setup.goquiq__quiqSettings__c.goquiq__quiqUrl__c}/app/outbound/widget/send?' + params.toString();
  </script>
</apex:page>

Notes on the code:

  • One page per object. A page whose standardController is Contact can only use Contact fields, and fields
    of records related to the Contact. Salesforce won't save the page otherwise. For Leads, make a second page with
    standardController="Lead", and change Contact. to Lead. throughout. Leads have MobilePhone and Phone, but
    not HomePhone or OtherPhone.
  • Related records use the relationship name: Contact.Account.Name for standard relationships,
    Contact.Location__r.City__c for custom ones.
  • $User is the Salesforce user who clicked the button, so {!JSENCODE($User.FirstName)} is the agent's first
    name.
  • JSENCODE keeps a value with quotes or line breaks from breaking the script. URLSearchParams encodes
    characters such as &, # and spaces so each value arrives intact. Keep both.
  • Blank values are left out, so the message's Fallback is used for them.

3. Create the action

  1. In Setup, search for Object and select Object Manager.
  2. Select Contact (or Lead), then Buttons, Links, and Actions.
  3. Select New Action.
  4. For Action Type, select Custom Visualforce.
  5. For Visualforce Page, select QuiqSendNotification.
  6. For Height, enter 540px.
  7. Leave Standard Label Type blank. For Label, enter Send Notification. For Name, enter
    Send_Notification_Detail.
  8. Select Save.

4. Add the action to the record page

  1. In Object Manager, select Contact (or Lead), then Page Layouts.
  2. Open the layout to edit, for example Contact Layout.
  3. Select Mobile & Lightning Actions.
  4. Drag Send Notification into Salesforce Mobile and Lightning Experience Actions. You may need to select
    override the predefined actions in that section first.
  5. Select Save.
📘

Button doesn't appear?

If your Lightning record page uses Dynamic Actions, the page layout's action list isn't used. Open the record
page in Lightning App Builder, select the Highlights Panel, and add Send Notification to its actions
there.

5. Check that it works

  1. Open a Contact that has a phone number and the fields your message uses.
  2. Select Send Notification. The Send Notification window opens with the phone number filled in.
  3. Choose the Catalog Message. The variables show the values from the Contact.

Send Notifications for a List of Contacts

This adds a Send Notifications button to Contact list views. The agent selects Contacts and sends them all the
same notification. Up to 100 Contacts can be sent to at once.

🚧

Note

The list button passes phone numbers only. Message variables aren't filled from Salesforce, because each
Contact would need different values.

1. Create the Visualforce page

  1. In Setup, search for visual and select Visualforce Pages.
  2. Select New.
  3. For Label, enter Send Notifications. For Name, enter QuiqSendNotificationList.
  4. Check Available for Lightning Experience, Experience Builder sites, and the mobile app.
  5. Paste in the following code and select Save.
<apex:page standardController="Contact" recordSetVar="contacts">
    <apex:includescript value="/soap/ajax/43.0/connection.js" />
    <script src="https://static.quiq-cdn.com/3/js-cookie/2.2.1/js.cookie.min.js"></script>
    <p id="infoText"></p>
    <button id="backButton" type="button">Back to Contact List</button>
    <script>
        function isLightningDesktop() {
            return UITheme.getUITheme() === "Theme4d";
        }

        function navigateToContactList() {
            if (isLightningDesktop()){
                sforce.one.navigateToURL('/lightning/o/Contact/list');
            } else {
                window.location.href = '{!URLFOR($Action.Contact.List, $ObjectType.Contact)}';
            }
        }

        function inEdge() {
            return (navigator.userAgent.indexOf('Edge') > -1);
        }

        function tryBulkSend(phoneNumbers) {
            if (phoneNumbers.length > 100) {
                return window.open(
                    '{!$Setup.goquiq__quiqSettings__c.goquiq__quiqUrl__c}/app/outbound/widget/error',
                    'sendNotification',
                    'width=600,height=500,resizable=0,top=' +
                    window.innerHeight / 2 +
                    'px,left=' +
                    window.innerWidth / 2 +
                    'px'
                )
            } else {
                return window.open(
                    '{!$Setup.goquiq__quiqSettings__c.goquiq__quiqUrl__c}/app/outbound/widget/send?phoneNumbers=' + phoneNumbers.join(','),
                        'sendNotification',
                    'width=600,height=500,resizable=0,top=' +
                        window.innerHeight / 2 +
                        'px,left=' +
                        window.innerWidth / 2 +
                        'px'
                )
            }
        }

        document.getElementById('backButton').addEventListener('mouseup', navigateToContactList);
        var escaping = false;
        if (Cookies) {
            var retryCookie = 'quiq-send-notification-retries';
            var expiration = new Date(Date.now() + (20*1000));
            var retries = Cookies.get(retryCookie);
            if (retries) {
                Cookies.remove(retryCookie);
                if (retries > 1) {
                    escaping = true;
                    navigateToContactList();
                } else {
                    Cookies.set(retryCookie, ++retries, {expires: expiration});
                }
            } else {
                Cookies.set(retryCookie, '1', {expires: expiration});
            }
        }

        if (!escaping) {
            sforce.connection.sessionId='{!GETSESSIONID()}';
            var result = "{!selected}".replace(/[\[\]\s]/g , "").replace(/,/g , "','").trim();
            var records = sforce.connection.query("SELECT Phone, MobilePhone, OtherPhone, HomePhone FROM Contact WHERE Id in ('" + result + "')")
                .getArray('records');
            var phoneNumbers = [];
            for (var i = 0; i < records.length; i++) {
                var r = records[i];
                var phone = r.MobilePhone || r.Phone || r.HomePhone || r.OtherPhone;
                if (phone) {
                    phoneNumbers.push(encodeURIComponent(phone.replace(/[\[\]\s]/g , "").trim()));
                }
            }
            var ref = tryBulkSend(phoneNumbers);
            if (ref) {
                window.history.back();
            } else {
                if (inEdge()) {
                    ref = window.open('', 'edgetest');
                    if (ref) {
                        ref.close();
                        window.history.back();
                    }
                }
                document.getElementById('infoText').innerHTML = "Oops! If you are seeing this message, you are probably blocking our pop-up.  Please enable pop-ups for this site and refresh the page or click your browser's 'Back' button"
            }
        }
    </script>
</apex:page>

2. Create the action

  1. In Object Manager, select Contact, then Buttons, Links, and Actions.
  2. Select New Button or Link.
  3. For Label, enter Send Notifications. For Name, enter Send_Notification_List.
  4. For Display Type, select List Button, and check Display Checkboxes (for Multi-Record Selection).
  5. For Behavior, select Display in existing window with sidebar.
  6. For Content Source, select Visualforce Page, and for Content, select QuiqSendNotificationList.
  7. Select Save.

3. Add the button to the list view

  1. In Object Manager, select Contact, then List View Button Layout (called Search Layouts in some
    orgs).
  2. Select Edit on the list view layout.
  3. Under Custom Buttons, move Send Notifications to Selected Buttons.
  4. Select Save.

4. Check that it works

  1. Open a Contact list view. Salesforce doesn't show custom list buttons on Recently Viewed, so pick another
    list view, and switch the display to Table if needed.
  2. Select some Contacts and select Send Notifications. The button may be under the arrow next to the standard
    buttons.
  3. A Quiq window opens with the Contacts' phone numbers filled in. If nothing opens, allow pop-ups for your
    Salesforce site.

Start Conversation for a Custom Object

This adds a Start Conversation button to any object, including custom objects. It opens Quiq's Start
Conversation window with Start Conversation fields filled in from the record.

1. Set up the Start Conversation fields in Quiq

  1. In Quiq Admin, go to Agent UI → Start Conversation Fields.
  2. Add the fields you want filled in from Salesforce, and save. To create a new field, go to
    Custom Fields and select New Conversation Field.
  3. Note each field's ID, shown on the field in Custom Fields. The Visualforce page uses these IDs.

Skip ahead if the object and its fields already exist in Salesforce. Otherwise, create the custom object in
Object Manager → Create → Custom Object, add a tab for it under Setup → Tabs, and add the fields
it needs. Matching each Salesforce field's data type to the Quiq field's type avoids surprises.

2. Create the Visualforce page

  1. In Setup, search for visual and select Visualforce Pages.
  2. Select New.
  3. For Label, enter Start Conversation. For Name, enter QuiqStartConversation.
  4. Check Available for Lightning Experience, Experience Builder sites, and the mobile app.
  5. Paste in the code below and edit it for your object and fields.
  6. Select Save.

This example uses a custom object named Service_Request__c. It fills two Start Conversation fields with the IDs
salesforceObjectId and customerIntent:

<apex:page standardController="Service_Request__c">
  <iframe id="startConversation" height="500" style="width: 99%; border: none; overflow: hidden;" src=""></iframe>
  <script>
    // One line per Start Conversation field: ['quiqFieldId', '{!JSENCODE(Object__c.Field__c)}']
    var fields = [
      ['salesforceObjectId', '{!JSENCODE(Service_Request__c.Id)}'],
      ['customerIntent',     '{!JSENCODE(Service_Request__c.Customer_Intent__c)}'],
    ];

    var params = new URLSearchParams();
    fields.forEach(function (f) {
      var value = (f[1] || '').trim();
      if (value) {
        params.set(f[0], value);
      }
    });

    // Optional: fill in the customer's phone number and the first message
    // params.set('phoneNumber', '{!JSENCODE(Service_Request__c.Phone__c)}');
    // params.set('message', 'Hi, this is about your service request.');

    document.getElementById('startConversation').src =
      '{!$Setup.goquiq__quiqSettings__c.goquiq__quiqUrl__c}/app/messaging/widget/startConversation?' + params.toString();
  </script>
</apex:page>

Besides Start Conversation field IDs, the Start Conversation window accepts:

ParameterWhat it fills in
phoneNumberThe customer's phone number
messageThe text of the first message, which the agent can edit before sending

3. Create the action and add it to the record page

Follow steps 3 and 4 of Send Notification for a Single Record above, with these changes:

  • Select your custom object in Object Manager.
  • For Visualforce Page, select QuiqStartConversation.
  • For Label, enter Start Conversation. For Name, enter Start_Conversation_Detail.

4. Check that it works

Open a record of your object and select Start Conversation. The Start Conversation window opens with the fields
filled in from the record.

Pass Data with the QuiqData Lightning Event

The Quiq package includes a QuiqData Lightning event (package version 1.4 and later). A component on a record
page can fire it to send that record's phone number to the Quiq Messaging component. When the agent selects +
in Quiq Messaging to start a new conversation, the phone number is already filled in.

The event's payload:

{
  quiqData: {
    phoneNumber?: string,
    recordId: string,
  }
}

The example below adds an invisible component to Case record pages. It sends the phone number of the Case's
Contact or Account.

1. Create the component

  1. In Lightning Experience, select the gear icon, then Developer Console.
  2. Select File → New → Lightning Component.
  3. Name it QuiqProxy, leave the other options blank, and select Submit.
  4. Replace the contents of QuiqProxy.cmp with the following and save:
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
  <aura:registerEvent name="quiqDataEvent" type="goquiq:QuiqData"/>
  <aura:attribute name="recordData" type="Object"/>
  <force:recordData aura:id="recordLoader"
    recordId="{!v.recordId}"
    targetFields="{!v.recordData}"
    recordUpdated="{!c.handleRecordUpdated}"
    fields="Account.Phone, Contact.Phone, Contact.MobilePhone, Contact.HomePhone, Contact.OtherPhone, ContactPhone"
  />
</aura:component>

aura:registerEvent registers the component to fire QuiqData. force:recordData loads the listed fields of the
current record and calls handleRecordUpdated when they load or change.

  1. On the right side of the Developer Console, select Create next to CONTROLLER.
  2. Replace its contents with the following and save:
({
  handleRecordUpdated: function(component, event, helper) {
    var eventParams = event.getParams();
    if (
      eventParams.changeType === "LOADED" ||
      eventParams.changeType === "CHANGED"
    ) {
      var record = component.get("v.recordData");
      var phoneNumber =
        record.ContactPhone ||
        (record.Account && record.Account.Phone) ||
        (record.Contact &&
          (record.Contact.MobilePhone ||
            record.Contact.Phone ||
            record.Contact.HomePhone ||
            record.Contact.OtherPhone));

      var appEvent = $A.get("e.goquiq:QuiqData");
      appEvent.setParams({ quiqData: { phoneNumber: phoneNumber, recordId: record.Id } });
      appEvent.fire();
    }
  }
});

The controller uses the Case's Contact phone first, then the Account's phone, then the Contact's other phone
numbers. It runs again whenever the record changes.

2. Add the component to the record page

  1. In Object Manager, select Case, then Lightning Record Pages.
  2. Open the page that has the Quiq components and select Edit.
  3. Drag QuiqProxy from the custom components onto the page. Its position doesn't matter; it has no content and
    takes up no space.
  4. Select Save.

3. Check that it works

  1. Open a Case whose Contact has a phone number.
  2. In Quiq Messaging, select + to start a new conversation. Customer Phone Number is filled in from the
    Contact.

Troubleshooting

ProblemWhat to check
The button doesn't appear on the recordSee the Button doesn't appear? note under Send Notification for a Single Record. Check that the Visualforce page has Available for Lightning Experience checked.
The Quiq window is blank or asks for a loginCheck that Quiq URL in Quiq Settings is your Quiq site with no trailing slash, and that the Trusted URLs are set up. Log in to Quiq in the same browser.
The phone number is filled in, but message variables aren'tCheck that each variable name matches exactly, including case, has no period, and has no Field selected. If none of the variables fill in, contact Quiq support to confirm message variables are turned on for your site.
A message is sent with {{variable}} in the textSalesforce had no value for that field. Add a Fallback to the variable.
A value is cut off or missing charactersMake sure the page uses URLSearchParams and JSENCODE as in the examples. Curly braces ({ and }) are removed from values passed to message variables.
The button opens the wrong page, or is missing fieldsIn Buttons, Links, and Actions, check which Visualforce page the action points to. Another page with a similar name may have been selected.

Did this page help you?