Actions
  • 09 Sep 2022
  • 7 Minutes To Read
  • PDF

Actions

  • PDF

Gladly Actions allow you to extend Gladly's UI to add functionality that Gladly does not natively provide, including the ability to call into other external systems. This guide gives detailed insight into Actions.

Note - Actions require an open Conversation

Actions is only available in open Conversations. Once a Conversation is closed, Actions become unavailable.

Background

Imagine being able to add a button to a transaction card that allows an Agent to cancel an order or reactive a subscription:

image.png

Or create a discount code:

image.png

Introduction

Gladly Actions can be applied to two targets: Customers and Transactions.

Actions may not be applicable to all Profiles and Transactions. They can be conditionally shown.

All Agents can perform all actions.

Tip - Transaction-level Actions

Actions at the transaction level are only available for ORDER and SUBSCRIPTION.

High-Level Actions

  1. Agent visits the linked Customer page, which triggers a detailed lookup to your Lookup Adaptor.
  2. When Gladly receives the lookup response, we display any relevant actions alongside the order, subscription, or Plus menu.
  3. Agent initiates an Action by selecting it in the order, subscription, or from the Plus menu.
  4. Gladly fetches the action form and action submit endpoint from your Lookup Adaptor and displays it to the Agent.
  5. Agent fills out and submits the form, which calls the submit Action endpoint specified in step four.
    1. If either form validation fails or action submit fails, Gladly displays errors to the Agent.
    2. If the action succeeds:
      1. Gladly logs an audit event in the conversation feed.
      2. Gladly refreshes the order or subscription data, which reflects updates from the action just performed.

Configuring Actions via Detailed Lookup

To configure Actions, your Customer lookup service should respond to the Detailed Lookup request by returning an array of actions per Profile and Transaction.

Gladly uses the name of the Actions you define to display to Agents.

Example Detailed Lookup Response With Actions Configured

Sample Detailed Lookup request response with actions on the transaction and profile level.

POST https://your-lookup-adaptor-url.com

Text
{
  "results": [
    {
      "externalCustomerId": "12345",
      "actions": [
        {
          "name": "Discount Code (Shopify Retail)",
          "formUrl": "/action?customer=12345"
        }
      ],
      "emails": [
        {
          "original": "email@email.com"
        }
      ],
      "phones": [
        {
          "original": "+16501234567",
          "type": "MOBILE"
        }
      ],
      "customAttributes": {
        "points": "$100.00"
      },
      "name": "First Last",
      "transactions": [
        {
          "type": "ORDER",
          "orderId": "12345",
          "actions": [
            {
              "name": "Cancel Refunded Order",
              "formUrl": "/cancel?customer=12345&order=12345"
            }
          ]
        }
      ]
    }
  ]
}

image.png

Action Fields

FieldTypeRequiredDescription
formUrlURLYesURL to use to fetch the actions form configuration. URL must be relative to the lookup service path defined in More Settings > Apps. Uses the same authentication as your Lookup Adaptor. URL may include query parameters. URL must be in String format.
nameStringYesDisplay name for action button.

Configuring the Form for a Specific Action

When the Agent clicks the Action button, the details for the Action are retrieved. The expected response informs how the Action form display. At the bottom of the form, there are two buttons for confirming or cancelling.

Example Response and Corresponding Form

This call occurs when an agent presses an action button on your Lookup Adaptor. Let's use the cancel order action example above:

GET https://your-lookup-adaptor-url.com/cancel?customer=12345&order=12345

Text
{
  "actionUrl": "/actions/cancel?orderNumber=1390",
  "title": "Cancel order #1391",
  "submitButton": "Cancel Order",
  "closeButton": "Close",
  "sections": [
    {
      "type": "input",
      "label": "Reason",
      "attr": "reason",
      "input": {
        "type": "select",
        "placeholder": "Please select a reason…",
        "optional": false,
        "options": [
          {
            "text": "Order mistake",
            "value": "order-mistake"
          },
          {
            "text": "Ships too late",
            "value": "ships-late"
          }
        ]
      },
      "hint": "Cancelation reason is required"
    },
    {
      "type": "input",
      "attr": "reason",
      "defaultValue": false,
      "input": {
        "type": "checkbox",
        "text": "Send a notification to the customer"
      }
    }
  ]
}

image.png

Action Form Response Fields

FieldTypeRequiredDescription
titleStringYesForm title. Appears at the top of the form.
actionUrlURLYesEndpoint to POST with form contents when form is submitted. URL is relative to the base lookup URL configured in More Settings > Apps. Uses same auth mechanism as that configured in More Settings > Apps as well.
closeButtonStringNoText for close button (to cancel the action)
submitButtonStringNoTest for submit button (to complete the action)
sectionsArrayNoInput fields. See Text Section and Input Section documentation below

Text Section

Text
{
  "type": "text",
  "text": "This is a text section. It is nothing fancy, just some plain text"
}

Text Section Fields

FieldTypeRequiredDescription
typeStringYesAlways specify as text
textStringYesThe text to display

Input Section

Input section elements are elements that wrap a text | select | checkbox.

Text
{
  "type": "input",
  "attr": "notify",
  "input": {
    "text": "Send a notification to the customer.",
    "type": "checkbox"
  }
}

Input Section Fields

