NAV Navbar
javascript python shell

Getting Ready

Signup and setting campaigns

Download GraphiQL

Please download Graphiql from here

Agent API

Endpoints

  1. Set the Endpoint to https://backend.alli.ai/d/graphql/ in GraphiQL

End point

Authorization

  1. You need get a token to access to the conversation list. You can get the token through the login mutation. > To get authorization token, use this code:
mutation m {
  login(email: "YOUR_EMAIL", password: "YOUR_PASSWORD") {
    token
  }
}
GRAPHQL_ENDPOINT = "https://backend.alli.ai/d/graphql/"

gql = """
mutation signin($email:String!, $passwd:String!) {
  login(email:$email, password:$passwd) {
    token
  }
}
"""
variables = {
  "email": "YOUR_EMAIL",
  "passwd": "YOUR_PASSWORD"
}

token = execute_gql(GRAPHQL_ENDPOINT, gql, variables=variables)['login']['token']
auth_headers = {
  'AUTHORIZATION': token
}
  1. Please put the token in HTTP header after clicking "Edit HTTP Headers" button. Header name is AUTHORIZATION and put the token in header value.

Http header

Overall structure

You can get project, campaigns, conversations, chats information through this API.

Please take a look at the following structure.

project
└─── campaigns
    └─── conversations
        └─── user
        └─── chats
            └─── UserChat
            └─── BotChat
            └─── AgentChat

Conversations list

  1. Retrieve conversations list by the following query.

Conversations

To get conversations list, use this code:

