Wix Answers Help Center
Backoffice SDK
Important
Improperly applying customizations with the backoffice SDK can impact the Wix Answers App experience.
The Backoffice SDK enables you to add JavaScript code to customize the Wix Answers App, which is used by agents and administrators. You manage this SDK by adding JavaScript to the Custom JS pane on the Backoffice Custom Code page (https://<tenant_subdomain>.wixanswers.com/app/settings/custom-code).
You can test the code in your browser console before entering it on the Backoffice Custom Code page.
The following are some examples of what you can do using the SDK.
You can test the code in your browser console before entering it on the Backoffice Custom Code page.
The following are some examples of what you can do using the SDK.
Note
If you have specific integration needs not met using the existing SDK, contact us at support@wixanswers.com with your request.
Methods
addListener(eventType:EventType, listener:function)
Add a listener for an event. Different payload are sent for different events.
Returns: None
The event types are as follows:
Returns: None
The event types are as follows:
Type | Description | Payload |
---|---|---|
eventTypes.appLoaded | App Loaded | None |
eventTypes.ticketLoaded | Ticket page loaded | {ticket: Ticket object, timeline: Ticket timeline object} |
eventTypes.ticketUpdated | Ticket updated | {ticket: Ticket object} |
eventTypes.ticketSidebarLoaded | Ticket sidebar loaded | {ticket: Ticket object} |
eventTypes.ticketWillLoad | Ticket page is about to be loaded | {ticket: Ticket object, timeline: Ticket timeline object} |
eventTypes.ticketInfoSectionAdded | An info section was added to a ticket | {sectionTitle: string} |
eventTypes.ticketRelationAdded | Article relation added to a ticket | {ticket: Ticket, articleIds: [list of article GUIDs]} |
eventTypes.ticketReplied | Agent replied to a ticket (not internal note) | {ticket: Ticket, replyContent: string} |
eventTypes.ticketCustomFieldsUpdated | Ticket's custom field value added or modified | {ticket: Ticket, customFields: Map of {<field-name>: <value>}} value format varies according to field type. |
eventTypes.timelineItemLoaded | Timeline item loaded | |
eventTypes.timelineLoaded | Timeline loaded | |
eventTypes.ticketEndSession | Agent ended handling the ticket | |
eventTypes.multipleTicketsReplied | Agent replied in bulk to multiple tickets (not internal notes) | {tickets: [list of ticket objects], replyContent: string} |
eventTypes.multipleTicketsRelationAdded | Article relation added in bulk to multiple tickets | {tickets: [list of ticket objects], articleIds: [list of article GUIDs]} |
eventTypes.customFieldsPanelConfigurationAdded | Case Details panel loaded | {panelName: string, clearFieldsOnParentChange: Boolean, customFields: [{id: custom field name, required: Boolean, dependentField: { <value>: [list of other custom field names] }, ...}, ...] } |
eventTypes.onCallDeviceRendered | Incoming call appears to agent | {ticket: extended ticket object, userPhoneNumber: phone number object} |
1 2 3 4
answersBackofficeSdk.addListener( answersBackofficeSdk.eventTypes.ticketLoaded, function() { console.log("ticket loaded") } );
addTicketInfoSection(title:string, HTML:string, isOpen:Boolean, tag?:string)
Add custom information section to the right sidebar when viewing a ticket.
Set the third parameter to true to configure that the new section is open by default.
Set the fourth parameter if you are using reorderTicketInfoSections (see below).
Returns: Boolean (true on success, false on failure)
forceSavedRepliesSearchLocale(locale:locale string)
Configure that saved replies are searched only in the specified locale.
Returns: None
Returns: None
getAgentSignature
Get the current agent signature.
Returns: String
getCurrentAgent
Get current agent.
Returns: Agent object
Returns: Agent object
insertHtmlToReplyArea(HTML:string)
Append HTML to the reply area without sending the reply.
Returns: None
Returns: None
notify({content: string})
Pop up a UI notification on the bottom right of the screen.
Returns: None
Returns: None
1 2 3
answersBackofficeSdk.notify( {'content': 'Something wonderful happened!'} )
relatedArticleAction(articleId:string, action:ArticleAction)
Perform actions regarding related articles. These simulate the actions normally performed by buttons on the page.
Returns: None
The actions are as follows:
Action | Description |
---|---|
on-link | Add link to article as a timeline entry. |
on-unlink | Remove timeline link to article. |
paste-link | Paste link to article into an agent reply. |
use-content | Paste article content into an agent reply. |
1 2 3
answersBackofficeSdk.relatedArticleAction('article-GUID', 'use-content'); answersBackofficeSdk.relatedArticleAction('article-GUID', 'paste-link'); answersBackofficeSdk.relatedArticleAction('article-GUID', 'on-link');
reorderTicketInfoSections([section-tag:string, ...])
Order the info sections on the ticket sidebar. Use the following tags, depending on the info section:
- Default section:
- recent-tickets
- technical-data
- custom-fields
- case-details
- Integration:
- Use the integration title, changing spaces into underscores (_). For example, use Salesforce_-_staging for the integration Salesforce - staging.
- Custom information section (added using addTicketInfoSection):
- Use the tag specified when adding the section.
Sections not listed in this method appear at the bottom.
Returns: None
1 2 3 4 5 6 7 8 9 10 11
answersBackofficeSdk.reorderTicketInfoSections([ "Salesforce", "recent-tickets", "technical-data", "custom-fields", "case-details", "Shopify", "Jira", "Hubspot", "Shopify" ]);
setAgentSignatureOverride(ticketProperties:structure, currentSignature:string)
Set a dynamic signature for the current agent. The signature changes based on the ticket. The parameters sent to this function include properties of the ticket object and the current, existing signature. The properties structure is as object, as follows:
{
// Ticket custom fields, map of field names to values
customFields: {"field GUID": "value1", "field GUID": "value2", ...},
// User custom fields, same as above
usersCustomFields: {...},
// Language code, such as "en"
locale: string,
// List of label objects
labels: [Label object 1, Label object 2, ...]
}
Note that some custom fields may not appear in the UI. If you want the signature to change when a user selects a custom field, ensure that this custom field is one that appears in the UI.
This function returns the new signature.
Returns: The new signature (string)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
answersBackofficeSdk.setAgentSignatureOverride((ticketProperties, signature) => { if (ticketProperties.customFields && ticketProperties.customFields.regulator) { return`${signature} <br /> ${ticketProperties.customFields.regulator}`; }; if (ticketProperties.labels && ticketProperties.labels.some(label=>label.name === 'Twitter ticket')) { return`${signature} <br /> Sent from twitter`; }; const ageCustomFieldId = '8cfb43d5-2890-4902-8133-db8837ee17c7'; if (ticketProperties.usersCustomFields && ticketProperties.usersCustomFields[ageCustomFieldId] === 30) { return`${signature} <br /> is 30 years old`; } if (ticketProperties.locale && ticketProperties.locale === 'fr') { return `${signature}, <br /> France`; } return signature });
setCustomFieldsPanelConfiguration({panelName:string, clearFieldsOnParentChange:Boolean, fields:[see below]})
Display an additional custom fields panel (known as the Case Details panel) alongside tickets in the app, and configure which custom fields appear in this panel. In addition, configure field dependencies for this panel. The dependencies enable you to define which custom fields appear in the panel depending on the values selected in other custom fields in this panel.
If you do not call this method, the panel does not appear.
The input contains a list of field structures, each one defining a field and optionally its dependencies. To have a field appear in all cases, not as a dependency, it must be at the top level in one of these structures. To have it appear as a dependency, it must be within a dependentFields sublevel.
Dependencies can be cascaded; in other words, you can configure field-B to appear only if a certain value is selected for field-A and for field-C to appear only if a certain value is selected for field-B.
Case Details Panel Only
This method does not affect the custom fields that appear in the Custom Fields panel, which always displays all custom fields.
Note
Each custom field MUST NOT appear more than once. In other words, each field must a) not appear, b) be a top level field, or c) be a dependent field of exactly one other field.
The input is as follows. Setting required for a field in the input overrides the mandatory setting defined for that field.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
answersBackofficeSdk.setCustomFieldsPanelConfiguration({ panelName: 'Panel Name (this field is mandatory)', clearFieldsOnParentChange: Boolean, fields: [ { id: '<custom field 1 GUID>', required: Boolean, dependentFields: { <custom field 1 value>: [ { id: '<custom field 2 GUID>', required: Boolean, dependentFields: { ... } }, ... ], ... }, ... }, ... ] });
For example, if custom field 1 value is 5, then custom field 2 appears on the page only if 5 if selected for the value in custom field 1 value. If the value is changed to something other than 5, the dependent fields are rehidden. Values in hidden fields are not submitted with the contact form.
If the value is changed, the dependent fields are rehidden in the panel (but continue to appear in the Custom Fields panel, as usual).
If you run this before the page is loaded, it will take effect when the page is loaded.
clearFieldsOnParentChange: When set to false (default), when you change a parent field value, values in all (now-hidden) dependent fields remain as they are. When set to true, all values are cleared from these dependent fields.
Returns: None
In the following example, the custom field OS Type appears in the panel. When the user selects Windows as a value for this field, the field Windows Version appears. When the user selects XP as a value for the Windows Version field, the field Patch Level appears. None of the fields are mandatory fields.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
answers.setCustomFieldsPanelConfiguration( { fields: [ { id: '77bc8694-5ccf-436c-ab2b-543563a5f425', required: false, dependentFields: { Windows: [ { id: 'bd948e62-a3fd-4cf0-87f3-ee6a0ae7f3fa', required: false, dependentFields: { XP: [ { id: 'd367738e-368e-41fe-9289-1a5cbbc3c239', required: false, } ] } } ] } } ] });
setEndSessionCheck(handler:function(ticket:Extended Ticket Object, )
Check whether the agent can end handling a ticket. The parameter is a callback function that can be used, for example, to display a confirmation pane. The ticket object is sent to the callback function.
Returns: Boolean: true to end handling the ticket, false otherwise.
1 2 3 4 5 6
answers.setEndSessionCheck((ticket) => { if (ticket[...] > ...) { return false; } return true; });
setInactiveAssignEntetiesCallback(ticket:Extended Ticket Object)
Set inactive agents and/or groups in the ticket assign component (on the left in the ticket page footer). This function is asynchronous. The parameter to the function includes the ticket. The function returns a map of agent/group GUIDs and reasons why they are inactive (the reason appears in the mouseover).
Returns: Structure (see above)
1 2 3 4 5 6 7
answersBackofficeSdk.setInactiveAssignEntetiesCallback(async (ticket) => { return { 'group-GUID': 'Outside working hours', 'group-2-GUID': 'Does not support ticket language', 'agent-GUID': 'Agent is busy', } });
setNewTicketSettingsOverride(settings:structure)
Configure the pane that appears when the user selects New Ticket.
The input is an object, as follows:
{
tab: 'by-agent' | 'on-behalf', // Whether to open the To a Customer or On Behalf of a
// Customer tab, by default. The default is by-agent
// (To a Customer).
additionalInfoOpen: boolean, // Whether to expand the Additional Ticket info section when
// the pane opens. The default is false.
customerInfoOpen: boolean, // Whether to expand the Customer info section when
// the pane opens. The default is false.
additionalActionsOpen: boolean, // Whether to expand the Additional Actions section when
// the pane opens. The default is false.
};
Returns: None
1 2 3 4 5 6
answersBackofficeSdk.setNewTicketSettingsOverride({ tab: 'on-behalf', additionalInfoOpen: true, customerInfoOpen: true, additionalActionsOpen: false });
setTicketPageCustomFieldsFilter(filters:object)
Filter custom fields available to select in the custom fields picker.
The input is an object, as follows:
{
The input is an object, as follows:
{
return {
customerFields: [<list of user custom fields to include>],
companyFields: [<list of company custom fields to include>],
ticketFields: [<list of ticket custom fields to include >]
customerFields: [<list of user custom fields to include>],
companyFields: [<list of company custom fields to include>],
ticketFields: [<list of ticket custom fields to include >]
}
}
}
Note that for ticket custom fields (only), use the ticket field GUID. For user and company custom fields, use the custom field names.
If a parameter is not included, then all fields of that type appear in the custom fields picker. If the parameter is included but it is empty, then no fields of that type appear in the custom fields picker.
Returns: None
1 2 3 4 5 6 7
answersBackofficeSdk.setTicketPageCustomFieldsFilter(() => { return { customerFields: ['fn1'], companyFields: ['fn2'], ticketFields: ['d367738e-368e-41fe-9289-1a5cbbc3c239'] }; });
setTicketRelatedArticlesFilter(filters:object)
Filter articles available to select in the related articles picker.
The input is an object, as follows:
{
categoryIds: [<list of categories to include if the article matches any of them>],
excludeCategoryIds: [<list of categories to exclude if the article matches any of them>],
hasAllOfLabelIds: [<list of labels to include if the article matches all of them>],
hasAnyOfLabelIds: [<list of labels to include if the article matches any of them>],
notHasAnyOfLabelIds: [<list of labels to exclude if the article matches any of them>],
}
Returns: None
The input is an object, as follows:
{
categoryIds: [<list of categories to include if the article matches any of them>],
excludeCategoryIds: [<list of categories to exclude if the article matches any of them>],
hasAllOfLabelIds: [<list of labels to include if the article matches all of them>],
hasAnyOfLabelIds: [<list of labels to include if the article matches any of them>],
notHasAnyOfLabelIds: [<list of labels to exclude if the article matches any of them>],
}
Returns: None
Examples
Adding a Custom Section in the User Information Sidebar
To create a custom section in the user's information side bar inside a ticket page, add two methods:
- answersBackofficeSdk.addListener
- answersBackofficeSdk.addTicketInfoSection
The first method enables Wix Answers to listen to the "ticket page loaded" event and receive the ticket's data. The second enables Wix Answers to add custom sections to the side bar.
Here is an example of a snippet that queries some service, checks if the user that opened the ticket is a "premium" user or not, and adds a custom section to the ticket page side bar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
function isPremiumUserByEmail(email, cb) { var isPremium = Math.random() > 0.5; //dummy check, replace this with an AJAX call to an external service, or any other meaningful action cb(isPremium); } function addPremiumUserSidebarItem(isPremium) { answersBackofficeSdk.addTicketInfoSection('Custom Data', '<p>Premium: ' + isPremium + '</p>'); } answersBackofficeSdk.addListener(answersBackofficeSdk.eventTypes.ticketLoaded, function (ticketData) { console.info(ticketData); isPremiumUserByEmail(ticketData.user.email, function (isPremium) { addPremiumUserSidebarItem(isPremium); }); });
Test this script by adding it in the developers console and then navigating to a ticket page. To add this to your site, enter the script in the Custom JS pane on the Backoffice Custom Code page.
When the script is active, your sidebar includes the following:
When the script is active, your sidebar includes the following:
Hide Widgets from the Settings Menu
Add the function answersBackofficeSdk.setHiddenWidgetIds to make widgets accessible only using a direct link. This is useful if you want to prevent accidental changes to your widget's settings.
1 2 3 4
answersBackofficeSdk.setHiddenWidgetIds([ 'a601657c-d618-be0f-a943-e6181512073f', 'b342347a-1528-4fed-2323-234234ababa2' ]);
Was this article helpful?