Getting Started

Web1on1's API that lets you build automations extending the agent console. You can build Web1on1 automations in any language, and run them on any platform: all you need is for your automation to talk to Web1on1 over open Web protocols (HTTPS, REST, OAuth, JWT).

Using the Web1on1 messaging API, your automation can:

  • Listen to Web1on1 events via webhooks
  • Call the Web1on1 REST API
  • Create new conversations
  • Send messages to Web1on1 conversations
  • Add search results, info panels and bot bubbles
  • Respond to bot commands
  • Enqueue and assign conversations
  • Augment and process form results
  • Change conversation state and meta data

Conversations

Note: when referring to an 'agent' we mean an API user or agent console user that has the 'agent', 'bot' or 'admin' role - from the perspective of the consumer, these users all act as the 'agent'. The term 'contact' and 'consumer' are used interchangably.

Conversation Models

Web1on1 makes a distinction between two types of conversations:

  • Consumer conversation A conversation between a consumer and one or more agents.
  • Team conversation A conversation between one or more agents.

Conversation type: 'contact'

A Consumer conversation should really only be created by an integration; it has a conversation.contact property (a contact ID) that represents the consumer that initiated the conversation. Each contact in the system is linked to exactly one conversation; in the UI, his/her chat messages are aligned to the left, and the responses of agents are aligned to the right. After the last agent closes this conversation, he/she may be notified of new contact messages through channel notifications.

Conversation type: 'bot', 'agent' or 'system'

A Team conversation is initiated by an agent or a bot. It does not have a conversation.contact property, since there's no consumer taking part of the conversation. New messages in the conversation will have all non-active participants' inbox flag set. The conversation type is set to the role of whoever created the conversation; a 'system' type conversation is usually the Welcome Bot.

Conversation Lifecycle

The conversation.status property is maintained by the system, and can represent one of four states - queued active closed or archived

  • queued: channels or channelsOffline are targeted (last message from contact), or a particant inbox is true;
  • active: at least one participant is active and has accepted the conversation
  • closed: no active participants have the conversation accepted, and no unread contact messages.
  • archived: conversation was merged into a target conversation.

When a contact sends a first message, the conversation is queued and channels are notified. On acceptance by an agent, the conversation becomes active (and agents can join/leave the conversation) until the last agent leaves, which will have the status set to closed - until the contact sends another message, which will queue the conversation again, or re-opening (joining) by an agent which will set it to active

Conversation Context

Messages in a conversation can be exchanged within a certain conversation.context - a sequence of messages grouped by a common goal, within a specific session.

The conversation.context property is a string consisting of a 'goal' and a 'session' part separated by a dot. The goal represents something that should be accomplished, and the session is a random identifier that can span multiple goals.

Example of a context switch after the second message):

  conversation: { context: "dispatcher.yU78soqB" }
1      message: { context: "dispatcher.yU78soqB" }
2      message: { context: "dispatcher.yU78soqB" }
  conversation: { context: "book-meeting.yU78soqB" }
3      message: { context: "book-meeting.yU78soqB" }

As a conversation state variable, there can only be at most one context set at any given time.

Automatically keeping track of context

By default, the conversation.context and message.context properties are set by the system, using the following heuristics:

  • When the conversation is assigned to a bot, the context is set from the bot's name.
  • When a form is added, the context is set, based on the form name.
  • When a form is sent as a form result, or removed, the context is cleared.
  • When a bot leaves the conversation, the context is cleared if it's based on the bot's name.
  • When the conversation is closed by the last active participant, the conversation context is cleared.

Bots can use the /set @context command to set, change or clear the context themselves, if needed.

Sessions can span multiple contexts

When a context is set, a session identifier is added to the context string. When switching contexts in an active conversation, the session identifier is copied into the new context. When all participants leave the conversation, both the session and context are cleared, and a new session identifier will be added to future contexts.

Example

context

In the example above, we can see two bots talking to a contact, in the following context sequence:

  1. The conversation is assigned to the first bot (B1) called "Dispatcher". This sets the context goal as the normalized name of the bot (dispatcher) with a new session identifier ( yU78soqB) attached.
  2. The conversation is re-assigned to the second bot (B2) called "Book Meeting". The context changes to the new bot name, while retaining the session.
  3. After both bots have left the conversation, both the context and session are cleared.
  4. When the contact returns, it's assigned (by routing rules) to the Dispatcher (B1) again, and a new 'dispatcher' context starts with a fresh session ( wOxx5aB).

These bots could use the /set @context command to override the default context goals set by the system.

Conversation Participants

An agent is added as a participant to a conversation when the agent joins the conversation (participant.active set to true), usually after having been notified through one or more channels. The agent is also added when assigned the conversation (participant.inbox set to true).

Assigning and joining/leaving is done by sending messages into the conversation - see chapter 5 for details.