query getConversations {
  conversations(filter: {}, first: 5) {
    edges {
      node {
        id
        campaign {
          id
        }
        user {
          ownUserId
        }
        chats {
          edges {
            node {
              ... on UserChat {
                message
              }
              ... on AgentChat {
                message
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }
      }
    }
  }
}
gql = """
query getConversations($filter:ConversationFilterInput, $limit:Int) {
  conversations(filter:$filter, first:$limit) {
    edges {
      node {
        id
        user {
          ownUserId
        }
        chats {
          edges {
            node {
              ... on UserChat {
                message
              }
              ... on AgentChat {
                message
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }
      }
    }
  }
}
"""
variables = {
  "limit": 10  # Please add limit. see
}
conversations = execute_gql(GRAPHQL_ENDPOINT, gql,
              variables=variables,
              headers=auth_headers)['conversations']['edges']
for conv in conversations:
  conv = conv['node']
  id = conv['id']
  user = conv['user']['ownUserId']
  print(f"ConvId({id}), User({user})")
  for chat in conv['chats']['edges']:
    typename, message, options = get_plain_text(chat['node'])
    print(f"\t{typename} : {message}, {options}")
  1. If you want to get more fields you can simply add field name in the query. Re: all the available field names and types, you can check it in the schema section.

Campaign types

For example, if you want to get more fields, such as name and description of the campaign in each conversation, you can simply put them in the query.

To edit fields list, use this code:

query getConversations {
  conversations(filter: {}, first: 5) {
    edges {
      node {
        id
        campaign {
          id
          name
          description
        }
        user {
          ownUserId
        }
        chats {
          edges {
            node {
              ... on UserChat {
                message
              }
              ... on AgentChat {
                message
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }
      }
    }
  }
}
  1. Retrieving conversations query takes the following parameters. To see the detailed type specification of each parameters, please take a look at the schema documentation in GraphiQL.

Documentation

Query with the parameters.

For example, if you want to get the 3 conversations with the following conditions: - the campaign id is YOUR_CAMPAIGN_ID. Please replace YOUR_CAMPAIGN_ID to your real campaign id. - the user's name is Pocoyo

The query would look like

To get conversations list with parameters, use this code:

query getConversations {
  conversations(filter: {searchTerm: "Pocoyo", campaignIds: ["YOUR_CAMPAIGN_ID"]}, first: 3) {
    edges {
      node {
        id
        campaign {
          id
        }
        user {
          id
          firstName
          ownUserId
        }
        chats {
          edges {
            node {
              ... on UserChat {
                message
              }
              ... on AgentChat {
                message
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }
      }
    }
  }
}

Query with params

Getting latest conversations list

If you want to get latest conversations list, keep last conversation id. Then pass it to the after parameter.

The query would look like

To get latest conversations list, use this code:

query getConversations {
  conversations(filter: {}, after: "YOUR LAST CONVERSATION ID", first: 3) {
    edges {
      node {
        id
        campaign {
          id
        }
        user {
          id
          firstName
          ownUserId
        }
        chats {
          edges {
            node {
              ... on UserChat {
                message
              }
              ... on AgentChat {
                message
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }
      }
    }
  }
}

Getting meta information

You can put the meta information in the chatflow dashboard if you want to add your custom processing per users' choice. Meta

You can check the details of choices in GraphiQL client.

To get meta information, simply add choices in UserChat.

query getConversations {
  conversations(filter: {searchTerm: "Pocoyo", campaignIds: ["Q2FtcGFpZ246NWI5MzBjNGRmOWNhY2MwMjI4MGQ5OWY3"]}, first: 3) {
    edges {
      node {
        id
        campaign {
          id
        }
        user {
          id
          firstName
          ownUserId
        }
        chats {
          edges {
            node {
              ... on UserChat {
                message
                choices {
                    optionId
                    label
                    meta
                }
              }
              ... on AgentChat {
                message
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }
      }
    }
  }
}

Campaigns list

You can get whole campaign list in your project. You can filter the results by project ids, author ids, search term and on/off status. Please take a look at the CampaignFilter description in GraphiQL.

Please use the following code to retrieve all campaigns list.

query getCampaigns {
  campaigns(filter: {}) {
    edges {
      node {
        id
        name
      }
    }
  }
}

Users list

You can get the users list who participated your campaign. You can also filter the results by project ids, search term. Please take a look at the UserFilter description in GraphiQL.

Please use the following code to retrieve all users list.

query getCampaigns {
  users(filter: {}) {
    edges {
      node {
        id
        name
      }
    }
  }
}

FAQ API

Endpoints

  1. Set the Endpoint to https://backend.alli.ai/d/graphql/ in GraphiQL

Retrieve FAQ List By Popularity

Retrieving FAQ list query takes 3 parameters: order, limit, isUsed.

If you want to show 10 FAQ pairs with the popularity, please use the following query:

query getFaqList {
  project {
    faqs(order: SELECTED_COUNT_DESC, limit: 10) {
      count
      faqs {
        question
        answer
        selectedCount
        suggestCount
        askedBeforeAdd
        createdAt

      }

    }
  }
}

You will get the result like this: Faq result

What are SUGGEST_COUNT, HARD_SUGGEST_COUNT and SELECTED_COUNT?

Order options

What is limit?

Limit is the number of items that you would like to retrieve.

What is isUsed?

You can see on/off of each question/answer pair in https://app.alli.ai/faq.

Faq on off

If you would like to retrieve the question answer pairs that are not being used, please use isUsed: false in the query.

Chat API - Starting a conversation

In this section, we'll take a look at an example on how to start a conversation and subscribe to that conversation using Apollo Link.

You can check out this example here. Make sure to set API key, User ID, and placement variables.

Step 1

In order to start a conversation, you first need to obtain the API key of your project from project settings page in Alli dashboard.

const GRAPHQL_URI = "https://backend.alli.ai/d/user/";
const GRAPQHL_SUBSCRIPTION_URI = "wss://backend.alli.ai/d/ws/user";

// API key can be obtained from project settings page
const apiKey = "YOUR_API_KEY_HERE";

// this is current user's id
const ownUserId = "CURRENT_USER_ID_HERE";

Step 2

Let's first create a HTTP link. This link will be used to send queries and mutations. Make sure to pass in the API key and the user ID as headers.

import { HttpLink } from "apollo-link-http";

// create HTTP link
const httpLink = new HttpLink({
  uri: GRAPHQL_URI,
  headers: {
    "api-key": apiKey, // send API key as a header
    "own-user-id": ownUserId // send user ID as a header
  }
});

Step 3

Let's create a WebSocket link next. This link starts a WebSocket connection over which subscription queries will be sent. In order to authenticate the WebSocket connection, we send the API key and the optional user ID as connection parameters.

import { SubscriptionClient } from "subscriptions-transport-ws";
import { WebSocketLink } from "apollo-link-ws";

// create WebSocket subscription client
const subscriptionClient = new SubscriptionClient(GRAPQHL_SUBSCRIPTION_URI, {
  connectionParams: {
    "api-key": apiKey, // send API key as a connection param
    "own-user-id": ownUserId // send user ID as a connection param
  }
});

// create WebSocket link
const wsLink = new WebSocketLink(subscriptionClient);
self.ws = websocket.WebSocketApp(endpoint,
                                 subprotocols=['graphql-ws'],
                                 on_open=self._on_open,
                                 on_message=self._on_message,
                                 on_error=self.on_error,
                                 on_close=self.on_close)

def _on_open(self, ws):
    # After websocket connected, Client should send "connection_init" command with api-key and user-id
    req = {
        "type": "connection_init",
        "payload": {
            "api-key": self.api_key,
            'own-user-id': self.user_id,
        }
    }

    def _connection_ok_and_keepalive(id, resp):
        # Server sent the CONNECTION ACK messages after connection established.
        if resp['type'] == "connection_ack":
            # If you receive websocket ack. you can send subscribe request.
            self._subscribe_chat()
            return
        # Server sent the KEEP ALIVE messages every 10 secs.
        elif resp['type'] == "ka":  # Keep alive
            return
        self.on_error(ws, "Unknown response " + str(resp))

    self._request(req, _connection_ok_and_keepalive)

Step 4

Then, we create a new ApolloLink instance that directs subscription queries to the WebSocket link and all other queries to the HTTP link.

import { split } from "apollo-link";
import { getMainDefinition } from "apollo-utilities";

// for subscription operations, use WebSocket link
// for all other operations use HTTP link
const link = split(
  op => {
    const { kind, operation } = getMainDefinition(op.query);
    return operation === "subscription" && kind === "OperationDefinition";
  },
  wsLink,
  httpLink
);

Step 5

For subscription operations, where it is common for a channel to receive multiple events, you can subscribe to an Observable for incoming events.

In this example, we are subscribing to chats subscription when given an ID for a new conversation.

import { execute } from "apollo-link";
import gql from "graphql-tag";

// execute returns an Observable so it can be subscribed to
const subscribeToChats = conversationId =>
  execute(link, {
    query: gql`
      subscription chatsSubscription($where: ChatWhereInput!) {
        chats(where: $where) {
          cursor
          node {
            ... on UserChat {
              id
              message
            }

            ... on BotChat {
              id
              message
            }

            ... on FillSlotRichUXChat {
              id
              message
            }

            ... on AgentChat {
              id
              message
            }
          }
        }
      }
    `,
    variables: {
      where: {
        conversationWhere: {
          id: conversationId
        }
      }
    }
  }).subscribe({
    next(data) {
      console.log("received data", data);
    },
    error(error) {
      console.log("received error", error);
    },
    complete() {
      console.log("complete");
    }
  });
subscribe_chat = {
    "type": "start",
    "payload": {
        "query": """
        subscription getChats($where:ChatWhereInput!) {
          chats(where:$where) {
            node {
              ... on UserChat {
                message createdAt
              }
              ... on AgentChat {
                message
                createdAt
                agent {
                  name
                }
              }
              ... on BotChat {
                message
                createdAt
                chatOptions
              }
              __typename
            }
          }
        }""",
        "variables": {
            "where": {
                "conversationWhere": {
                    "id": self.conversation_id
                }
            }
        }
    }
}
...
self._request(subscribe_chat, _receive_chat)

Step 6

For single execution operations such as queries and mutations, you can use Promise.

In this example, we are sending a startConversation mutation request with placement variable. When the mutation request is successful, it subscribes to the conversation using subscribeToChats function from the previous section.

import { execute, makePromise } from "apollo-link";
import gql from "graphql-tag";

// send placement to start a converation under a campaign that matches placement & targeting
const placement = "PLACEMENT_HERE";

// For single execution operations, a Promise can be used
makePromise(
  execute(link, {
    query: gql`
      mutation startConversationMutation($placement: String!) {
        startConversation(placement: $placement) {
          conversation {
            id

            user {
              id
              ownUserId
            }

            chats {
              edges {
                cursor
                node {
                  ... on UserChat {
                    id
                    message
                  }

                  ... on BotChat {
                    id
                    message
                  }

                  ... on FillSlotRichUXChat {
                    id
                    message
                  }

                  ... on AgentChat {
                    id
                    message
                  }
                }
              }
            }
          }
        }
      }
    `,
    variables: {
      placement
    }
  })
)
  .then(data => {
    console.log("received data", data);

    if (
      data &&
      data.data &&
      data.data.startConversation &&
      data.data.startConversation.conversation
    ) {
      subscribeToChats(data.data.startConversation.conversation.id);
    }
  })
  .catch(error => {
    console.log("received error", error);
  });
# Start Conversation
gql = """
mutation startConversation($v_placement:String!, $v_debug:Boolean) {
  startConversation(placement: $v_placement, debug:$v_debug) {
    conversation {
      id
    } debug
  }
}
"""

variables = {
    'v_placement': "LANDING",
    "v_debug": True
}

result = execute_gql(GRAPHQL_ENDPOINT, gql, variables=variables, headers=headers)
conversation = result['data']['startConversation']['conversation']
if not conversation:
    exit(-1)

conversation_id = conversation['id']

Chat API - Getting conversations list

If you would like to use chat >socket subscription, please read this section.

What is Subscription?

To understand subscription, please read this article.

To test GraphQL Subscription, you need to use Altair Altair

Prerequisite

When you set the subscription in Altair, you need to set the subscription url. You can get the authorization token by logging in. Please read the authorization section above.

Altair subscription

How to use Chat Subscription?

First of all, let's register to the conversations subscription, which will return all the updated conversations by real time. Please put url as https://backend.alli.ai/d/graphql/

subscription s {
  conversations(filter: {}) {
    node {
      id
      createdAt
      modifiedAt
      chats {
        edges {
          node {
            ... on UserChat {
                id
                message
                createdAt
            }
            ... on AgentChat {
                id
                message
                createdAt
                agent {
                    id
                }
            }
            ... on BotChat {
                id
                message
                createdAt
            }
          }
        }
      }
    }
  }
}

The GraphQL code will give you the subscription result in the right pane as follows: Conversations subscription If you have the new conversation, the subscription gives you the updated result by real time.

Integrating Javascript SDK

Getting ready

If you want to have a simple html integration file, please simply put the following code and open it in the browser. You should see Alli pop up at the bottom right of the page. Please turn on the debug, and see the message in a browser console.

For full instruction, follow this Javascript integration guide. In the dashboard, create a campaign without placement or targeting, and create a simple chatflow for the campaign. Go to [onboarding guide]onboarding guide to see details on how to set up a campaign. Make sure to set debug: true and go to your webpage to verify the integration.

Integrating SDK

basic integration

<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<script src="https://unpkg.com/@allganize/sdk"></script>

<body>
<h1>Alli Test</h1>
<script>
<!-- Start of Alli Code -->
    window.Alli.initialize({
        apiKey: "YOUR_API_KEY",
        debug: true
    });
    if (window.Alli) {
    window.Alli.event();
    }
<!-- End of Alli Code -->
</script>

</body>
</html>

Customizing SDK

If you want to customize SDK, please contact support@alli.ai first.

Below are the class names of the elements in Alli: Sdk class name

Making Get external data node

Get external data node is used to interface with customers. Customer should prepare endpoint to receive request from Get external data node.

Requests are HTTP POST. Body contains key-value documents serialized as json that Contains the variable values defined in "Variable to send". For example, if you define @AGE variable at "Variable to send", the request body is {"AGE": 39}.

The return value is also the key-value document of json format. Key defined at "Data to recieve" should be included. If not included, it will branch into "Fail". However, if there are undefined keys, these values are automatically saved if they are defined in the project variable. For example, two variables are defined in the project, FOO and BAR, and @FOO variable is defined in the "Data to response" field in the node. If {"FOO":"foo value"", "BAR":"bar value"} returned, this response contains "FOO". So it is a valid response value. The variables "FOO" and "BAR" store as "foo value" and "bar value".

Example scenarios and examples of set values for Get external data. The endpoints of the customer were assumed to be https://your.domain/alley/report_age. Get external data example

You can use a curl to test input/output before integrating with Alli. (shell) The curl request below is in almost the same format as the request sent by Alli.

$ curl -v -H "Content-Type: application/json" -d '{"AGE":39}' https://your.domain/alli/report_age
*   Trying xxx.xxx.xxx.xxx...
...
> POST /alli/report_age HTTP/2
> Host: your.domain
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 10
>
...
< content-type: application/json
...
<
* Connection #0 to host your.dmain left intact
{"FOO": "foo value", "BAR": "bar value"}

One important thing is that Content-Type should be application/json both when requested and when responding.

The following example is implemented as django (python)

def report_age(request):
    received = json.loads(request.body)
    # make response key-value dict.
    response = { 'FOO' : 'foo_value', 'BAR' : 'var_value' }
    return JsonResponse(fields)

References

Tools & Library

GraphQL is implemented over standard HTTP and websocket. So you can choose any http, websocket library like python requests.