FieldTypeRequiredDescription
typeStringYesAlways specify as input
labelStringYesThe label to display next to the input field
attrStringYesField name in the JSON repsonse. Must be unique across all form fields.
defaultValueBooleanNoInitial value for the field. This value will update whenever the agent edits the field, and will be passed as the value corresponding to the key named in the name field in the JSON response.
inputStringYesInput element. One of text or select or checkbox.
hintStringNoOptional hint string that appears beneath the input.

Text Input

These elements are simple single-line text inputs.

For example, to make a discount code of SALE20:

Text
{
  "type": "text",
  "placeholder": "e.g. SALE20",
  "optional": false
}

Text Input Fields

FieldTypeRequiredDescription
typeStringYesAlways input
placeholderStringNoString that appears in the input when it has no value
optionalBooleanNoWhether the text input must have some content filled out. The form will display an error before submission if there is no content. Default is false.

Checkbox Input

This element renders a checkbox.

image.png

Text
{
  "text": "Send a notification to the customer",
  "type": "checkbox"
}

Checkbox Input Fields

FieldTypeRequiredDescription
typeStringYesAlways checkbox
textStringYesLabel for the checkbox

Select Input

These elements render a dropdown menu where an Agent can choose a single option. In the future, there will be multiple options.

image.png

Text
{
  "type": "select",
  "placeholder": "Please select a reason…",
  "options": [
    {
      "text": "Order mistake",
      "value": "order-mistake"
    },
    {
      "text": "Payment declined",
      "value": "declined"
    }
  ],
  "optional": false
}

Select Input Fields

FieldTypeRequiredDescription
typeStringYesAlways select
optionsArrayYesArray of select-option elements
placeholderStringNoString that appears in the input when it has no value
optionalBooleanNoWhether the select input must have some content filled out. The form will display an error before submission if there is no content. Default is false.

Select Option Fields

These elements comprise the options presented in the select-input dropdown menu.

image.png

Text
{
  "text": "Order mistake",
  "value": "order-mistake"
}
FieldTypeRequiredDescription
textStringYesText that appears in menu item
valueStringNoValue that is submitted as select-option value in the JSON response. If not provided, text field value will be used

Submitting the Form

When the confirm button is clicked in the form, an HTTP POST request is made to the url specified in the form with the elements the agent entered into the form.

POST https://your-lookup-adaptor.com/actions/cancel?orderNumber=1390

Text
{
  "actionUrl": "/actions/cancel?orderNumber=%231390",
  "notify": true,
  "reason": "declined"
}

The request payload will have the values specified in the form inputs.

Form Errors

When the form is submitted, there are 3 possible types of errors.

  • Validation
    • Agent entered invalid data
  • Permanent
    • Order is no longer valid to be returned
  • Other
    • For example, a network timeout

Validation Errors

Validation errors occur when the Agent needs to correct data in the form.

The form will be updated with the error text and re-displayed for the Agent to correct the information.

To show a validation error, the service should respond to the form submission with 400 Bad Request response, and a payload that looks like the following.

Text
// 400 Response - errors displayed in the form
{
  "errors": [
    {
      "attr": "value",
      "detail": "expected String to be a BigDecimal"
    }
  ]
}

Error Response Fields

FieldTypeRequiredDescription
errorsArrayyesArray of error objects

Error Object Fields

FieldTypeRequiredDescription
attrStringnoThe form attribute to assocaite with the error. Must match the attr of one of the form inputs. If no matching attr is provided, the error will not be displayed.
detailStringYesDescriptive text about the error.

Permanent Errors

Permanent errors occur when an Agents attempts an Action that is not possible. These errors appear as a red toast notification.

image.png

For example, if the Agent attempts to cancel an order that has already shipped, this is a permanent error.

When this type of response is returned:

  • The form closes.
  • The Agent sees an error message.
  • The detailed lookup refreshes to determine what actions remain available.

To show a permanent error, the service should respond to the form submission with a 406 Status Not Accepted status and a payload that looks like the following.

Text

// 406 - Permanent failure, do not allow agents to take action again
{
  "errors": [
    {
      "detail": "Cannot cancel a paid and fulfilled order"
    }
  ]
}

Other Errors

These can include:

  • Network timeouts
    • Gladly does not receive a response from the service in 15 seconds
  • 500 Internal Server Error where the service is not responding properly
  • 429 Too Many Requests where the service is overwhelmed
  • All other HTTP codes not enumerated above.

In these cases, Gladly will keep the form open and the Agent can retry submitting the Action.

Form Success

Any 20X response to form submission will be considered an indication of success.

When this type of response returns:

  • The form closes.
  • A record of the action performed adds to the conversation history.
  • The detailed lookup refreshes to determine what actions should remain available.
  • If the response body contains JSON in the following format, it will render in the success notification.
Text
// 200 - Success
{
  "message": "Order Refunded"
  "detail": "Order #1391 was refunded $25.00."
}

Success Object Fields

A default actions Conversation Timeline update is shown if "detail" or "message" is missing. Both must be configured to avoid the default action message.

custom app contact developer


FieldTypeRequiredDescription
messageStringYesBolded summary message to show in the action record.
detailStringYes
  • Detailed message to show in the action record.
  • URLs automatically turn into a clickable link in the UI. Format text like bold and underline using HTML in the string using. Additional formatting like bold/underline to a URL will no longer be clickable. 

image.png


Was this article helpful?