Create a Team Conversation

All API requests are made on behalf of the user owning the API key (usually a 'bot' user) and the organization the user is a member of - the default user and organization properties used when creating conversations and messages.

To create a new conversation, just POST to the conversations endpoint. For convenience, you may supply an array of message objects to convert into message resources. It is recommended to include an /assign or /notify command, to to target one or more user inboxes or notify channels to act on the conversation.

Request: POST /v2/conversations

{
    "messages": [
        {
            "text": "Hello"
        },
        {
            "type": "command",
            "text": "/notify",
            "meta": {
                "channels": [
                    "5b2bf9dd9f3c885eb7ad7a63"
                ]
            }
        }
    ]
}

Response: 201 CREATED

{
    "organization": "aaa111111111111111111111",
    "orgPath": "aaa111111111111111111111",
    "name": "Gnoboris Finestrip",
    "type": "bot",
    "slug": "SJPFDsaYX",
    "url": "https://app.web1on1.chat/c/SJPFDsaYX",
    "status": "queued",
    "participants": [
        {
            "updatedAt": "2018-09-30T01:31:43.457Z",
            "createdAt": "2018-09-30T01:31:43.457Z",
            "name": "awesome bot",
            "avatar": "https://storage.googleapis.com/cs2-uploads/avatars/ca6e1762-988e-4cbc-becb-ad952b6df9a4.png",
            "user": "aaa000000000000000000111",
            "unreadCount": 0,
            "inbox": false,
            "accepted": false,
            "active": false,
            "role": "bot"
        }
    ],
    "messages": [
        "5bb0277fd99faf11a3f4a37f",
        "5bb0277fd99faf11a3f4a380"
    ],
    "channels": [],
    "channelsOffline": [],
    "forms": [],
    "results": [],
    "createdBy": "aaa000000000000000000111",
    "updatedAt": "2018-09-30T01:31:43.458Z",
    "createdAt": "2018-09-30T01:31:43.425Z",
    "id": "5bb0277fd99faf11a3f4a37e"
}

This will create a conversation, run routing rules and notify any resulting channels.

Instead of notifying channels, you may want to target a specific set of users. For example, to have a conversation pop up in some users' inboxes):

Request: POST /v2/conversations

{
    "name": "Announcement",
    "messages": [
        { "text": "I'm getting married!" },
        { "text": "/assign", "type": "command", "meta": { "users": ["5ade8cd0c8287923aede5e0d"] } },
    ]
}

You (the owning agent of the API key) are added to the conversation as a participant. When one of the recipients replies, your inbox flag will become truthy, and when logged into the console you'll receive an inbox notification.

Create a Consumer Conversation

The previous conversations we created were team conversations. Automations should, in general, only create contact conversations when:

  • operating as an integration to a consumer endpoint, or
  • creating a business-initiated conversation

See chapter 8. Outbound Messaging for details on creating outbound messaging campaigns.

Update a Conversation

Any changes to active conversations are propagated through the UI to the currently active agent, if any. Typically conversation updates are used for:

  • re-routing to new channels, (eg on escalation)
  • re-assigning to new agents
  • context switching ('category' property),
  • setting results for active forms
  • updating contact profile
  • force-setting contact presence status
  • setting anchor links

Updates to the conversation state can be done through Command messages. For example, to assign a 'queued' conversation to a specific agent:

Request: POST /v2/conversations/590bd49f458b716046347f47/messages

{
    "type": "command",
    "text": "/accept",
    "user": "bbb000000000000000444444"
}

In addition to commands, messages typed form and field are used to change the state of the conversation. See the chapters on Commands and Forms and Fields for more examples.

Each conversation and each message has a unique url property, (accessible in the API and through webhook payloads), built up by adding the conversation.slug or message.slug as a URL path segment to a base domain (default: app.web1on1.chat).

So conversation- and message links are formatted like this:

    `https://${organization.domainPrefix}.${organization.domain}/c/${conversation.slug}`
    `https://${organization.domainPrefix}.${organization.domain}/m/${message.slug}`

By default, these links point towards the Web1on1 agent console, and will resolve to their canonical URLs:

https://app.web1on1.chat/conversations/590bd49f458b716046347f47
https://app.web1on1.chat/conversations/590bd49f458b716046347f47#5dcb1ede6b63474094c43461

Linking to a custom domain

To have the API generate URLs using a custom base domain, simply update the organization:

Request: PATCH /v2/organizations/5c7574c78ae07962b12e264c

{
    "domainPrefix": "www",
    "domain": "example.com"
}

This would generate conversation and message URLs similar to

https://www.example.com/c/D60eCpa4
https://www.example.com/m/Ui6lxBY0m

Organization domains are inherited by child organizations (subsidiaries).

Links to conversations are solely provided to active CS consumer touchpoints. See chapter 8: Messaging to Consumers for details.