NAV Navbar
C# JavaScript HTTP
  • Introduction
  • Concepts
  • SDK
  • Webhook
  • Authentication
  • Content Types
  • Content Types Samples
  • Extensions
  • Integrations
  • Introduction

    Welcome to BLiP! Here, we'll introduce you to the platform's basics in order to help you build your own chatbot.

    You can create your chatbot in three ways:

    The main goal of this documentation is to provide an overview of BLiP platform and present a lot of samples. For each subject, you'll find code samples on the right side. The samples are presented in C#, JavaScript and as a generic HTTP request that you can use in your favorite programming language.

    In the left side menu, you will find a step-by-step guide for each big subject on BLiP.

    Have some question or advice? Go to BLiP Forum or to BLiP Blog. In case you have any doubts, get in touch with us via BLiP Chat, Messenger, Telegram or Skype and we will help you.

    Concepts

    BLiP allows messaging apps (here also called chatbots, bots, intelligent contacts, or just, contacts) to be built only once and be made available through different messaging channels, such as Messenger, Skype, Workplace, BLiP Chat (a BLiP's channel) and others.

    In order to allow the contact owner to charge for their services, there are integrations with payment channels, such as PagSeguro (a Brazilian payment gateway). It is not necessary for the owner to be a developer if he wants to use these features, since the templates allow him to offer services with only some quick customization.

    For developers, it is possible to choose between using webhooks, the simplest and fastest way to send and receive messages and notifications, or the SDKs that enable them to build contacts in a flexible and scalable way.

    Developers can also use extensions that encapsulate common functionalities used in message applications, such as message broadcasting and scheduling.

    BLiP uses LIME protocol for communication between chatbots and clients and many of the concepts come from the protocol. The envelopes are information containers defined by the protocol and can be messages, notifications or commands, sent in JSON format.

    Addressing

    All the envelopes (messages, notifications and commands) exchanged between chatbots and customers in BLiP have from and to addresses.

    The address is presented in the format name@domain/instance, where:

    Usually, the interaction between a chatbot and a customer starts after the message, which has a from address, is received. In this case, it is only necessary to answer to this address - in an unchanged way, in order to guarantee the message's delivery.

    The addresses may have different life cycles depending on the channels, they can be scoped – valid in some conditions (as in Messenger, where the address is only valid for a specific originator) or persistent, always valid (in SMS and BLiP App). The chatbots must take these characteristics in consideration to build the interactions. For more details, check the LIME protocol specification.

    Channels

    Channels are message nets connected to BLiP in which the chatbots are able to send and receive messages to these nets' customers. Each channel has an identifier used for addressing which is normally a FQDN. This identifier appears after the @ in the nodes address.

    In order to send or receive messages to a channel, the chatbot must be published on it. The publishing is done through the portal, which may request specific information that helps to identify the chatbot in this channel, such as API tokens for example. Usually, previous registration is necessary in each channel, through a specific tool, before publishing.

    Each channel has different capabilities, such as supported message formats or notification events.

    The following channels are available in BLiP platform:

    Name FQDN
    BLiP Chat 0mn.io
    Tangram (SMS) tangram.com.br
    Take.IO (SMS) take.io
    Facebook Messenger messenger.gw.msging.net
    Skype skype.gw.msging.net
    Telegram telegram.gw.msging.net
    Workplace workplace.gw.msging.net
    Email mailgun.gw.msging.net
    PagSeguro pagseguro.gw.msging.net

    For more information about any channel, check the Integrations section.

    Messages

    See below the representation of a message:

      var message = new Message
      {
          Id = "65603604-fe19-479c-c885-3195b196fe8e",
          From = "551199991111@0mn.io/182310923192",
          To = "mycontact@msging.net",
          Content = new PlainText
          {
              Text = "Hello World"
          }
      };
    
    var message = {
      id: "65603604-fe19-479c-c885-3195b196fe8e",
      from: "551199991111@0mn.io/182310923192",
      to: "mycontact@msging.net",
      type: "text/plain",
      content: "Hello World"
    }
    
    {
      "id": "65603604-fe19-479c-c885-3195b196fe8e",
      "from": "551199991111@0mn.io/182310923192",
      "to": "mycontact@msging.net",
      "type": "text/plain",
      "content": "Hello World"
    }
    

    A message allows content exchange between clients and chatbots.

    Each message has:

    For more information, check the LIME protocol specification.

    Sending messages

    In order to send messages and notifications use an instance of `ISender` (on C#), which is automatically injected on constructors of registered `receivers` defined on project and on the `Startup` class.

    //reply a received message sample
    public class PlainTextMessageReceiver : IMessageReceiver
    {
        private readonly ISender _sender;
        private readonly Settings _settings;
    
        public PlainTextMessageReceiver(ISender sender, Settings settings)
        {
            _sender = sender;
            _settings = settings;
        }
    
        public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
        {
            // Write the received message to the console
            Console.WriteLine(message.Content.ToString());
            // Responds to the received message
            _sender.SendMessageAsync("Hi. I just received your message!", message.From, cancellationToken);
        }
    
    }
    

    It's possible send notifications and messages only after sessions has been stablished.

    //send a message after connection has been stablished sample
    client.connect()
        .then(function(session) {
            // After connection is possible send messages
            var msg = { type: 'text/plain', content: 'Hello, world', to: '553199990000@0mn.io' };
            client.sendMessage(msg);
        });
    

    For this sample bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ is a valid Key for blipmessaginghubapp chatbot.

    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Length: 131
    
    {
        "id": "123e4567-e89b-12d3-a456-426655440000",
        "to": "551100001111@0mn.io",
        "type": "text/plain",
        "content": "Hello, how can I help you?"
    }
    

    The process of sending message is asynchronous and the status of sent messages is delivered to application by notifications.

    For more information about messages, check the Messages documentation page or the supported content types specification.

    REQUEST

    Name Description
    id Unique identifier of the message
    from Originator’s address
    to Recipient’s address
    type Statement with content type, in the MIME format
    content Message content

    Receiving messages

    The receipt of messages is done using the interface IMessageReceiver.

    //A `IMessageReceiver` can be defined as follows
    public class PlainTextMessageReceiver : IMessageReceiver
    {
        private readonly ISender _sender;
        private readonly Settings _settings;
    
        public PlainTextMessageReceiver(ISender sender, Settings settings)
        {
            _sender = sender;
            _settings = settings;
        }
    
        public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
        {
            // Write the received message to the console
            Console.WriteLine(message.Content.ToString());
        }
    
    }
    

    All messages sent to the chatbot are redirected to registered receivers of messages. You also can define filters to each receiver.

    //add simple message receiver example
    client.addMessageReceiver(true, (message) => {
      // Process received message
    
    });
    
    //Example of message receiver with filter of originator
    client.addMessageReceiver((message) => { message.from === "553199990000@0mn.io" },
    (message) => {
      // Process received message
    });
    
    //Each registration of receivers return a `handler` that can be used to cancell the registration:
    var removeJsonReceiver = client.addMessageReceiver("application/json", handleJson);
    // ...
    removeJsonReceiver();
    

    All messages will be delivered as a HTTP POST request on configured chatbot messages URL. A sample of received message is presented bellow.

    POST https://your.endpoint/messages HTTP/1.1
    Content-Type: application/json
    
    {
      "id": "99cf454e-f25d-4ebd-831f-e48a1c612cd4",
      "from": "551100001111@0mn.io/4ac58r6e3",
      "to": "blipmessaginghubapp@msging.net",
      "type": "text/plain",
      "content": "Help"
    }
    

    The process of receiving messages is asynchronous. The received messages will be on the format defined on LIME Protocol.

    Notifications

    See below the representation of a received notification from the destination:

    var notification = new Notification
    {
        Id = "65603604-fe19-479c-c885-3195b196fe8e",
        From = "551199991111@0mn.io/182310923192",
        To = "mycontact@msging.net",
        Event = Event.Received
    };
    
    var notification = {
      id: "65603604-fe19-479c-c885-3195b196fe8e",
      from: "551199991111@0mn.io/182310923192",
      to: "mycontact@msging.net",
      event: "received"
    }
    
    POST https://your.endpoint/notifications HTTP/1.1
    Content-Type: application/json
    
    {
      "id": "65603604-fe19-479c-c885-3195b196fe8e",
      "from": "551199991111@0mn.io/182310923192",
      "to": "mycontact@msging.net",
      "event": "received"
    }
    

    And a notification of a server failure:

    var notification = new Notification
    {
        Id = "65603604-fe19-479c-c885-3195b196fe8e",
        From = "551199991111@0mn.io/182310923192",
        To = "mycontact@msging.net",
        Event = Event.Failed,
        Reason = new Reason
        {
            Code = 42,
            Description = "Destination not found"
        }
    };
    
    var notification = {
      id: "65603604-fe19-479c-c885-3195b196fe8e",
      from: "postmaster@msging.net/server1",
      to: "mycontact@msging.net",
      event: "failed",
      reason: {
        code: 42,
        description: "Destination not found"
      }
    }
    
    POST https://your.endpoint/notifications HTTP/1.1
    Content-Type: application/json
    
    {
      "id": "65603604-fe19-479c-c885-3195b196fe8e",
      "from": "postmaster@msging.net/server1",
      "to": "mycontact@msging.net",
      "event": "failed",
      "reason": {
        "code": 42,
        "description": "Destination not found"
      }
    }
    
    
    

    A notification provides information about a sent message.

    Each notification has:

    For more details, check the LIME protocol specification.

    Sending notifications

    We send a notification using a client object with method sendNotification

    client.connect()
        .then((session) => {
            // Sending "received" notification
            var notification = {
                id: 'ef16284d-09b2-4d91-8220-74008f3a5788',
                to: '553199990000@0mn.io',
                event: Lime.NotificationEvent.RECEIVED
            };
            client.sendNotification(notification);
        });
    
    // Using await keyword
    let session = await client.connect();
    let notification = {
        id: 'ef16284d-09b2-4d91-8220-74008f3a5788',
        to: '553199990000@0mn.io',
        event: Lime.NotificationEvent.RECEIVED
    };
    
    client.sendNotification(notification);
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
        private readonly ISender _sender;
        private readonly Settings _settings;
    
        public PlainTextMessageReceiver(ISender sender, Settings settings)
        {
            _sender = sender;
            _settings = settings;
        }
    
        public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
        {
             var notification = new Notification
                {
                    Id = message.Id,
                    To = message.From,
                    Event = Event.Consumed
                };
    
            await _sender.SendNotificationAsync(notification, cancellationToken);
        }
    }
    

    For instance, imagine that the received a message from example above (whit id 99cf454e-f25d-4ebd-831f-e48a1c612cd4

    POST https://msging.net/notifications HTTP/1.1
    Content-Type: application/json
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Length: 131
    
    {
        "id": "99cf454e-f25d-4ebd-831f-e48a1c612cd4",
        "from": "551100001111@0mn.io/4ac58r6e3",
        "event": "consumed"
    }
    

    In order to correctly show the message history, it is important that the chatbots send notifications of messages processed to originator clients.

    For each message processed, a notification must be sent with the consumed event. In case of problems, the chatbot must send a notification with the failed event.

    REQUEST

    Name Description
    id Identifier of the related message
    from Notification originator’s address
    to Notification recipient’s address
    event Event related to the message
    reason In case of failed events, represents the reason of the message failure

    Receiving notifications

    The next sample shows how to add a notification receiver with filter to the `received` event type:

    client.addNotificationReceiver("received", function(notification) {
      // Process received notifications
    });
    
    // Using expression lambda
    client.addNotificationReceiver(() => true, function(message) {
      // Process received notifications
    });
    

    The receipt of notifications is done using the interface INotificationReceiver.

    public class ConsumedNotificationReceiver : INotificationReceiver
    {
        public async Task ReceiveAsync(Notification notification, CancellationToken cancellationToken)
        {
            // Write the received notification to the console
            Console.WriteLine(notification.ToString());
        }
    }
    

    All notifications will be delivered as a HTTP POST request on the configured URL for chatbot notifications.

    POST https://your.endpoint/notifications HTTP/1.1
    Content-Type: application/json
    
    {
      "id": "123e4567-e89b-12d3-a456-426655440000",
      "from": "551100001111@0mn.io/4ac58r6e3",
      "to": "blipmessaginghubapp@msging.net/7a8fr233x",
      "event": "received"
    }
    

    Each notification contains the status of messages. Observe that the notifications are sent by the clients, informing if they received some message or not.

    Commands

    See below the representation of a command for the distribution list creation.

    var command = new Command()
    {
        Id = EnvelopeId.NewId(),
        To = "postmaster@broadcast.msging.net",
        Method = CommandMethod.Set,
        Uri = new LimeUri("/lists"),
        Resource = new JsonDocument(DistributionList.MediaType)
        {
            {"identity", "list@broadcast.msging.net"}
        }
    };
    
    var command = {
      id:  "1",
      to: "postmaster@broadcast.msging.net",
      method: "set",
      uri: "/lists",
      type: "application/vnd.iris.distribution-list+json",
      resource: {
        identity:  "list@broadcast.msging.net"
      }
    } 
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Length: 131
    
    {
      "id":  "1",
      "to": "postmaster@broadcast.msging.net",
      "method": "set",
      "uri": "/lists",
      "type": "application/vnd.iris.distribution-list+json",
      "resource": {
        "identity":  "list@broadcast.msging.net"
      }
    } 
    

    Reponse in the case of a successful answer:

    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@broadcast.msging.net/#hmgirismsging2",
      "to": "my-contact@msging.net/default",
      "method": "set",
      "status": "success"
    } 
    

    In the case of a failure:

    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@broadcast.msging.net/#hmgirismsging2",
      "to": "my-contact@msging.net/default",
      "method": "set",
      "status": "failure",
      "reason": {
       "code": 60,
       "description": "Invalid list identifier"
      }
    } 
    

    A command allows querying and manipulation of server resources and the consumption of BLiP extensions. It provides a request-response interface similar to HTTP, with verbs and URIs.

    Each command has:

    Note: Some extensions cannot accept all of the available methods.

    Besides the properties previously mentioned, a response command may have:

    For more details, check the LIME protocol specification.

    Sending commands

    ISender interface also enables send commands to the server, as the following sample:

    // For this case, the command response is received on a synchronous way.
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
        private readonly ISender _sender;
        private readonly Settings _settings;
    
        public PlainTextMessageReceiver(ISender sender, Settings settings)
        {
            _sender = sender;
            _settings = settings;
        }
    
        public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
        {
            var command = new Command {
                Id = 1,
                Method = CommandMethod.Get,
                Uri = new LimeUri("/account")
            };
    
            var response = await _sender.ProcessCommandAsync(command, cancellationToken);
        }
    }
    
    var pingCommand = {
        id: Lime.Guid(),
        uri: '/ping',
        method: 'get'
    };
    
    messagingHubClient
        .sendCommand(pingCommand)
        .then(function (commandResponse) {
            utils.logLimeCommand(pingCommand, 'Ping sent');
            utils.logLimeCommand(commandResponse, 'Ping response');
        })
        .catch(function (err) {
            utils.logMessage('An error occurred: ' + err);
        });
    
    
    
    POST https://msging.net/commands HTTP/1.1
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Type: application/json
    Content-Length: 393
    
    {  
        "id":"2",
        "to":"postmaster@scheduler.msging.net",
        "method":"set",
        "uri":"/schedules",
        "type":"application/vnd.iris.schedule+json",
        "resource":{  
        "message":{  
            "id":"ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67",
            "to":"553100001111@0mn.io",
            "type":"text/plain",
            "content":"Scheduled Message"
        },
        "when":"2016-07-25T17:50:00.000Z"
        }
    }
    

    In order to use the BLiP's extensions (like schedule and directory), it is necessary to send commands.

    REQUEST

    Name Description
    id Unique command identifier
    from Command originator address
    to Command recipient address
    uri The path at the recipient the command refers to
    method Method for resource manipulation defined at the uri. This value is mandatory
    type Declaration of the resource value type, in the MIME format
    resource JSON resource representation
    status Indicates the command processing result, it is mandatory in the answers
    reason Indicates the command processing failure reason

    Obs: The uri value is mandatory in the requests and can be omitted in the responses. A response command may have status and reason properties.

    Result codes for requests

    Code Description
    202 (Accepted) Envelope was accepted by the server
    400 (Bad Request) Alert to some problem with the format or fields of sent envelope.
    401 (Unauthorized) Alert to some problem or Authorization header missing

    SDK

    C#

    The C# SDK makes easier to build chatbots with BLiP platform. It is based on .NET Core, which allows the creation of multiplatform chatbots.

    You can check the SDK source code in Github and the documentation on our Wiki.

    Javascript

    If you are a Javascript developer and want to create a chatbot with BLiP, you must use the BLiP Javascript SDK. It was developed to help sending and receiving of BLiP messages using Javascript for browsers or node.js through persistent WebSocket connections.

    Go to Github to see the source code and documentation.

    Webhook

    Webhook's chatbot enables integration via HTTP endpoints to exchange messages, notifications and commands.

    1. Send messages

    To send messages, it is necessary to make a HTTP POST request to URL provided on portal (chatbot settings section). The request must contain an authorization header (Authorization) with Key type, as showed on chatbot settings.

    The message data must be sent on the request body. The message must be a JSON on LIME protocol format. For more details go to protocol documentation.

    Example

    Imagine a chatbot with a blipmessaginghubapp identifier. To send a message from this bot to a BLiP user, use:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Length: 131
    
    {
      "id": "123e4567-e89b-12d3-a456-426655440000",
      "to": "551100001111@0mn.io",
      "type": "text/plain",
      "content": "Hello, how can I help you?"
    }
    

    Note: For this sample, bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ is a valid Key for blipmessaginghubapp chatbot.

    For more information about messages, check the Messages documentation page or the supported content types specification.

    1. Receiving notification

    All notifications will be delivered on the configured chatbot's notification URL. Each notification contains the status of messages. Observe that notifications are sent by clients, informing if received or not some message.

    A sample of notification is presented below. This notification will be deliverd as a HTTP POST request on the chatbot notification URL.

    {
      "id": "123e4567-e89b-12d3-a456-426655440000",
      "from": "551100001111@0mn.io/4ac58r6e3",
      "to": "blipmessaginghubapp@msging.net/7a8fr233x",
      "event": "received"
    }
    

    For more information, check the Notification documentation page

    1. Receiving messages

    Similar to notifications, all messages will be delivered as a HTTP POST request on the configured chatbot's messages URL. These messages have a JSON format as defined on LIME PROTOCOL. A sample of a received message is presented below.

    {
      "id": "99cf454e-f25d-4ebd-831f-e48a1c612cd4",
      "from": "551100001111@0mn.io/4ac58r6e3",
      "to": "blipmessaginghubapp@msging.net",
      "type": "text/plain",
      "content": "Help"
    }
    
    1. Sending notifications

    In order to correctly show the message history, it is important that the chatbots send notifications of messages processed to originator clients.

    For each message processed, it is important to send a notification with the consumed event. In case of problems, the chatbot must send a notification with the failed event. The request must contain an authorization header (Authorization) with Key type, as showed on chatbot settings.

    For instance, imagine that the received message from the example above (whit id 99cf454e-f25d-4ebd-831f-e48a1c612cd4) was processed with success. The code bellow shows a complete notification request including the headers and the body request. ``` POST https://msging.net/notifications HTTP/1.1 Content-Type: application/json Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ= Content-Length: 131

    { "id": "99cf454e-f25d-4ebd-831f-e48a1c612cd4", "from": "551100001111@0mn.io/4ac58r6e3", "event": "consumed" } ```

    1. Sending commands

    In order to use BLiP's extensions (like schedule and directory), it is necessary to send commands. To do that, a HTTP POST request on /commands URL must be made.

    For instance, send a command to schedule some message:

    POST https://msging.net/commands HTTP/1.1
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Type: application/json
    Content-Length: 393
    
    {  
      "id":"2",
      "to":"postmaster@scheduler.msging.net",
      "method":"set",
      "uri":"/schedules",
      "type":"application/vnd.iris.schedule+json",
      "resource":{  
        "message":{  
          "id":"ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67",
          "to":"553100001111@0mn.io",
          "type":"text/plain",
          "content":"Scheduled Message"
        },
        "when":"2016-07-25T17:50:00.000Z"
      }
    }
    

    The command response is immediately delivered on HTTP response, as below:

    HTTP/1.1 200 OK
    Content-Type: application/json
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Credentials: true
    Date: Mon, 12 Sep 2016 17:35:02 GMT
    Content-Length: 131
    
    {  
      "id":"2",
      "from":"postmaster@scheduler.msging.net/#irismsging1",
      "to":"blipmessaginghubapp@msging.net",
      "method":"set",
      "status":"success"
    }
    
    
    Code Description
    202 (Accepted) Envelope was accepted by the server
    400 (Bad Request) Alert to some problem with format or fields of sent envelope.
    401 (Unauthorized) Alert to some problem or Authorization header missing
    Name Description
    Url to receive messages Endpoint where BLiP will post the messages
    Url to receive notification Endpoint where BLiP will post the notifications

    Authentication

    Imagine a chatbot with an Authorization 'Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ='. To send a message from this bot to a BLiP user, use:

    Note: For this sample, bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ is a valid Key.
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key bWVzc2FnaW5naHViQHRha2VuZXQuY29tLmJyOjEyMzQ=
    Content-Length: 131
    
    {
        "id": "123e4567-e89b-12d3-a456-426655440000",
        "to": "551100001111@0mn.io",
        "type": "text/plain",
        "content": "Hello, how can I help you?"
    }
    

    With `C#`, the authentication of your chatbot is made on application.json file. Basically, this file defines all receivers and other control properties.

    //Check an example of how to set your application.json file:
    {
      "identifier": "xpto",
      "accessKey": "cXkzT1Rp",
      "messageReceivers": [
        {
          "type": "PlainTextMessageReceiver",
          "mediaType": "text/plain"
        }
      ]
    }
    

    In order to instantiate the client, use ClientBuilder class informing the identifier and access key:

    
    // Create a client instance passing the identifier and accessKey of your chatbot 
    var client = new ClientBuilder()
        .withIdentifier(identifier)
        .withAccessKey(accessKey)
        .withTransportFactory(() => new WebSocketTransport())
        .build();
    
    // Register a receiver for messages of 'text/plain' type
    client.addMessageReceiver('text/plain', function(message) {
      // TODO: Proccess the received message
    });
    
    // Register a receiver to any notification
    client.addNotificationReceiver(true, function(notification) {
      // TODO: Proccess the received notification
    });
    
    // Connect with server asynchronously
    // Connection will occurr via websocket on 8081 port.
    client.connect() // This method return a 'promise'.
        .then(function(session) { 
            // Connection success. Now is possible send and receive envelopes from server. */ 
            })  
        .catch(function(err) { /* Connection failed. */ }); 
    
    

    In order to authenticate your chatbot, you need to follow these steps:

    On Webhook, whatever request made (messages/notifications/commands) must contain an authorization header (Authorization) with a Key type, as showed on BLiP Portal chatbot configurations.

    On both C# and Javascript, you will need to check credentials on BLiP Portal, inside chatbot configuration menu, and find your identifier and access key. Then, you need to insert them in a specific place.

    See the examples at code sidebar.

    Content Types

    If you want to see all content-types working, clone our SDK sample project:
    github.com/takenet/blip-sdk-csharp/tree/master/src/Samples/MessageTypes
    

    BLiP uses message content types defined by LIME protocol and performs the conversion of these types to the most adequate format for each destination channel. For more details, check the LIME protocol content types specification.

    Besides that, it's possible to send native contents to some channels - like Messenger -, which allows the usage of the channel capabilities without restrictions. See more details on Native contents item on the left menu.

    Metadata

    Messages received from some channels may have unique metadata information coming from the channel. This information is included in the metadata property of the BLiP messages.

    An example of a message received from Messenger:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    {
      "id": "9dc08447-8b23-4bc2-8673-664dca202ee2",
      "from": "128271320123982@messenger.gw.msging.net",
      "to": "mybot@msging.net",
      "type": "text/plain",
      "content": "Hello",
      "metadata": {
          "messenger.mdi": "mid.$cAAAu_n30PEFiJQdYSlb8785KMO5E",
          "messenger.seq": "19062"
      }
    }
    

    The properties messenger.mdi and messenger.seq are specific to Messenger, but they are delivered together with incoming messages. In Messenger specifically, several different metadata properties can be delivered, one of the most important being the messenger.ref, which is the referral generated when a client clicks on a m.me/bot-name?ref=value link from your chatbot or when it scans a code for the bot.

    HTTP/1.1 200 OK
    Content-Type: application/json
    {
      "id": "2dc05467-4b23-1bc2-8673-664dca202ee2",
      "from": "128271320123982@messenger.gw.msging.net",
      "to": "mybot@msging.net",
      "type": "text/plain",
      "content": "Get started",
      "metadata": {
          "messenger.ref": "website",
          "messenger.source": "SHORTLINK",
          "messenger.type": "OPEN_THREAD"
      }
    }
    

    Plain Text

    MIME type
    text/plain

    Allows sending and receiving simple text messages.

    Sending a message to a Messenger recipient:

        client.sendMessage({
            id: Lime.Guid(),
            type: "text/plain",
            to: "128271320123982@messenger.gw.msging.net",
            content: "Welcome to our service! How can I help you?"
            });
    
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    //Replying a received message with a simple text message.
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new PlainText {Text = "Welcome to our service! How can I help you?"};
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "128271320123982@messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Welcome to our service! How can I help you?"
    }
    

    For more details, check the specification of LIME protocol.

    Channel mapping

    Channel Type
    BLiP Chat Text
    Messenger Text message
    SMS Text
    Skype Activity
    Telegram Message

    Sending the link of an image including title, descriptive text and metadata:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var imageUri = new Uri("http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg", UriKind.Absolute);
        var previewUri = new Uri("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX", UriKind.Absolute);
    
        var document = new MediaLink
        {
            Title = "Cat",
            Text = "Here is a cat image for you!",
            Type = MediaType.Parse("image/jpeg"),
            AspectRatio = "1:1",
            Size = 227791,
            Uri = imageUri,
            PreviewUri = previewUri
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "title": "Cat",
            "text": "Here is a cat image for you!",
            "type": "image/jpeg",
            "uri": "http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg",
            "aspectRatio": "1:1",
            "size": 227791,
            "previewUri": "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX",
            "previewType": "image/jpeg"
        }
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.media-link+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            title: "Cat",
            text: "Here is a cat image for you!",
            type: "image/jpeg",
            uri: "http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg",
            aspectRatio: "1:1",
            size: 227791,
            previewUri: "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX",
            previewType: "image/jpeg"
          }
        });
    

    Sending an audio link: (For more details, check the LIME protocol specification)

    var audioMediaLink = new MediaLink
    {
        Title = "Audio",
        Type = MediaType.Parse("audio/mp3"),
        Uri = new Uri("http://blaamandagjazzband.dk/jazz/mp3/basin_street_blues.mp3"),
        Size = 3124123,
        AspectRatio = "1:1"
    };
    
    await _sender.SendMessageAsync(audioMediaLink, message.From, cancellationToken);
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "type": "audio/mp3",
            "uri": "http://blaamandagjazzband.dk/jazz/mp3/basin_street_blues.mp3",
            "size": 3124123
        }
    }
    
    MIME type
    application/vnd.lime.media-link+json

    Allows sending and receiving of links for multimedia content. The link can be any valid URI, but most part of the channels only support content served by HTTP/HTTPS protocol. It is possible to include a title and a text, besides image metadada such as MIME type, size and preview.

    Some channels allow defining the display's aspect ratio for certain media types. For instance, in Messenger, you should set the 1:1 value for the aspectRatio property to send squared images.

        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.media-link+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            type: "audio/mp3",
            uri: "http://blaamandagjazzband.dk/jazz/mp3/basin_street_blues.mp3",
            size: 3124123
          }
        });
    

    For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type
    BLiP Chat Media Link
    Messenger Attachments (image/audio/video/file, depending of MIME type)
    SMS Text with link
    Skype Activity
    Telegram Message

    Chat state

    Sending status typing to bot user:

    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
    public class OptionChatStateMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionChatStateMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var chatState = new ChatState
        {
            State = ChatStateEvent.Composing
        };
        await _sender.SendMessageAsync(chatState, message.From, cancellationToken);
    }
    
    }
    }
    
    client.sendMessage({
            id: Lime.Guid(),
            to:"104222@telegram.gw.msging.net",
            type:"application/vnd.lime.chatstate+json",
            content: {
                "state": "composing"
            }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "to":"104222@telegram.gw.msging.net",
        "type":"application/vnd.lime.chatstate+json",
        "content": {
            "state": "composing"
        }
    }
    
    MIME type
    application/vnd.lime.chatstate+json

    Allows sending and receiving information about the conversation's current status. Possible status are:

    State Description
    starting Initiating new conversation
    composing Typing/preparing a message
    paused New message typing interrupted, message not sent
    deleting Deleting message (which was being prepared)
    gone Exit/Conversation finished

    In general, there is no need to receive delivery notifications messages with this content, thus it is recommended to omit the Id in these messages. For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type Supported states
    BLiP Chat Chat State All
    Messenger Sender Actions and Referral composing and paused (sending only) and starting (referral of an existing thread)
    SMS - None
    Skype - None
    Telegram SendChatAction composing (sending only)

    Location

    Sending a location with latitude, longitude and altitude:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    //A chatbot can send and receive a location entity. For those cases, use Location type:
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new Location
        {
            Latitude = -19.918899,
            Longitude = -43.959275,
            Altitude = 853,
            Text = "Take's place"
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.location+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            latitude: -19.918899,
            longitude: -43.959275,
            altitude: 853,
            text: "Take's place"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.location+json",
        "content": {
            "latitude": -19.918899,
            "longitude": -43.959275,
            "altitude": 853,
            "text": "Take's place"
        }
    }
    

    Request location

        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.input+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            label: {
              type: "text/plain",
              value: "Send your location please!"
            },
            validation: {
              rule: "type",
              type: "application/vnd.lime.location+json"
            }
          }
        });
    
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class RequestLocation : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public RequestLocation(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var location = new Input
        {
            Label = new DocumentContainer{
                Value = new PlainText
                {
                    Text = "Send your location please!"
                }
            },
            Validation = new InputValidation{
                Rule = InputValidationRule.Type,
                Type = Location.MediaType
            }
        };
    
    await _sender.SendMessageAsync(location, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "1334448323284655@messenger.gw.msging.net",
        "type": "application/vnd.lime.input+json",
        "content": {
            "label": {
              "type": "text/plain",
              "value": "Send your location please!"
            },
            "validation": {
              "rule": "type",
              "type": "application/vnd.lime.location+json"
            }
        }
    }
    
    MIME type
    application/vnd.lime.location+json

    Allows sending and receiving of geographic information.

    For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type
    BLiP Chat Location
    Messenger Generic template
    SMS Text with link
    Skype Activity
    Telegram Location

    Asks the user for her location

    Multimedia menu

    Menu with image in the header and a link and text as options:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class OptionMultimidiaMenuMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionMultimidiaMenuMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    DocumentSelectOption[] options = new DocumentSelectOption[]
    {
        new DocumentSelectOption
        {
            Label = new DocumentContainer
            {
                Value = new WebLink
                {
                    Text = "Go to your site",
                    Uri = new Uri("https://meusanimais.com.br/14-nomes-criativos-para-o-seu-gato/")
                }
            }
        },
        new DocumentSelectOption
        {
            Label = new DocumentContainer
            {
                Value = new PlainText
                {
                    Text = "Show stock here!"
                }
            },
            Value = new DocumentContainer
            {
                Value = new JsonDocument()
            }
        }
    };
    
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new DocumentSelect
            {
                Header = new DocumentContainer
                {
                    Value = new MediaLink
                    {
                        Title = "Welcome to mad hatter",
                        Text = "Here we have the best hats for your head.",
                        Type = "image/jpeg",
                        Uri = new Uri("http://i.overboard.com.br/imagens/produtos/0741720126/Ampliada/chapeu-new-era-bucket-print-vibe.jpg"),
                        AspectRatio = "1.1"
                    }
                },
                Options = options
            };
    
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.document-select+json",
        "content": {
            "header": {
                "type": "application/vnd.lime.media-link+json",
                "value": {
                    "title": "Welcome to mad hatter",
                    "text": "Here we have the best hats for your head.",
                    "type": "image/jpeg",
                    "uri": "http://petersapparel.parseapp.com/img/item100-thumb.png",
                    "aspectRatio": "1:1"
                }
            },
            "options": [
                {
                    "label": {
                        "type": "application/vnd.lime.web-link+json",
                        "value": {
                            "text": "Go to our site",
                            "uri": "https://petersapparel.parseapp.com/view_item?item_id=100"
                        }
                    }
                },
                {
                    "label": {
                        "type": "text/plain",
                        "value": "Show stock"
                    },
                    "value": {
                        "type": "application/json",
                        "value": {
                            "action": "show-items"
                        }
                    }
                }
            ]
        }
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.document-select+json",
          to: "1042221589186385@messenger.gw.msging.net",
          content: {
                header: {
                    type: "application/vnd.lime.media-link+json",
                    value: {
                        title: "Welcome to mad hatter",
                        text: "Here we have the best hats for your head.",
                        type: "image/jpeg",
                        uri: "http://petersapparel.parseapp.com/img/item100-thumb.png",
                        aspectRatio: "1:1"
                    }
                },
                options: [
                    {
                        label: {
                            type: "application/vnd.lime.web-link+json",
                            value: {
                                text: "Go to our site",
                                uri: "https://petersapparel.parseapp.com/view_item?item_id=100"
                            }
                        }
                    },
                    {
                        label: {
                            type: "text/plain",
                            value: "Show stock"
                        },
                        value: {
                            type: "application/json",
                            value: {
                                action: "show-items"
                            }
                        }
                    }
                ]
            }
        });
    

    Getting the location of a Messenger user:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class MenuMultimidiaGetLocation : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public MenuMultimidiaGetLocation(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new DocumentSelect
            {
                Header = new DocumentContainer
                {
                    Value = new PlainText
                    {
                        Text = "Please, share your location"
                    }
                },
                Options = new DocumentSelectOption[]{
                    new DocumentSelectOption {
                        Label = new DocumentContainer{
                            Value = new Input {
                                Label = new DocumentContainer {
                                    Value = new PlainText {
                                        Text = "Press Button"
                                    }
                                },
                                Validation = new InputValidation
                                {
                                    Type = Location.MediaType,
                                    Rule = InputValidationRule.Type
                                }
                            }
                        }
                    }
                }
            };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.document-select+json",
        "content": {
            "scope": "immediate",
            "header": {
                "type": "text/plain",
                "value": "Please, share your location"
            },
            "options": [
                {
                    "label": {
                        "type": "application/vnd.lime.input+json",
                        "value": {
                            "validation": {
                              "rule": "type",
                              "type": "application/vnd.lime.location+json"
                            }
                        }
                    }
                }
            ]
        }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.document-select+json",
          to: "1042221589186385@messenger.gw.msging.net",
          content: {
                scope: "immediate",
                header: {
                    type: "text/plain",
                    value: "Please, share your location"
                },
                options: [
                    {
                        label: {
                            type: "application/vnd.lime.input+json",
                            value: {
                                validation: {
                                    rule: "type",
                                    type: "application/vnd.lime.location+json"
                                }
                            }
                        }
                    }
                ]
            }
        });
    
    MIME type
    application/vnd.lime.document-select+json

    Allows sending an options menu to customers where the header and options can be of any content type, such as media link or web link, and not only text - like in the Select type. For each option, it is possible to define a document that is delivered to the contact when the customer performs a choice (depending on the channel support).

    For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type
    BLiP Chat Document select
    Messenger Generic template
    SMS Text
    Skype Activity
    Telegram Message

    Collection

    A text Collection

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class OptionDocumentCollectionMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionDocumentCollectionMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    PlainText[] documents = new PlainText[]
    {
        new PlainText
        {
            Text = "Text 1"
        },
        new PlainText
        {
            Text = "Text 2"
        },
        new PlainText
        {
            Text = "Text 3"
        }
    };
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new DocumentCollection
        {
            ItemType = "text/plain",
            Items = documents
        };
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
        client.sendMessage({
            id: Lime.Guid(),
            type: "application/vnd.lime.collection+json",
            to: "128271320123982@messenger.gw.msging.net",
            content: {
                itemType: "text/plain",
                items: [
                    "Text 1",
                    "Text 2",
                    "Text 3"
                ]
            }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "to": "553199990000@0mn.io",
        "type": "application/vnd.lime.collection+json",
        "content": {
            "itemType": "text/plain",
            "items": [
                "Text 1",
                "Text 2",
                "Text 3"
            ]
        }
    }
    

    A different type of collection, using container

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class CollectionWithDiferentTypes : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public CollectionWithDiferentTypes(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    DocumentContainer[] documents = new DocumentContainer[]
    {
        new DocumentContainer{
            Value = new MediaLink
            {
                Uri = new Uri("http://www.petshoplovers.com/wp-content/uploads/2014/03/CUIDADOS-B%C3%81SICOS-PARA-CRIAR-COELHOS.jpg"),
                Text = "Welcome to our store!",
                Type = "image/jpeg"
            }
        },
        new DocumentContainer{
            Value = new Select
            {
                Text = "Choose what you need",
                Options = new SelectOption[]
                {
                    new SelectOption
                    {
                        Order = 1,
                        Text = "See our stock"
                    },
                    new SelectOption
                    {
                        Order = 2,
                        Text = "Follow an order"
                    }
                }
    
            }
        }
    };
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new DocumentCollection
        {
            ItemType = "application/vnd.lime.container+json",
            Items = documents
        };
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
        id: Lime.Guid(),
        type: "application/vnd.lime.collection+json",
        to: "128271320123982@messenger.gw.msging.net",
        content: {
            itemType: "application/vnd.lime.container+json",
            items: [
                {
                    type: "application/vnd.lime.media-link+json",
                    value: {
                        text: "Welcome to our store!",
                        type: "image/jpeg",
                        uri: "http://www.petshoplovers.com/wp-content/uploads/2014/03/CUIDADOS-B%C3%81SICOS-PARA-CRIAR-COELHOS.jpg"
                    }
                },
                {
                    type: "application/vnd.lime.select+json",
                    value: {
                        text: "Choose what you need",
                        options: [
                            {
                                order: 1,
                                text: "See our stock"
                            },
                            {
                                order: 2,
                                text: "Follow an order"
                            }
                        ]
                    }
                }
            ]
        }
    });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "to": "553199990000@0mn.io",
        "type": "application/vnd.lime.collection+json",
        "content": {
            "itemType": "application/vnd.lime.container+json",
            "items": [
                {
                    "type": "application/vnd.lime.media-link+json",
                    "value": {
                        "text": "Welcome to our store!",
                        "type": "image/jpeg",
                        "uri": "http://www.petshoplovers.com/wp-content/uploads/2014/03/CUIDADOS-B%C3%81SICOS-PARA-CRIAR-COELHOS.jpg"
                    }
                },
                {
                    "type": "application/vnd.lime.select+json",
                    "value": {
                        "text": "Choose what you need",
                        "options": [
                            {
                                "order": 1,
                                "text": "See our stock"
                            },
                            {
                                "order": 2,
                                "text": "Follow an order"
                            }
                        ]
                    }
                }
            ]
        }
    }
    
    

    A multimedia menu collection

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class CollectionMultimidiaMenu : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    JsonDocument jsonDocuments;
    JsonDocument jsonDocuments2;
    JsonDocument jsonDocuments3;
    
    public CollectionMultimidiaMenu(ISender sender)
    {
        _sender = sender;
    }
    
    DocumentSelect[] documents = new DocumentSelect[]
    {
        jsonDocuments = new JsonDocument();
        jsonDocuments2 = new JsonDocument();
        jsonDocuments3 = new JsonDocument();
    
        jsonDocuments.Add("Key1", "value1");
        jsonDocuments.Add("Key2", "2");
    
        jsonDocuments2.Add("Key3", "value3");
        jsonDocuments2.Add("Key4", "4");
    
        jsonDocuments3.Add("Key5", "value5");
        jsonDocuments3.Add("Key6", "6");
    
        DocumentSelect[] documents = new DocumentSelect[]
        {
            new DocumentSelect
            {
                Header = new DocumentContainer
                {
                    Value = new MediaLink
                    {
                        Title = "Title",
                        Text = "This is a first item",
                        Type = "image/jpeg",
                        Uri = new Uri("http://www.isharearena.com/wp-content/uploads/2012/12/wallpaper-281049.jpg"),
                    }
                },
                Options = new DocumentSelectOption[]
                {
                    new DocumentSelectOption
                    {
                        Label = new DocumentContainer
                        {
                            Value = new WebLink
                            {
                                Title = "Link",
                                Uri = new Uri("http://www.adoteumgatinho.org.br/")
                            }
                        }
                    },
                    new DocumentSelectOption
                    {
                        Label = new DocumentContainer
                        {
                            Value = new PlainText
                            {
                                Text = "Text 1"
                            }
                        },
                        Value = new DocumentContainer
                        {
                            Value = jsonDocuments
                        }
                    }
                }
            },
            new DocumentSelect
            {
                Header = new DocumentContainer
                {
                    Value = new MediaLink
                    {
                        Title = "Title 2",
                        Text = "This is another item",
                        Type = "image/jpeg",
                        Uri = new Uri("http://www.freedigitalphotos.net/images/img/homepage/87357.jpg")
                    }
                },
                Options = new DocumentSelectOption[]
                {
                    new DocumentSelectOption
                    {
                        Label = new DocumentContainer
                        {
                            Value = new WebLink
                            {
                                Title = "Second link",
                                Text = "Weblink",
                                Uri = new Uri("https://pt.dreamstime.com/foto-de-stock-brinquedo-pl%C3%A1stico-amarelo-do-pato-image44982058")
                            }
                        }
                    },
                    new DocumentSelectOption
                    {
                        Label = new DocumentContainer
                        {
                            Value = new PlainText {
                                Text = "Second text"
                            }
                        },
                        Value = new DocumentContainer
                        {
                            Value = jsonDocuments2
                        }
                    },
                    new DocumentSelectOption
                    {
                        Label = new DocumentContainer
                        {
                            Value = new PlainText {
                                Text = "More one text"
                            }
                        },
                        Value = new DocumentContainer
                        {
                            Value = jsonDocuments3
                        }
                    }
                }
            }
        };
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new DocumentCollection
        {
            ItemType = "application/vnd.lime.document-select+json",
            Items = documents,
        };
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
        client.sendMessage({
            id: Lime.Guid(),
            type: "application/vnd.lime.collection+json",
            to: "128271320123982@messenger.gw.msging.net",
            content: {
                itemType: "application/vnd.lime.document-select+json",
                items: [
                    {
                        header: {
                            type: "application/vnd.lime.media-link+json",
                            value: {
                                title: "Title",
                                text: "This is a first item",
                                type: "image/jpeg",
                                uri: "http://www.isharearena.com/wp-content/uploads/2012/12/wallpaper-281049.jpg"
                            }
                        },
                        options: [
                            {
                                label: {
                                    type: "application/vnd.lime.web-link+json",
                                    value: {
                                        title: "Link",
                                        uri: "http://www.adoteumgatinho.org.br/"
                                    }
                                }
                            },
                            {
                                label: {
                                    type: "text/plain",
                                    value: "Text 1"
                                },
                                value: {
                                    type: "application/json",
                                    value: {
                                        key1: "value1",
                                        key2: 2
                                    }
                                }
                            }
                        ]
                    },
                    {
                        header: {
                            type: "application/vnd.lime.media-link+json",
                            value: {
                                title: "Title 2",
                                text: "This is another item",
                                type: "image/jpeg",
                                uri: "http://www.freedigitalphotos.net/images/img/homepage/87357.jpg"
                            }
                        },
                        options: [
                            {
                                label: {
                                    type: "application/vnd.lime.web-link+json",
                                    value: {
                                        title: "Second link",
                                        text: "Weblink",
                                        uri: "https://pt.dreamstime.com/foto-de-stock-brinquedo-pl%C3%A1stico-amarelo-do-pato-image44982058"
                                    }
                                }
                            },
                            {
                                label: {
                                    type: "text/plain",
                                    value: "Second text"
                                },
                                value: {
                                    type: "application/json",
                                    value: {
                                        key3: "value3",
                                        key4: 4
                                    }
                                }
                            },
                            {
                                label: {
                                    type: "text/plain",
                                    value: "More one text"
                                },
                                value: {
                                    type: "application/json",
                                    value: {
                                        key5: "value5",
                                        key6: 6
                                    }
                                }
                            }
                        ]
                    }
                ]
            }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "5",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.collection+json",
        "content": {
            "itemType": "application/vnd.lime.document-select+json",
            "items": [
                {
                    "header": {
                        "type": "application/vnd.lime.media-link+json",
                        "value": {
                            "title": "Title",
                            "text": "This is a first item",
                            "type": "image/jpeg",
                            "uri": "http://www.isharearena.com/wp-content/uploads/2012/12/wallpaper-281049.jpg"
                        }
                    },
                    "options": [
                        {
                            "label": {
                                "type": "application/vnd.lime.web-link+json",
                                "value": {
                                    "title": "Link",
                                    "uri": "http://www.adoteumgatinho.org.br"
                                }
                            }
                        },
                        {
                            "label": {
                                "type": "text/plain",
                                "value": "Text 1"
                            },
                            "value": {
                                "type": "application/json",
                                "value": {
                                    "key1": "value1",
                                    "key2": 2
                                }
                            }
                        }
                    ]
                },
                {
                    "header": {
                        "type": "application/vnd.lime.media-link+json",
                        "value": {
                            "title": "Title 2",
                            "text": "This is another item",
                            "type": "image/jpeg",
                            "uri": "http://www.freedigitalphotos.net/images/img/homepage/87357.jpg"
                        }
                    },
                    "options": [
                        {
                            "label": {
                                "type": "application/vnd.lime.web-link+json",
                                "value": {
                                    "title": "Second link",
                                    "text": "Weblink",
                                    "uri": "https://pt.dreamstime.com/foto-de-stock-brinquedo-pl%C3%A1stico-amarelo-do-pato-image44982058"
                                }
                            }
                        },
                        {
                            "label": {
                                "type": "text/plain",
                                "value": "Second text"
                            },
                            "value": {
                                "type": "application/json",
                                "value": {
                                    "key3": "value3",
                                    "key4": 4
                                }
                            }
                        },
                        {
                            "label": {
                                "type": "text/plain",
                                "value": "More one text"
                            },
                            "value": {
                                "type": "application/json",
                                "value": {
                                    "key5": "value5",
                                    "key6": 6
                                }
                            }
                        }
                    ]
                }
            ]
        }
    }
    
    MIME type C#
    application/vnd.lime.collection+json Lime.Protocol.DocumentCollection

    Allows sending multiple contents of the same type in a single message. Some channels support this type of aggregation with special layouts (for example, in Facebook Messenger a multimedia menu collection is displayed as a carousel). In other channels, multiple messages are sent instead.

    Note: It is possible to send different content types using a collection of the container type.

    For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type
    BLiP Chat Collection
    Messenger Multiple messages / Generic template (if is a multimedia menu collection)
    SMS Text (multiple lines)
    Skype Activity (multiple lines)
    Telegram Message (multiple lines)

    List

    Sending a list with a weblink header to a Messenger user:

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
    public class OptionListMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionListMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new DocumentList
        {
            Header = new DocumentContainer
            {
                Value = new WebLink
                {
                    Title = "Classic T-Shirt Collection",
                    Text = "See all our colors",
                    PreviewUri = new Uri("http://streetwearvilla.com/image/cache/data/Products/Supreme/T-shirt/supreme-box-logo-t-shirt-collection-600x600.png"),
                    Uri = new Uri("http://streetwearvilla.com/supreme-box-logo-t-shirt-white"),
                    Target = WebLinkTarget.SelfTall
                }
            },
            Items = new DocumentContainer[]{
                new DocumentContainer
                {
                    Value = new WebLink
                    {
                        Title = "Classic White T-Shirt",
                        Text = "100% Cotton, 200% Comfortable",
                        PreviewUri = new Uri("http://www.plainwhitetshirt.co.uk/image/cache/catalog/images/GD010vwhiteteegildan-750x750.jpg"),
                        Uri = new Uri("http://www.plainwhitetshirt.co.uk/gildan-soft-style-white-vneck-tshirt"),
                        Target = WebLinkTarget.SelfTall
                    }
                },
                new DocumentContainer
                {
                    Value = new WebLink
                    {
                        Title = "Classic Blue T-Shirt",
                        Text = "100% Cotton, 200% Comfortable",
                        PreviewUri = new Uri("https://cdn.shopify.com/s/files/1/1475/5420/products/Classic_Blue_Front_12068_1024x1024.jpg?"),
                        Uri = new Uri("https://www.theringboxingclubshop.com/products/ring-classic-blue-t-shirt"),
                        Target = WebLinkTarget.SelfTall
    
                    }
                },
                new DocumentContainer
                {
                    Value = new WebLink
                    {
                        Title = "Classic Black T-Shirt",
                        Text = "100% Cotton, 200% Comfortable",
                        PreviewUri = new Uri("http://www.lvnlifestyle.com/wp-content/uploads/2014/08/mens.black_.tshirt.jpg"),
                        Uri = new Uri("http://www.lvnlifestyle.com/product/black-mens-bamboo-organic-cotton-classic-t-shirt/"),
                        Target = WebLinkTarget.SelfTall
                    }
                }
            }
        };
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    
    }
    }
    
    
    client.sendMessage({
        id: Lime.Guid(),
        type: "application/vnd.lime.list+json",
        to: "123129898129832@msging.gw.msging.net",
        content: {
          header:{
              type: "application/vnd.lime.web-link+json",
              value: {
                  title: "Classic T-Shirt Collection",
                  text: "See all our colors",
                  previewUri: "http://streetwearvilla.com/image/cache/data/Products/Supreme/T-shirt/supreme-box-logo-t-shirt-collection-600x600.png",
                  uri: "http://streetwearvilla.com/supreme-box-logo-t-shirt-white",
                  target: "selfTall"
              }
          },
          items:[
              {
                  type: "application/vnd.lime.web-link+json",
                  value:{
                      title: "Classic White T-Shirt",
                      text: "100% Cotton, 200% Comfortable",
                      previewUri: "http://www.plainwhitetshirt.co.uk/image/cache/catalog/images/GD010vwhiteteegildan-750x750.jpg",
                      uri: "http://www.plainwhitetshirt.co.uk/gildan-soft-style-white-vneck-tshirt",
                      target: "selfTall"
                  }
              },
              {
                  type: "application/vnd.lime.web-link+json",
                  value:{
                      title: "Classic Blue T-Shirt",
                      text: "100% Cotton, 200% Comfortable",
                      previewUri: "https://cdn.shopify.com/s/files/1/1475/5420/products/Classic_Blue_Front_12068_1024x1024.jpg?",
                      uri: "https://www.theringboxingclubshop.com/products/ring-classic-blue-t-shirt",
                      target: "selfTall"
                  }
              },
              {
                  type: "application/vnd.lime.web-link+json",
                  value:{
                      title: "Classic Black T-Shirt",
                      text: "100% Cotton, 200% Comfortable",
                      previewUri: "http://www.lvnlifestyle.com/wp-content/uploads/2014/08/mens.black_.tshirt.jpg",
                      uri: "http://www.lvnlifestyle.com/product/black-mens-bamboo-organic-cotton-classic-t-shirt/",
                      target: "selfTall"
                  }
              }
          ]
        }
      });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"1",
      "to":"123129898129832@msging.gw.msging.net",
      "type":"application/vnd.lime.list+json",
      "content":{
        "header":{
          "type":"application/vnd.lime.web-link+json",
          "value":{
            "title":"Classic T-Shirt Collection",
            "text":"See all our colors",
            "previewUri":"http://streetwearvilla.com/image/cache/data/Products/Supreme/T-shirt/supreme-box-logo-t-shirt-collection-600x600.png",
            "uri":"http://streetwearvilla.com/supreme-box-logo-t-shirt-whitemessengerExtensions=true",
            "target":"selfTall"
          }
        },
        "items":[
          {
            "type":"application/vnd.lime.web-link+json",
            "value":{
              "title":"Classic White T-Shirt",
              "text":"100% Cotton, 200% Comfortable",
              "previewUri":"http://www.plainwhitetshirt.co.uk/image/cache/catalog/images/GD010vwhiteteegildan-750x750.jpg",
              "uri":"http://www.plainwhitetshirt.co.uk/gildan-soft-style-white-vneck-tshirt&messengerExtensions=true",
              "target":"selfTall"
            }
          },
          {
            "type":"application/vnd.lime.web-link+json",
            "value":{
              "title":"Classic Blue T-Shirt",
              "text":"100% Cotton, 200% Comfortable",
              "previewUri":"https://cdn.shopify.com/s/files/1/1475/5420/products/Classic_Blue_Front_12068_1024x1024.jpg?",
              "uri":"https://www.theringboxingclubshop.com/products/ring-classic-blue-t-shirt&messengerExtensions=true",
              "target":"selfTall"
            }
          },
          {
            "type":"application/vnd.lime.web-link+json",
            "value":{
              "title":"Classic Black T-Shirt",
              "text":"100% Cotton, 200% Comfortable",
              "previewUri":"http://www.lvnlifestyle.com/wp-content/uploads/2014/08/mens.black_.tshirt.jpg",
              "uri":"http://www.lvnlifestyle.com/product/black-mens-bamboo-organic-cotton-classic-t-shirt/&messengerExtensions=true",
              "target":"selfTall"
            }
          }
        ]
      }
    }
    
    MIME type
    application/vnd.lime.list+json

    Allows sending of a list of different documents on a single message. It's also possible to define a document as a list header.

    Channel support

    Channel Type
    BLiP Chat Not supported yet
    Messenger List template
    SMS Text
    Skype Activity
    Telegram Message

    Select

    Creating a menu with 3 options

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    //Send an options list to give your client the choice between multiple answers using Select type:
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        jsonDocuments = new JsonDocument();
        jsonDocuments.Add("Key1", "value1");
        jsonDocuments.Add("Key2", "2");
    
        var document = new Select
        {
            //Scope = SelectScope.Immediate, (create a quickreply instead menu)
            Text = "Choose an option:",
            Options = new SelectOption[]
            {
                new SelectOption
                {
                    Order = 1,
                    Text = "First option!",
                    Value = new PlainText { Text = "1" }
                },
                new SelectOption
                {
                    Order = 2,
                    Text = "Second option",
                    Value = new PlainText { Text = "2" }
                },
                new SelectOption
                {
                    Order = 3,
                    Text = "Third option",
                    Value = jsonDocuments
                }
            }
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    
    }
    Note:
    
    //NOTE:
    //Value field is optional. If informed, your value will be sent to the chatbot when the user chooses the option.
    //If Value field is not provided, one of the following fields must be provided: Order or Text. The Order field will be used only if Value and Text is not provided.
    //
    //Limitations:
    //Facebook Messenger: Limit of 3 options. Otherwise, your message will not be delivered.
    //If sending more than 3 options is necessary, divide them into multiple messages.
    //Tangram SMS: The Value field will be ignored. Only the Order field will be sent if the option be selected.
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.select+json",
          to: "1042221589186385@messenger.gw.msging.net",
          content: {
            text: "Choose an option",
            options: [
                {
                    text: "First option"
                },
                {
                    order: 2,
                    text: "Second option"
                },
                {
                    order: 3,
                    text: "Third option",
                    type: "application/json",
                    value: {
                        key1: "value1",
                        key2: 2
                    }
                }
            ]
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id":"311F87C0-F938-4FF3-991A-7C5AEF7771A5",
        "to":"1042221589186385@messenger.gw.msging.net",
        "type":"application/vnd.lime.select+json",
        "content":{
            "text":"Choose an option",
            "options":[
                {
                    "text":"First option"
                },
                {
                    "order":2,
                    "text":"Second option"
                },
                {
                    "order":3,
                    "text":"Third option",
                    "type":"application/json",
                    "value":{
                        "key1":"value1",
                        "key2":2
                    }
                }
            ]
        }
    }
    
    MIME type
    application/vnd.lime.select+json

    Allows sending of a text menu to customers to make a choice. It is possible to define a document that may be delivered to the chatbot when the customer selects an option - depending on the channel support. The options can also be numbered, if needed.

    Some channels support the options scope limitation, which determines for how much time they are valid for the user selection. For example, in some cases, sent options can only be selected by the customer at that time and must disappear after the choice. In this case, the scope is immediate. In others, the options are valid for the selection at any time, and the scope is persistent.

    For more details, check the LIME protocol specification.

    JSON 1

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "f8cf7a7a-be4f-473a-8516-60d55534b5a6",
        "from": "1042221589186385@messenger.gw.msging.net",
        "to": "blipcontact@msging.net",
        "type": "text/plain",
        "content": "First option"
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.select+json",
          to: "blipcontact@msging.net",
          content: "First option"
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "f8cf7a7a-be4f-473a-8516-60d55534b5a6",
        "from": "1042221589186385@messenger.gw.msging.net",
        "to": "blipcontact@msging.net",
        "type": "text/plain",
        "content": "First option"
    }
    

    JSON 2

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "76CB408D-39E6-4212-8AA1-7435B42A6993",
        "from": "1042221589186385@messenger.gw.msging.net",
        "to": "blipcontact@msging.net",
        "type": "text/plain",
        "content": "Second option"
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.select+json",
          to: "blipcontact@msging.net",
          content: "Second option"
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "76CB408D-39E6-4212-8AA1-7435B42A6993",
        "from": "1042221589186385@messenger.gw.msging.net",
        "to": "blipcontact@msging.net",
        "type": "text/plain",
        "content": "Second option"
    }
    

    JSON 3

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "035E675C-D25B-437D-80BD-057AD6F70671",
        "from": "1042221589186385@messenger.gw.msging.net",
        "to": "blipcontact@msging.net",
        "type": "application/json",
        "content": {
            "key1":"value1",
            "key2":2
        }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.select+json",
          to: "blipcontact@msging.net",
          content: {
                key1: "value1",
                key2: 2
            }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "035E675C-D25B-437D-80BD-057AD6F70671",
        "from": "1042221589186385@messenger.gw.msging.net",
        "to": "blipcontact@msging.net",
        "type": "application/json",
        "content": {
            "key1":"value1",
            "key2":2
        }
    }
    

    When the user selects one option, a message returns according to the rule:

    Return example of the above mentioned menu:

    When selecting the first option: (JSON 1):

    When selecting the second option (JSON 2):

    At last, when selecting the third option (JSON 3):

    The return message type will always be the same as the chosen option. When a value for the field value is not defined, the type will be text/plain.

    Channel mapping

    Channel Type
    BLiP Chat Select
    Messenger Button template (on default scope) e Quick replies (on immediate scope)
    SMS Text
    Skype Activity
    Telegram Message

    Payment receipt

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class InvoiceStatusReceiver : IMessageReceiver
    {
    private readonly IMessagingHubSender _sender;
    
    public InvoiceStatusReceiver(IMessagingHubSender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var invoiceStatus = message.Content as InvoiceStatus;
        switch (invoiceStatus?.Status)
        {
            case InvoiceStatusStatus.Cancelled:
                await _sender.SendMessageAsync("Ok, you don't need pay anything.", message.From, cancellationToken);
                break;
            case InvoiceStatusStatus.Completed:
                await _sender.SendMessageAsync("Thank you for your payment, this is only a test", message.From, cancellationToken);
                var document = new PaymentReceipt
                {
                    Currency = "BLR",
                    Total = 10
                    Items =
                        new[]
                        {
                            new InvoiceItem
                            {
                                Currency = "BRL",
                                Unit = 10,
                                Description = "Item 1",
                                Quantity = 10,
                                Total = 10
                            }
                        },
                };
                await _sender.SendMessageAsync(document, message.From, cancellationToken);
                break;
            case InvoiceStatusStatus.Refunded:
                await _sender.SendMessageAsync("Ok, your payment was refunded by PagSeguro!", message.From, cancellationToken);
                break;
        }
    }
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.payment-receipt+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            paidOn: "2016-08-26T19:03:37.024Z",
            code: "215BF6B5-01EF-4F9A-A944-0BC05FD0F228",
            method: {
                    name: "Credit Card"
            },
            currency: "BRL",
            total: 10.85,
            items: [{
                    quantity: 1.0,
                    unit: 10.85,
                    currency: "BRL",
                    total: 10.85,
                    description: "Item 1"
                }
            ]
        }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.payment-receipt+json",
        "content": {
            "paidOn": "2016-08-26T19:03:37.024Z",
            "code": "215BF6B5-01EF-4F9A-A944-0BC05FD0F228",
            "method": {
                    "name": "Credit Card"
            },
            "currency": "BRL",
            "total": 10.85,
            "items": [{
                    "quantity": 1.0,
                    "unit": 10.85,
                    "currency": "BRL",
                    "total": 10.85,
                    "description": "Item 1"
                }
            ]
        }
    }
    
    MIME type
    application/vnd.lime.payment-receipt+json

    Allows sending of a payment receipt to a customer.

    In order to realize a payment on your chatbot, it is necessary to use the payment channel. For now, only the PagSeguro channel is supported. To request a payment, the chatbot must send a message of type Invoice to the payment channel informing the user address using the format at right bar.

    Example

    Sending a payment receipt to a Messenger user:

    Channel mapping

    Channel Type
    BLiP Chat Not supported yet
    Messenger Receipt template
    SMS Text
    Skype Activity
    Telegram Message

    Sending a message to a Messenger recipient:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    //To send a web page link use the WebLink type:
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var url = new Uri("http://limeprotocol.org/content-types.html#web-link");
        var previewUri =
            new Uri("techbeacon.scdn7.secure.raxcdn.com/sites/default/files/styles/article_hero_image/public/documents-stack-documentation-agile-devops.jpg?itok=cFDq9Y95");
    
        var document = new WebLink
        {
            Text = "Here is a documentation weblink",
    +       Target = WebLinkTarget.Self,
            PreviewUri = previewUri,
            Uri = url
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    
    }
    
    client.sendMessage({s
          id: Lime.Guid(),
          type: "application/vnd.lime.web-link+json",
          to: "1042225583186385@messenger.gw.msging.net",
          content: {
            uri: "http://limeprotocol.org/content-types.html#web-link",
            target: "self",
            text: "Here is a documentation weblink"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042225583186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.web-link+json",
        "content": {
            "uri": "http://limeprotocol.org/content-types.html#web-link",
            "target": "self",
            "text": "Here is a documentation weblink"
        }
    }
    
    MIME type
    application/vnd.lime.web-link+json

    Allows sending of a link for a webpage to the client including metadata, such as link's title, description and a miniature image.

    Sending a message to a Messenger recipient:

    In some channels, it is possible to define how the webpage will be displayed (on the same window, openning a new window or occupying part of the device window) through the target property. For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type
    BLiP Chat Web Link
    Messenger Generic template or Button (if used with the Multimedia Menu).
    SMS Text with link
    Skype Activity
    Telegram Message

    It is also possible in some channels to use special URI schemes to create links with specific behaviors as below:

    Channel URI Scheme Description Example
    Messenger tel Defines a link for the telephone call to the specific number. Mapped to a Call button. tel:+5531999990000
    Messenger share Defines a link to share current message. Mapped to a Share button. share:

    Payment Invoice

    Example - Sending a payment request to a Facebook Messenger user using PagSeguro:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new Invoice
        {
            Currency = "BLR",
            DueTo = DateTime.Now.AddDays(1),
            Total = 10,
            Items =
                new InvoiceItem[]
                {
                    new InvoiceItem
                    {
                        Currency = "BRL",
                        Unit = 10,
                        Description = "Subscription for product: Hit",
                        Quantity = 1,
                        Total = 10
                    }
                },
        };
    
        var toPagseguro = $"{Uri.EscapeDataString(message.From.ToIdentity().ToString())}@pagseguro.gw.msging.net";
    
        await _sender.SendMessageAsync(document, toPagseguro, cancellationToken);
    }
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.invoice+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            created: "2016-08-26T19:03:37.024Z",
            dueTo: "2016-08-27T19:03:37.024Z",
            currency: "BRL",
            total: 10.85,
            items: [
                {
                    quantity: 1.0,
                    unit: 10.85,
                    currency: "BRL",
                    total: 10.85,
                    description:"Subscription for product: Hit"
                }
            ]
        }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385%40messenger.gw.msging.net@pagseguro.gw.msging.net",
        "type": "application/vnd.lime.invoice+json",
        "content": {
            "created":"2016-08-26T19:03:37.024Z",
            "dueTo":"2016-08-27T19:03:37.024Z",
            "currency":"BRL",
            "total":10.85,
            "items":[
                {
                    "quantity":1.0,
                    "unit":10.85,
                    "currency":"BRL",
                    "total":10.85,
                    "description":"Subscription for product: Hit"
                }
            ]
        }
    }
    
    MIME type
    application/vnd.lime.invoice+json

    Allows sending of a payment request to a payment channel.

    Note: Payment invoices are not mapped to channel's cards. The purpose of such messages is only to control the payment's life cycle.

    Native Content

    Sending a Messenger text message:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
      public class OptionNativeContentReceiver : IMessageReceiver
      {
          private readonly ISender _sender;
          private readonly Settings _settings;
    
          public OptionNativeContentReceiver(ISender sender)
          {
              _sender = sender;
              _settings = settings;
          }
    
          public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
          {
              JsonDocument document = new JsonDocument();
    +         document.Add("text", "hello, world!"); //exemplo funcional no messenger
    
              await _sender.SendMessageAsync(document, message.From, cancellationToken);
          }
      }
    
    }
    
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"1",
      "to":"949839515125748@messenger.gw.msging.net",
      "type":"application/json",
      "content":{
        "text": "hello, world!"
      }
    }
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.payment-receipt+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
              text: "hello, world!"
          }
        });
    

    2 - Sending an airline boardingpass template message type to Messenger:

    /*
    No examples for C# here
    still possible but is too big for this doc
    */
    
        client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.payment-receipt+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            attachment:{
              type: "template",
              payload:{
                template_type: "airline_boardingpass",
                intro_message: "You are checked in.",
                locale: "en_US",
                boarding_pass:[
                  {
                    passenger_name: "SMITH\/NICOLAS",
                    pnr_number: "CG4X7U",
                    travel_class: "business",
                    seat: "74J",
                    auxiliary_fields:[
                      {
                        label: "Terminal",
                        value: "T1"
                      },
                      {
                        label: "Departure",
                        value: "30OCT 19:05"
                      }
                    ],
                    secondary_fields:[
                      {
                        label: "Boarding",
                        value: "18:30"
                      },
                      {
                        label: "Gate",
                        value: "D57"
                      },
                      {
                        label: "Seat",
                        value: "74J"
                      },
                      {
                        label: "Sec.Nr.",
                        value: "003"
                      }
                    ],
                    logo_image_url: "https://www.example.com/en/logo.png",
                    header_image_url: "https://www.example.com/en/fb/header.png",
                    qr_code: "M1SMITH/NICOLAS  CG4X7U nawouehgawgnapwi3jfa0wfh",
                    above_bar_code_image_url: "https://www.example.com/en/PLAT.png",
                    flight_info:{
                      flight_number: "KL0642",
                      departure_airport:{
                        airport_code: "JFK",
                        city: "New York",
                        terminal: "T1",
                        gate: "D57"
                      },
                      arrival_airport:{
                        airport_code: "AMS",
                        city: "Amsterdam"
                      },
                      flight_schedule:{
                        departure_time: "2016-01-02T19:05",
                        arrival_time: "2016-01-05T17:30"
                      }
                    }
                  },
                  {
                    passenger_name: "JONES/FARBOUND",
                    pnr_number: "CG4X7U",
                    travel_class: "business",
                    seat: "74K",
                    auxiliary_fields:[
                      {
                        label: "Terminal",
                        value: "T1"
                      },
                      {
                        label: "Departure",
                        value: "30OCT 19:05"
                      }
                    ],
                    secondary_fields:[
                      {
                        label: "Boarding",
                        value: "18:30"
                      },
                      {
                        label: "Gate",
                        value: "D57"
                      },
                      {
                        label: "Seat",
                        value: "74K"
                      },
                      {
                        label: "Sec.Nr.",
                        value: "004"
                      }
                    ],
                    logo_image_url: "https://www.example.com/en/logo.png",
                    header_image_url: "https://www.example.com/en/fb/header.png",
                    qr_code: "M1JONES/FARBOUND  CG4X7U nawouehgawgnapwi3jfa0wfh",
                    above_bar_code_image_url: "https://www.example.com/en/PLAT.png",
                    flight_info:{
                      flight_number: "KL0642",
                      departure_airport:{
                        airport_code: "JFK",
                        city: "New York",
                        terminal: "T1",
                        gate: "D57"
                      },
                      arrival_airport:{
                        airport_code: "AMS",
                        city: "Amsterdam"
                      },
                      flight_schedule:{
                        departure_time: "2016-01-02T19:05",
                        arrival_time: "2016-01-05T17:30"
                      }
                    }
                  }
                ]
              }
            }
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"2",
      "to":"949839515125748@messenger.gw.msging.net",
      "type":"application/json",
      "content":{
        "attachment":{
          "type":"template",
          "payload":{
            "template_type":"airline_boardingpass",
            "intro_message":"You are checked in.",
            "locale":"en_US",
            "boarding_pass":[
              {
                "passenger_name":"SMITH\/NICOLAS",
                "pnr_number":"CG4X7U",
                "travel_class":"business",
                "seat":"74J",
                "auxiliary_fields":[
                  {
                    "label":"Terminal",
                    "value":"T1"
                  },
                  {
                    "label":"Departure",
                    "value":"30OCT 19:05"
                  }
                ],
                "secondary_fields":[
                  {
                    "label":"Boarding",
                    "value":"18:30"
                  },
                  {
                    "label":"Gate",
                    "value":"D57"
                  },
                  {
                    "label":"Seat",
                    "value":"74J"
                  },
                  {
                    "label":"Sec.Nr.",
                    "value":"003"
                  }
                ],
                "logo_image_url":"https://www.example.com/en/logo.png",
                "header_image_url":"https://www.example.com/en/fb/header.png",
                "qr_code":"M1SMITH/NICOLAS  CG4X7U nawouehgawgnapwi3jfa0wfh",
                "above_bar_code_image_url":"https://www.example.com/en/PLAT.png",
                "flight_info":{
                  "flight_number":"KL0642",
                  "departure_airport":{
                    "airport_code":"JFK",
                    "city":"New York",
                    "terminal":"T1",
                    "gate":"D57"
                  },
                  "arrival_airport":{
                    "airport_code":"AMS",
                    "city":"Amsterdam"
                  },
                  "flight_schedule":{
                    "departure_time":"2016-01-02T19:05",
                    "arrival_time":"2016-01-05T17:30"
                  }
                }
              },
              {
                "passenger_name":"JONES/FARBOUND",
                "pnr_number":"CG4X7U",
                "travel_class":"business",
                "seat":"74K",
                "auxiliary_fields":[
                  {
                    "label":"Terminal",
                    "value":"T1"
                  },
                  {
                    "label":"Departure",
                    "value":"30OCT 19:05"
                  }
                ],
                "secondary_fields":[
                  {
                    "label":"Boarding",
                    "value":"18:30"
                  },
                  {
                    "label":"Gate",
                    "value":"D57"
                  },
                  {
                    "label":"Seat",
                    "value":"74K"
                  },
                  {
                    "label":"Sec.Nr.",
                    "value":"004"
                  }
                ],
                "logo_image_url":"https://www.example.com/en/logo.png",
                "header_image_url":"https://www.example.com/en/fb/header.png",
                "qr_code":"M1JONES/FARBOUND  CG4X7U nawouehgawgnapwi3jfa0wfh",
                "above_bar_code_image_url":"https://www.example.com/en/PLAT.png",
                "flight_info":{
                  "flight_number":"KL0642",
                  "departure_airport":{
                    "airport_code":"JFK",
                    "city":"New York",
                    "terminal":"T1",
                    "gate":"D57"
                  },
                  "arrival_airport":{
                    "airport_code":"AMS",
                    "city":"Amsterdam"
                  },
                  "flight_schedule":{
                    "departure_time":"2016-01-02T19:05",
                    "arrival_time":"2016-01-05T17:30"
                  }
                }
              }
            ]
          }
        }
      }
    }
    
    MIME type
    application/json

    Allows sending of a native content of some channel using JSON format. It is possible to use any channel's available resource, even if this content is not yet supported as a BLiP canonical type.

    Note that, for a multi channel chatbot, it is the chatbot developer's responsibility to send the correct content type to each channel.

    Channel mapping

    Channel Type
    BLiP App Does not support
    Messenger Supported (the property content refers to message element of Messenger Send API
    SMS Does not support
    Skype Does not support
    Telegram Does not support

    Sensitive information

    Sending a password using text content for a Messenger user:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class OptionSensitiveMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionSensitiveMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
    
        var document = new SensitiveContainer
        {
            Value = "Your password is 123456"
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.sensitive+json",
          to: "1042225583186385@messenger.gw.msging.net",
          content: {
            type: "text/plain",
            value: "Your password is 123456"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "1",
      "to": "1334448251684655@messenger.gw.msging.net",
      "type": "application/vnd.lime.sensitive+json",
      "content": {
        "type": "text/plain",
        "value": "Your password is 123456"
      }
    }
    
    

    Sending a weblink:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class SensitiveWeblinkMessage : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public SensitiveWeblinkMessage(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var url = new Uri("https://mystore.com/checkout?ID=A8DJS1JFV98AJKS9");
        var document = new SensitiveContainer
        {
            Value = new WebLink
            {
                Text = "Please follow this link for the checkout",
                Uri = url
            }
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.sensitive+json",
          to: "1042225583186385@messenger.gw.msging.net",
          content: {
            type: "application/vnd.lime.web-link+json",
            value: {
              text: "Please follow this link for the checkout",
              uri: "https://mystore.com/checkout?ID=A8DJS1JFV98AJKS9"
            }
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "2",
      "to": "1334448251684655@messenger.gw.msging.net",
      "type": "application/vnd.lime.sensitive+json",
      "content": {
        "type": "application/vnd.lime.web-link+json",
        "value": {
          "text": "Please follow this link for the checkout",
          "uri": "https://mystore.com/checkout?ID=A8DJS1JFV98AJKS9"
        }
      }
    }
    
    
    MIME type
    application/vnd.lime.sensitive+json

    Wraps a message content in order to signal that the information is confidential or sensitive. In this case, the server will not store the message content in any moment. The wrapped content can be of any available BLiP type.

    Important note: This is restricted to the BLiP servers. External channels (Messenger, Telegram, etc.) still can store your information in some way. Pay attention on particular security polices for each channel.

    User input

    Requesting a user's name:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class OptionUserInputMessaReceiver : IMessageReceiver
    {
        private readonly ISender _sender;
    
        public OptionUserInputMessaReceiver(ISender sender)
        {
            _sender = sender;
            _settings = settings;
        }
    
        public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
        {
            var document = new Input
            {
                Label = new DocumentContainer{
                    Value = new PlainText {
                        Text = "What is your name?"
                    }
                },
                Validation = new InputValidation{
                    Rule = InputValidationRule.Text
                }
            };
    
            await _sender.SendMessageAsync(document, message.From, cancellationToken);
        }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.input+json",
          to: "1042225583186385@messenger.gw.msging.net",
          content: {
              label: {
                type: "text/plain",
                value: "What is your name?"
              },
              validation: {
                rule: "text"
              }
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.input+json",
        "content": {
            "label": {
              "type": "text/plain",
              "value": "What is your name?"
            },
            "validation": {
              "rule": "text"
            }
        }
    }
    

    Requesting a user's location:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class UserInputLocationReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    
    public UserInputLocationReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new Input
        {
            Label = new DocumentContainer{
                Value = "Send your location please!"
            },
            Validation = new InputValidation{
                Rule = InputValidationRule.Type,
                Type = "application/vnd.lime.location+json"
            }
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.input+json",
          to: "1042225583186385@messenger.gw.msging.net",
          content: {
              label: {
                type: "text/plain",
                value: "Send your location please!"
              },
              validation: {
                rule: "type",
                type: "application/vnd.lime.location+json"
              }
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "1334448323284655@messenger.gw.msging.net",
        "type": "application/vnd.lime.input+json",
        "content": {
            "label": {
              "type": "text/plain",
              "value": "Send your location please!"
            },
            "validation": {
              "rule": "type",
              "type": "application/vnd.lime.location+json"
            }
        }
    }
    
    MIME type
    application/vnd.lime.input+json

    Allows sending of structured information requests to the user, where it is possible to define validations rules. This is useful for building question forms and getting specific user information - like name or phone number - or typed information - like an image or location. The execution of validation rules depends of channel's support.

    For more details, check the LIME protocol specification.

    Channel mapping

    Channel Type
    BLiP Chat Uer input (for Location type only)
    Messenger Location
    SMS Text
    Skype Activity
    Telegram Message

    Resource

    Sending a resource message with the welcome-message identifier:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class OptionResourceMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionResourceMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new Resource
        {
            Key = "welcome-message" //recurso previamente adicionado com extensão 'recursos' ou através do portal
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.iris.resource+json",
        "content": {
            "key": "welcome-message"
        }
    }
    
    client.sendMessage({
        id: Lime.Guid(),
        type: "application/vnd.iris.resource+json",
        to: "1042221589186385@messenger.gw.msging.net",
        content: {
            key: "welcome-message"
        }
    });
    

    In case there is a resource with this key, the server replaces the content and forwards it to the destination. Imagining that the resource with welcome-message key is a text/plain document with value Welcome to our service, the final message would be like this:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Welcome to our service"
    }
    
    {
        id: "1",
        to: "1042221589186385@messenger.gw.msging.net",
        type: "text/plain",
        content: "Welcome to our service"
    }
    
    MIME type
    application/vnd.iris.resource+json

    Allows sending of a message where the content is a resource stored in the server. The resource should be stored through the resources extension. The server automatically replaces the content with the stored resource, in case the resource key already exists for the caller chatbot.

    The resource may contain variables which can be replaced by values specified during sending time, through the variables property.

    You can enter substitution variables for the resource using the variables property. In this case, the variables present in the resource with the ${variableName} format are replaced by the specified values.

    For example, imagine that the resource in the welcome-message key has the value Welcome to our service, ${name}!'. If you send the following:

    Request

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class ResourceMessageReplace : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public ResourceMessageReplace(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var openWith = new Dictionary<string, string>();
        openWith.Add("name",message.From.Name);
    
        var document = new Resource
        {
            Key = "welcome-message",
            Variables = openWith
    
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.iris.resource+json",
        "content": {
            "key": "welcome-message",
            "variables": {
                "name": "John Doe"
            }
        }
    }
    
    client.sendMessage({
        id: Lime.Guid(),
        to: "1042221589186385@messenger.gw.msging.net",
        type: "application/vnd.iris.resource+json",
        content: {
            key: "welcome-message",
            variables: {
                name: "John Doe"
            }
        }
    });
    

    The final message will be:

    Response

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Welcome to our service, John Doe!"
    }
    
    {
        id: "1",
        to: "1042221589186385@messenger.gw.msging.net",
        type: "text/plain",
        content: "Welcome to our service, John Doe!"
    }
    

    Channel mapping

    This content type is supported on all channels.

    Redirect

    1 - Redirecting to the attendance service

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class OptionRedirectMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public OptionRedirectMessageReceiver(ISender sender)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var document = new Redirect
        {
            Address = "atendimento"
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "54f1dd2e-42d2-43f2-9100-68fbbabb9c83@tunnel.msging.net",
        "type": "application/vnd.lime.redirect+json",
        "content": {
            "address": "attendance"
        }
    }
    
    client.sendMessage({
        id: Lime.Guid(),
        to: "54f1dd2e-42d2-43f2-9100-68fbbabb9c83@tunnel.msging.net",
        type: "application/vnd.lime.redirect+json",
        content: {
            address: "attendance",
        }
    });
    

    From this moment, the messages sent by the client will be forwarded to the chatbot configured as service attendance in the master model settings tab. Note: The customer identifier is not the same for the other bot.

    2 - Redirecting to the chatbot with identifier mysdkbot , passing a document as the context of the conversation.

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class SpecificRedirectPassingContext : IMessageReceiver
    {
        private readonly ISender _sender;
        private readonly Settings _settings;
    
        public SpecificRedirectPassingContext(ISender sender)
        {
            _sender = sender;
            _settings = settings;
        }
    
        public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
        {
           var document = new Redirect
            {
                Address = "mysdkbot@msging.net",
                Context = new DocumentContainer {
                    Value = new PlainText {
                        Text = "Get Started"
                    }
                }
            };
    
            await _sender.SendMessageAsync(document, message.From, cancellationToken);
        }
    }
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "54f1dd2e-42d2-43f2-9100-68fbbabb9c83@tunnel.msging.net",
        "type": "application/vnd.lime.redirect+json",
        "content": {
            "address": "mysdkbot@msging.net",
            "context": {
                "type": "text/plain",
                "value": "Get started"
            }
        }
    }
    
    client.sendMessage({
        id: Lime.Guid(),
        to: "54f1dd2e-42d2-43f2-9100-68fbbabb9c83@tunnel.msging.net",
        type: "application/vnd.lime.redirect+json",
        content: {
            address: "mysdkbot@msging.net",
            context: {
                type: "text/plain",
                value: "Get started"
            }
        }
    });
    

    In this example, the chatbot with mysdkbot identifier will receive the messages sent by the client, in addition to receiving a message with the content defined in the context, as if it had been sent by the client:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "3",
        "from": "2bdcd8d0-9e69-484f-a88a-d5a529708864@tunnel.msging.net",
        "to": "mysdkbot@msging.net",
        "type": "text/plain",
        "content": "Get started"
    }
    
    {
        id: "3",
        from: "2bdcd8d0-9e69-484f-a88a-d5a529708864@tunnel.msging.net",
        to: "mysdkbot@msging.net",
        type: "text/plain",
        content: "Get started"
    }
    
    MIME type
    application/vnd.lime.redirect+json

    Allows the redirection of a particular chatbot conversation to a new address. In practice, it makes the handover of a conversation between different chatbots possible, which can be of any template (FAQ, Human Operator) or SDK / Webhooks.

    Currently, redirection is only supported on chatbots configured as services in master template. This can be done using the chatbot (identifier) address or the service name defined in the master model settings in the portal.

    It is possible to define a document that represents the context of the conversation and that will be received by the chatbot to which the conversation was directed. The context is useful for defining a specific flow in the destination chatbot, for example.

    Channel mapping

    Redirect is currently supported only by chatbots configured as services in the master template. In this case, all messages will have the domain @tunnel.msging.net, since the master template uses the tunnel extension for communication with services (sub-bots).

    Content Types Samples

    Text

    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
        public class OptionPlainTextMessageReceiver : IMessageReceiver
        {
            private readonly ISender _sender;
    
            public OptionPlainTextMessageReceiver(ISender sender)
            {
                _sender = sender;
            }
    
    
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                Document document = new PlainText
                {
                    Text = "Welcome to our service! How can I help you?"
                };
                await _sender.SendMessageAsync(document, message.From, cancellationToken);
            }
    
        }
    }
    
     client.sendMessage({
            id: Lime.Guid(),
            type: "text/plain",
            to: "128271320123982@messenger.gw.msging.net",
            content: "Welcome to our service! How can I help you?"
            })
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "128271320123982@messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Welcome to our service! How can I help you?"
    }
    

    You can send text by using the Plain Text content type.

    Messenger BLiPChat
    imagem imagem

    Images

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var imageUri = new Uri("http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg", UriKind.Absolute);
        var previewUri = new Uri("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX", UriKind.Absolute);
    
        Document document = new MediaLink
        {
            Title = "Cat",
            Text = "Here is a cat image for you!",
            Type = MediaType.Parse("image/jpeg"),
            AspectRatio = "1:1",
            Size = 227791,
            Uri = imageUri,
            PreviewUri = previewUri
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
     client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.media-link+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            title: "Cat",
            text: "Here is a cat image for you!",
            type: "image/jpeg",
            uri: "http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg",
            aspectRatio: "1:1",
            size: 227791,
            previewUri: "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX",
            previewType: "image/jpeg"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "title": "Cat",
            "text": "Here is a cat image for you!",
            "type": "image/jpeg",
            "uri": "http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg",
            "aspectRatio": "1:1",
            "size": 227791,
            "previewUri": "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX",
            "previewType": "image/jpeg"
        }
    }
    

    You can send images by uploading them or sharing a URL using the Media Link content type. Supported formats are jpg, png and gif.

    Messenger BLiPChat
    imagem imagem

    Gif

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var imageUri = new Uri("http://i.giphy.com/14aUO0Mf7dWDXW.gif");
    
        Document document = new MediaLink
        {
            Type = "image/gif",
            Uri = imageUri
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          to: "128271320123982@messenger.gw.msging.net",
          type: "application/vnd.lime.media-link+json",
          content: {
            type: "image/gif",
            uri: "http://i.giphy.com/14aUO0Mf7dWDXW.gif"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "uri": "http://i.giphy.com/14aUO0Mf7dWDXW.gif",
            "type": "image/gif"
        }
    }
    

    You can send gifs by uploading them or sharing a URL using the Media Link content type.

    Messenger BLiPChat
    imagem imagem

    Audio

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        Document document = new MediaLink
        {
            Type = MediaType.Parse("audio/mp3"),
            Uri = new Uri("http://blaamandagjazzband.dk/jazz/mp3/basin_street_blues.mp3"),
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.media-link+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            type: "audio/mp3",
            uri: "http://blaamandagjazzband.dk/jazz/mp3/basin_street_blues.mp3",
            size: 3124123
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "type": "audio/mp3",
            "uri": "http://blaamandagjazzband.dk/jazz/mp3/basin_street_blues.mp3",
            "size": "3124123"
        }
    }
    

    You can send sounds by uploading them or sharing a URL using the Media Link content type.

    Messenger BLiPChat
    imagem imagem

    Video

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        Document document = new MediaLink
        {
            Type = MediaType.Parse("video/mp4"),
            Uri = new Uri("http://techslides.com/demos/sample-videos/small.mp4"),
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          to: "128271320123982@messenger.gw.msging.net",
          type: "application/vnd.lime.media-link+json",
          content: {
            type: "video/mp4",
            uri: "http://techslides.com/demos/sample-videos/small.mp4"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "uri": "http://techslides.com/demos/sample-videos/small.mp4",
            "type": "video/mp4"
        }
    }
    

    You can send videos by uploading them or sharing a URL using the Media Link content type.

    Messenger BLiPChat
    imagem imagem

    Document/Files

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        var uriLink = new Uri("https://gradcollege.okstate.edu/sites/default/files/PDF_linking.pdf");
        var mediaTypeLink = new MediaType(MediaType.DiscreteTypes.Application, "pdf");
        var title = "pdf_open_parameters.pdf";
    
        Document document = new MediaLink
        {
            Title = title,
            Uri = uriLink,
            Type = mediaTypeLink,
            Size = 5540,
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.media-link+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            title: "pdf_open_parameters.pdf",
            uri: "https://gradcollege.okstate.edu/sites/default/files/PDF_linking.pdf",
            type: "application/pdf",
            size: 5540
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "553199991111@0mn.io",
        "type": "application/vnd.lime.media-link+json",
        "content": {
            "title": "pdf_open_parameters.pdf",
            "uri": "https://gradcollege.okstate.edu/sites/default/files/PDF_linking.pdf",
            "type": "application/pdf",
            "size": 5540
        }
    }
    

    You can send documents like PDF's by uploading them or sharing a URL using the Media Link content type.

    Messenger BLiPChat
    imagem imagem
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
        public class OptionDocumentCollectionMessageReceiver : IMessageReceiver
        {
            private readonly ISender _sender;
            Document[] documents;
            JsonDocument jsonDocuments;
            JsonDocument jsonDocuments2;
            JsonDocument jsonDocuments3;
    
            public OptionDocumentCollectionMessageReceiver(ISender sender)
            {
                _sender = sender;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                Document document;
                document = getDocumentCollectionMenuMultimidia();
    
                await _sender.SendMessageAsync(document, message.From, cancellationToken);
            }
    
            public DocumentCollection getDocumentCollectionMenuMultimidia()
            {
                jsonDocuments = new JsonDocument();
                jsonDocuments2 = new JsonDocument();
                jsonDocuments3 = new JsonDocument();
    
                jsonDocuments.Add("Key1", "value1");
                jsonDocuments.Add("Key2", "2");
    
                jsonDocuments2.Add("Key3", "value3");
                jsonDocuments2.Add("Key4", "4");
    
                jsonDocuments3.Add("Key5", "value5");
                jsonDocuments3.Add("Key6", "6");
    
                DocumentSelect[] documents = new DocumentSelect[]
                {
                    new DocumentSelect
                    {
                        Header = new DocumentContainer
                        {
                            Value = new MediaLink
                            {
                                Title = "Title",
                                Text = "This is a first item",
                                Type = "image/jpeg",
                                Uri = new Uri("http://www.isharearena.com/wp-content/uploads/2012/12/wallpaper-281049.jpg"),
                            }
                        },
                        Options = new DocumentSelectOption[]
                        {
                            new DocumentSelectOption
                            {
                                Label = new DocumentContainer
                                {
                                    Value = new WebLink
                                    {
                                        Title = "Link",
                                        Uri = new Uri("http://www.adoteumgatinho.org.br/")
                                    }
                                }
                            },
                            new DocumentSelectOption
                            {
                                Label = new DocumentContainer
                                {
                                    Value = new PlainText
                                    {
                                        Text = "Text 1"
                                    }
                                },
                                Value = new DocumentContainer
                                {
                                    Value = jsonDocuments
                                }
                            }
                        }
                    },
                    new DocumentSelect
                    {
                        Header = new DocumentContainer
                        {
                            Value = new MediaLink
                            {
                                Title = "Title 2",
                                Text = "This is another item",
                                Type = "image/jpeg",
                                Uri = new Uri("http://www.freedigitalphotos.net/images/img/homepage/87357.jpg")
                            }
                        },
                        Options = new DocumentSelectOption[]
                        {
                            new DocumentSelectOption
                            {
                                Label = new DocumentContainer
                                {
                                    Value = new WebLink
                                    {
                                        Title = "Second link",
                                        Text = "Weblink",
                                        Uri = new Uri("https://pt.dreamstime.com/foto-de-stock-brinquedo-pl%C3%A1stico-amarelo-do-pato-image44982058")
                                    }
                                }
                            },
                            new DocumentSelectOption
                            {
                                Label = new DocumentContainer
                                {
                                    Value = new PlainText {
                                        Text = "Second text"
                                    }
                                },
                                Value = new DocumentContainer
                                {
                                    Value = jsonDocuments2
                                }
                            },
                            new DocumentSelectOption
                            {
                                Label = new DocumentContainer
                                {
                                    Value = new PlainText {
                                        Text = "More one text"
                                    }
                                },
                                Value = new DocumentContainer
                                {
                                    Value = jsonDocuments3
                                }
                            }
                        }
                    }
    
                };
    
                var document = new DocumentCollection
                {
                    ItemType = "application/vnd.lime.document-select+json",
                    Items = documents,
                };
    
                return document;
            }
        }
    }
    
    
     client.sendMessage({
            id: Lime.Guid(),
            type: "application/vnd.lime.collection+json",
            to: "128271320123982@messenger.gw.msging.net",
            content: {
                itemType: "application/vnd.lime.document-select+json",
                items: [
                    {
                        header: {
                            type: "application/vnd.lime.media-link+json",
                            value: {
                                title: "Title",
                                text: "This is a first item",
                                type: "image/jpeg",
                                uri: "http://www.isharearena.com/wp-content/uploads/2012/12/wallpaper-281049.jpg"
                            }
                        },
                        options: [
                            {
                                label: {
                                    type: "application/vnd.lime.web-link+json",
                                    value: {
                                        title: "Link",
                                        uri: "http://www.adoteumgatinho.org.br/"
                                    }
                                }
                            },
                            {
                                label: {
                                    type: "text/plain",
                                    value: "Text 1"
                                },
                                value: {
                                    type: "application/json",
                                    value: {
                                        key1: "value1",
                                        key2: 2
                                    }
                                }
                            }
                        ]
                    },
                    {
                        header: {
                            type: "application/vnd.lime.media-link+json",
                            value: {
                                title: "Title 2",
                                text: "This is another item",
                                type: "image/jpeg",
                                uri: "http://www.freedigitalphotos.net/images/img/homepage/87357.jpg"
                            }
                        },
                        options: [
                            {
                                label: {
                                    type: "application/vnd.lime.web-link+json",
                                    value: {
                                        title: "Second link",
                                        text: "Weblink",
                                        uri: "https://pt.dreamstime.com/foto-de-stock-brinquedo-pl%C3%A1stico-amarelo-do-pato-image44982058"
                                    }
                                }
                            },
                            {
                                label: {
                                    type: "text/plain",
                                    value: "Second text"
                                },
                                value: {
                                    type: "application/json",
                                    value: {
                                        key3: "value3",
                                        key4: 4
                                    }
                                }
                            },
                            {
                                label: {
                                    type: "text/plain",
                                    value: "More one text"
                                },
                                value: {
                                    type: "application/json",
                                    value: {
                                        key5: "value5",
                                        key6: 6
                                    }
                                }
                            }
                        ]
                    }
                ]
            }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "5",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.collection+json",
        "content": {
            "itemType": "application/vnd.lime.document-select+json",
            "items": [
                {
                    "header": {
                        "type": "application/vnd.lime.media-link+json",
                        "value": {
                            "title": "Title",
                            "text": "This is a first item",
                            "type": "image/jpeg",
                            "uri": "http://www.isharearena.com/wp-content/uploads/2012/12/wallpaper-281049.jpg"
                        }
                    },
                    "options": [
                        {
                            "label": {
                                "type": "application/vnd.lime.web-link+json",
                                "value": {
                                    "title": "Link",
                                    "uri": "http://www.adoteumgatinho.org.br"
                                }
                            }
                        },
                        {
                            "label": {
                                "type": "text/plain",
                                "value": "Text 1"
                            },
                            "value": {
                                "type": "application/json",
                                "value": {
                                    "key1": "value1",
                                    "key2": "2"
                                }
                            }
                        }
                    ]
                },
                {
                    "header": {
                        "type": "application/vnd.lime.media-link+json",
                        "value": {
                            "title": "Title 2",
                            "text": "This is another item",
                            "type": "image/jpeg",
                            "uri": "http://www.freedigitalphotos.net/images/img/homepage/87357.jpg"
                        }
                    },
                    "options": [
                        {
                            "label": {
                                "type": "application/vnd.lime.web-link+json",
                                "value": {
                                    "title": "Second link",
                                    "text": "Weblink",
                                    "uri": "https://pt.dreamstime.com/foto-de-stock-brinquedo-pl%C3%A1stico-amarelo-do-pato-image44982058"
                                }
                            }
                        },
                        {
                            "label": {
                                "type": "text/plain",
                                "value": "Second text"
                            },
                            "value": {
                                "type": "application/json",
                                "value": {
                                    "key3": "value3",
                                    "key4": "4"
                                }
                            }
                        },
                        {
                            "label": {
                                "type": "text/plain",
                                "value": "More one text"
                            },
                            "value": {
                                "type": "application/json",
                                "value": {
                                    "key5": "value5",
                                    "key6": "6"
                                }
                            }
                        }
                    ]
                }
            ]
        }
    }
    

    You can send carousels by using Document Collection content type and passing an array of Select type as the Items atribute.

    Messenger
    imagem imagem
    BLiPChat
    imagem imagem

    Quick Replies

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        jsonDocuments = new JsonDocument();
        jsonDocuments.Add("Key1", "value1");
        jsonDocuments.Add("Key2", "2");
    
        Document document = new Select
        {
            Scope = SelectScope.Immediate,// (create a quickreply instead menu)
            Text = "Choose an option:",
            Options = new SelectOption[]
            {
                new SelectOption
                {
                    Order = 1,
                    Text = "First option!",
                    Value = new PlainText { Text = "1" }
                },
                new SelectOption
                {
                    Order = 2,
                    Text = "Second option",
                    Value = new PlainText { Text = "2" }
                },
                new SelectOption
                {
                    Order = 3,
                    Text = "Third option",
                    Value = jsonDocuments
                }
            }
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.select+json",
          to: "1042221589186385@messenger.gw.msging.net",
          content: {
            scope:"immediate", // (create a quickreply instead menu)
            text: "Choose an option",
            options: [
                {
                    text: "First option"
                },
                {
                    order: 2,
                    text: "Second option"
                },
                {
                    order: 3,
                    text: "Third option",
                    type: "application/json",
                    value: {
                        key1: "value1",
                        key2: 2
                    }
                }
            ]
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id":"311F87C0-F938-4FF3-991A-7C5AEF7771A5",
        "to":"1042221589186385@messenger.gw.msging.net",
        "type":"application/vnd.lime.select+json",
        "content":{
            "scope":"immediate",
            "text":"Choose an option",
            "options":[
                {
                    "text":"First option"
                },
                {
                    "order":2,
                    "text":"Second option"
                },
                {
                    "order":3,
                    "text":"Third option",
                    "type":"application/json",
                    "value":{
                        "key1":"value1",
                        "key2":2
                    }
                }
            ]
        }
    }
    

    Quick replies provide a way to present a set of up to 11 buttons in-conversation that contain a title and an optional image, and appear prominently above the composer. You can also use quick replies to request a person's location.

    You can send quick replies by using Select. To switch between menu and quick reply you only need to change the scope attribute. Quick replies requires scope to be 'immediate'.

    Messenger BLiPChat
    imagem imagem
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    public class PlainTextMessageReceiver : IMessageReceiver
    {
    private readonly ISender _sender;
    private readonly Settings _settings;
    
    public PlainTextMessageReceiver(ISender sender, Settings settings)
    {
        _sender = sender;
        _settings = settings;
    }
    
    public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
    {
        jsonDocuments = new JsonDocument();
        jsonDocuments.Add("Key1", "value1");
        jsonDocuments.Add("Key2", "2");
    
        Document document = new Select
        {
            Text = "Choose an option:",
            Options = new SelectOption[]
            {
                new SelectOption
                {
                    Order = 1,
                    Text = "First option!",
                    Value = new PlainText { Text = "1" }
                },
                new SelectOption
                {
                    Order = 2,
                    Text = "Second option",
                    Value = new PlainText { Text = "2" }
                },
                new SelectOption
                {
                    Order = 3,
                    Text = "Third option",
                    Value = jsonDocuments
                }
            }
        };
    
        await _sender.SendMessageAsync(document, message.From, cancellationToken);
    }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.select+json",
          to: "1042221589186385@messenger.gw.msging.net",
          content: {
            text: "Choose an option",
            options: [
                {
                    text: "First option"
                },
                {
                    order: 2,
                    text: "Second option"
                },
                {
                    order: 3,
                    text: "Third option",
                    type: "application/json",
                    value: {
                        key1: "value1",
                        key2: 2
                    }
                }
            ]
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id":"311F87C0-F938-4FF3-991A-7C5AEF7771A5",
        "to":"1042221589186385@messenger.gw.msging.net",
        "type":"application/vnd.lime.select+json",
        "content":{
            "text":"Choose an option",
            "options":[
                {
                    "text":"First option"
                },
                {
                    "order":2,
                    "text":"Second option"
                },
                {
                    "order":3,
                    "text":"Third option",
                    "type":"application/json",
                    "value":{
                        "key1":"value1",
                        "key2":2
                    }
                }
            ]
        }
    }
    

    The persistent menu can be set for your bot to help people discover and access functionalities throughout the conversation.

    You can send a menu by using Select as well as quick replies.

    Messenger BLiPChat
    imagem imagem

    Send Location

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
        public class OptionLocationMessageReceiver : IMessageReceiver
        {
            private readonly ISender _sender;
    
            public OptionLocationMessageReceiver(ISender sender)
            {
                _sender = sender;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                Document document = new Location
                {
                    Latitude = -19.919715,
                    Longitude = -43.959753,
                    Altitude = 853,
                    Text = "Take's place"
                };;
    
                await _sender.SendMessageAsync(document, message.From, cancellationToken);
            }
        }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.location+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            latitude: -19.919715,
            longitude: -43.959753,
            altitude: 853,
            text: "Take's place"
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "to": "1042221589186385@messenger.gw.msging.net",
        "type": "application/vnd.lime.location+json",
        "content": {
            "latitude": -19.918899,
            "longitude": -43.959275,
            "altitude": 853,
            "text": "Take's place"
        }
    }
    

    You can send a location by using location.

    Sending a location with latitude, longitude and altitude:

    Messenger BLiPChat
    imagem imagem

    Request Location

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Messaging.Contents;
    using Lime.Protocol;
    using Take.Blip.Client;
    
    namespace MessageTypes
    {
        public class OptionUserInputMessageReceiver : IMessageReceiver
        {
            private readonly ISender _sender;
    
            public OptionUserInputMessageReceiver(ISender sender)
            {
                _sender = sender;
            }
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                Document document = new Input
                {
                    Label = new DocumentContainer
                    {
                        Value = "Send your location please!"
                    },
                    Validation = new InputValidation
                    {
                        Rule = InputValidationRule.Type,
                        Type = "application/vnd.lime.location+json"
                    }
                };
    
                await _sender.SendMessageAsync(document, message.From, cancellationToken);
            }
        }
    }
    
    client.sendMessage({
          id: Lime.Guid(),
          type: "application/vnd.lime.input+json",
          to: "128271320123982@messenger.gw.msging.net",
          content: {
            label: {
              type: "text/plain",
              value: "Send your location please!"
            },
            validation: {
              rule: "type",
              type: "application/vnd.lime.location+json"
            }
          }
        });
    
    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "1334448323284655@messenger.gw.msging.net",
        "type": "application/vnd.lime.input+json",
        "content": {
            "label": {
              "type": "text/plain",
              "value": "Send your location please!"
            },
            "validation": {
              "rule": "type",
              "type": "application/vnd.lime.location+json"
            }
        }
    }
    

    You can send a location request by using input content-type

    Sending a location request:

    Messenger BLiPChat
    imagem imagem

    Extensions

    Extensions are BLiP connected services that provide developers with different features for their chatbots. The extensions can receive commands and messages from the chatbots and execute special tasks, e.g. schedule or send a message broadcast. Through BLiP extensions the bot's developer can reuse a lot of code and focus only on bot's logic.

    As the other platform nodes, each extension has a unique address with postmaster@[identifier].msging.net format. The identifier value is the extension sub domain. Thus, to send commands and messages, use this address. If you don't know what is a command or how you can use this on BLiP, please go to Concepts > Commands section.

    Some extensions can require permission to send messages in name of the chatbot. The command delegation is used to grant this permission and must be sent to server with postmaster@msging.net address. To learn more details, check the delegation documentation.

    Event Analysis

    The event analysis extension allows chatbot's events registration in order to create analytics reports in the BLiP portal. The events are agregated by category, action and day. The reports and graphs can be generated through the portal, in the Panel -> Data analysis option.

    To use any feature of event analysis extension, send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The event document.
    type "application/vnd.iris.eventTrack+json"
    uri /event-track
    to postmaster@analytics.msging.net

    The command's properties resource and method can change according of the feature. An event track object passed as a document resource has the following properties:

    Property Description Example
    category Category to aggregate the related events. billing
    action The action associated to the event. The event counting is made using the actions. payment
    identity Optional contact associated to the event. If contact is a 'testers' group member, the event will be ignored. 123456@messenger.gw.msging.net
    extras Optional extra information to be stored within the event. {"customerId": "41231", "paymentId": "ca82jda"}

    Create an event

    Imagine that your chatbot must track the number of payment orders realized and show this data on a real time report. To make this possible you can register every single success order as an action of the payments category.

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '9494447a-2581-4597-be6a-a5dff33af156',
            'method': 'set',
            'type': 'application/vnd.iris.eventTrack+json',
            'uri': '/event-track',
            'resource': {
                'category': 'billing',
                'action': 'payment'
            }
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "9494447a-2581-4597-be6a-a5dff33af156",
      "to": "postmaster@analytics.msging.net",
      "method": "set",
      "type": "application/vnd.iris.eventTrack+json",
      "uri": "/event-track",
      "resource": {
        "category": "payments",
        "action": "success-order"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "method": "set",
      "status": "success",
      "id": "9494447a-2581-4597-be6a-a5dff33af156",
      "from": "postmaster@analytics.msging.net/#irismsging1",
      "to": "contact@msging.net/default"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.EventTracker;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IEventTrackExtension _eventTrackExtension;
    
            public SampleMessageReceiver(IEventTrackExtension eventTrackExtension)
            {
                _eventTrackExtension = eventTrackExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                await _eventTrackExtension.AddAsync("payments", "success-order");
            }
        }
    }
    

    Create event with identity

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '9494447a-2581-4597-be6a-a5dff33af156',
            'method': 'set',
            'type': 'application/vnd.iris.eventTrack+json',
            'uri': '/event-track',
            'resource': {
              'category': 'billing',
              'action': 'payment',
              'identity': '123456@messenger.gw.msging.net',
            }
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "9494447a-2581-4597-be6a-a5dff33af156",
        "to": "postmaster@analytics.msging.net",
        "method": "set",
        "type": "application/vnd.iris.eventTrack+json",
        "uri": "/event-track",
        "resource": {
            "category": "payments",
            "action": "success-order",
            "identity": "123456@messenger.gw.msging.net",
        }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "method": "set",
      "status": "success",
      "id": "9494447a-2581-4597-be6a-a5dff33af156",
      "from": "postmaster@analytics.msging.net/#irismsging1",
      "to": "contact@msging.net/default"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.EventTracker;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IEventTrackExtension _eventTrackExtension;
    
            public SampleMessageReceiver(IEventTrackExtension eventTrackExtension)
            {
                _eventTrackExtension = eventTrackExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                await _eventTrackExtension.AddAsync("payments", "success-order", identity: new Identity("123456", "messenger.gw.msging.net"));
            }
        }
    }
    

    It is also possible to associate a specific contact in an event. You can use this to ignore events of a tester user for example. If your bot has a 123456@messenger.gw.msging.net contact identity as a tester user, you can ignore all of its tracked events by adding this identity to the event resource object.

    Get Categories

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '3',
            'method': 'get',
            'uri': '/event-track'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "3",
      "to": "postmaster@analytics.msging.net",
      "method": "get",
      "uri": "/event-track"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@analytics.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.eventTrack+json",
        "items": [{
            "category": "payments"
        },
        {
            "category": "accounts"
        }]
      }
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.EventTracker;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IEventTrackExtension _eventTrackExtension;
    
            public SampleMessageReceiver(IEventTrackExtension eventTrackExtension)
            {
                _eventTrackExtension = eventTrackExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var categories = await _eventTrackExtension.GetCategoriesAsync();
            }
        }
    }
    

    Retrieves all tracked categories.

    Get Counters

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '4',
            'method': 'get',
            'uri': '/event-track/billing?startDate=2016-01-01&$take=10'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "4",
      "to": "postmaster@analytics.msging.net",
      "method": "get",
      "uri": "/event-track/payments?startDate=2016-01-01&$take=10"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@analytics.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.eventTrack+json",
        "items": [{
            "category": "payments",
            "action": "success-order",
            "storageDate": "2016-01-01",
            "count": 10
        },
        {
            "category": "payments",
            "action": "success-order",
            "storageDate": "2016-01-02",
            "count": 20
        }]
      }
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.EventTracker;
    using System;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IEventTrackExtension _eventTrackExtension;
    
            public SampleMessageReceiver(IEventTrackExtension eventTrackExtension)
            {
                _eventTrackExtension = eventTrackExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var startDate = new DateTimeOffset(2016, 1, 1, 0, 0, 0, default(TimeSpan));
                var endDate = new DateTimeOffset(2017, 1, 1, 0, 0, 0, default(TimeSpan));
                var take = 10;
    
                var categories =
                  await _eventTrackExtension.GetCategoryActionsCounterAsync(startDate, endDate, "payments", take);
            }
        }
    }
    

    To retrieve all counters of a category, add the category name to the command uri (for instance /event-track/payments). Those counters represent the number of events tracked in a specific pair of action and categories grouped by days. It is also possible to add query strings parameters as request filters. The following filters are available:

    QueryString Description
    $take Limit of total of items to be returned
    startDate Initial date to search for events
    endDate Limit date to retrieve the events

    Get Details

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '5',
            'method': 'get',
            'uri': '/event-track/billing/payment?startDate=2016-01-01&$take=10'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "5",
      "to": "postmaster@analytics.msging.net",
      "method": "get",
      "uri": "/event-track/payments/success-order?startDate=2016-01-01&$take=10"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@analytics.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.eventTrack+json",
        "items": [{
            "category": "payments",
            "action": "success-order",
            "storageDate": "2016-01-01T12:30:00.000Z",
            "extras": {
              "expiration": "2015-12-30",
              "customerId": "199213"
            }
        },
        {
            "category": "payments",
            "action": "success-order",
            "storageDate": "2016-01-02T09:15:00.000Z",
            "extras": {
              "expiration": "2016-01-01",
              "customerId": "4123123"
            }
        }]
      }
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.EventTracker;
    using System;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IEventTrackExtension _eventTrackExtension;
    
            public SampleMessageReceiver(IEventTrackExtension eventTrackExtension)
            {
                _eventTrackExtension = eventTrackExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var startDate = new DateTimeOffset(2016, 1, 1, 0, 0, 0, default(TimeSpan));
                var endDate = new DateTimeOffset(2017, 1, 1, 0, 0, 0, default(TimeSpan));
                var take = 10;
    
                var categories =
                  await _eventTrackExtension.GetAllAsync(startDate, endDate, "payments", "success-order", take: take);
            }
        }
    }
    

    Retrieves all events tracked with a specific pair of action and categories. The following filters are available as possible query strings:

    QueryString Description
    $skip Number of items to be skipped for paging
    $take Limit of total of items to be returned
    startDate Initial date to search for events
    endDate Limit date to retrieve the events

    Schedule

    The scheduler extension allows the chatbot to schedule messages to be sent in specific date and time on its behalf. Any type of message to any destination can be scheduled, including broadcast messages (to a distribution list). The scheduling time must be done in the GMT timezone. Any received notification from a scheduled message is forwarded to the chatbot.

    To use scheduler extension features, send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The schedule document.
    type "application/vnd.iris.schedule+json"
    uri /schedules
    to postmaster@scheduler.msging.net

    The command's properties resource and method can change according to the feature. A schedule object passed as a document resource has the following properties:

    Property Description Example
    message A complete message object to be scheduled. { "id": "1", "to": "destination@0mn.io", "type": "text/plain", "content": "Hi" }
    when The scheduled time (in the GMT timezone) "2017-07-25T17:50:00.000Z"

    Create a scheduling

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '1',
            'to': 'postmaster@broadcast.msging.net',
            'method': 'set',
            'type': 'application/vnd.iris.distribution-list+json',
            'uri': '/lists',
            'resource': {
                'identity': 'your_distributionList@broadcast.msging.net'
            }
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "to": "postmaster@scheduler.msging.net",
      "method": "set",
      "uri": "/schedules",
      "type": "application/vnd.iris.schedule+json",
      "resource": {  
        "message": {  
          "id": "ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67",
          "to": "destination@0mn.io",
          "type": "text/plain",
          "content": "Scheduling test"
        },
        "when": "2016-07-25T17:50:00.000Z"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    { 
      "id": "1",
      "from": "postmaster@scheduler.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Scheduler;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class SampleExtensionMessageReceiver : IMessageReceiver
        {
            private readonly ISchedulerExtension _schedulerExtension;
    
            public SampleExtensionMessageReceiver(ISchedulerExtension schedulerExtension)
            {
                _schedulerExtension = schedulerExtension;
            }
    
            public async Task ReceiveAsync(Message receivedMessage, CancellationToken cancellationToken)
            {
                var schedullingDate = DateTimeOffset.Now.AddMinutes(10);
                var messageContent = "Scheduling test";
    
                var message = new Message
                {
                    Id = Guid.NewGuid().ToString(),
                    To = Node.Parse("destination@0mn.io"),
                    Content = new PlainText { Text = messageContent }
                };
    
                //Schedule a message to next 10 minutes
                await _schedulerExtension.ScheduleMessageAsync(message, schedullingDate);
            }
        }
    }
    

    Scheduling a message text/plain with the content 'Scheduling test' to be sent to the user destination@0mn.io in 2016-07-25T17:50:00.000Z

    Get a scheduled message

    client.addMessageReceiver('text/plain', async (message) => {
        let scheduledMessage = await client.sendCommand({
            'id': '1',
            'to': 'postmaster@scheduler.msging.net',
            'method': 'get',
            'uri': '/schedules/ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "75c1621e-350c-4e85-8854-3e2cf3abbc3a",
      "to": "postmaster@scheduler.msging.net",
      "method": "get",
      "uri": "/schedules/ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "from": "postmaster@scheduler.msging.net/#hmgirismsging2",
      "to": "rssreader@msging.net/default",
      "id": "75c1621e-350c-4e85-8854-3e2cf3abbc3a",
      "method": "get",
      "status": "success",
      "type": "application/vnd.iris.schedule+json",
      "resource": {
        "when": "2016-07-25T17:50:00.000Z",
        "message": {
          "id": "9abfd060-f05b-4ccb-944c-ec9f13525fe0",
          "type": "text/plain",
          "content": "Teste agendamento",
          "from": "contact@msging.net",
          "pp": "postmaster@scheduler.msging.net/contact%40msging.net",
          "to": "destination@0mn.io",
        },
        "status": "scheduled"
      }
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Scheduler;
    
    namespace Extensions
    {
        public class SampleExtensionMessageReceiver : IMessageReceiver
        {
            private readonly ISchedulerExtension _schedulerExtension;
    
            public SampleExtensionMessageReceiver(ISchedulerExtension schedulerExtension)
            {
                _schedulerExtension = schedulerExtension;
            }
    
            public async Task ReceiveAsync(Message receivedMessage, CancellationToken cancellationToken)
            {
                var scheduledMessage = await _schedulerExtension.GetScheduledMessageAsync("ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67", cancellationToken);
            }
        }
    }
    

    Getting an existing scheduled message with id ad19adf8-f5ec-4fff-8aeb-2e7ebe9f7a67. Each scheduled message has tree possible status values: scheduled, executed and canceled. This values are returned when you search for a specific scheduled message.

    Broadcast

    The broadcast extension allows creation and management of distribution lists and their members for sending messages to multiple destinations simultaneously.

    Each distribution list has a unique address in the format list-name@broadcast.msging.net in addition to the members, who are the recipients of messages sent to this list. Only the chatbot that created a remote list has permission to send messages to it.

    Notifications are forwarded to the chatbot when received by the extension.

    In order to use broadcast extension features, you must send commands with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The schedule document.
    type "application/vnd.iris.distribution-list+json"
    uri /lists
    to postmaster@broadcast.msging.net

    The command's properties resource and method can change according to the feature. An schedule object passed as a document resource has the following properties:

    Property Description Example
    identity Identifier of a distribution list. news@broadcast.msging.net

    Default list

    BLiP automatically creates a distribution list with all clients that have already contacted your chatbot. Its address is [bot-identifier]+senders@broadcast.msging.net where bot-identifier is the identifier of your chatbot, which is used with the access key for authentication.

    For example, for a chatbot with identifier mychatbot, this list address would be mychatbot+senders@broadcast.msging.net.

    Replacement variables

    It is possible to use contact replacement variables in the sent messages. For more information, please check the documentation of the Contacts extension.

    Availability

    The Broadcast service is available in the following domains:

    Domain Available Observation
    Messenger x Needed initial user interaction with chatbot
    BLiP Chat x Not necessary initial user interaction with chatbot
    Skype x Needed initial user interaction with chatbot
    SMS x Not necessary initial user interaction with chatbot
    Telegram x Needed initial user interaction with chatbot
    Workplace x Needed initial user interaction with chatbot

    Create a list

    client.addMessageReceiver('text/plain', async (message) => {
      await client.sendCommand({
        "id": "1",
        "to": "postmaster@broadcast.msging.net",
        "method": "set",
        "type": "application/vnd.iris.distribution-list+json",
        "uri": "/lists",
        "resource": {
            "identity": "your_distributionList@broadcast.msging.net"
        }
      });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "to": "postmaster@broadcast.msging.net",
      "method": "set",
      "type": "application/vnd.iris.distribution-list+json",
      "uri": "/lists",
      "resource": {  
        "identity": "your_distributionList@broadcast.msging.net"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@broadcast.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Broadcast;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBroadcastExtension _broadcastExtension;
    
            public SampleMessageReceiver(IBroadcastExtension broadcastExtension)
            {
                _broadcastExtension = broadcastExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var listName = "your_distributionList";
    
                await _broadcastExtension.CreateDistributionListAsync(listName);
            }
        }
    }
    

    Before making a broadcast, it is necessary to create a distribution list and add some members to it. To create a distribution list with your_distributionList identifier you must send command with SET method and a resource document with identity equal to your_distributionList@broadcast.msging.net.

    Get all lists

    client.addMessageReceiver('text/plain', async (message) => {
      await client.sendCommand({
        "id": "1",
        "to": "postmaster@broadcast.msging.net",
        "method": "get",
        "uri": "/lists"
      });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "6",
      "to": "postmaster@broadcast.msging.net",
      "method": "get",
      "uri": "/lists"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "6",
      "from": "postmaster@broadcast.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "total": 2,
        "itemType": "application/vnd.lime.identity",
        "items": [
          "list1@msging.net",
          "contact+senders@msging.net"
        ]
      }
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Broadcast;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBroadcastExtension _broadcastExtension;
    
            public SampleMessageReceiver(IBroadcastExtension broadcastExtension)
            {
                _broadcastExtension = broadcastExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                await _broadcastExtension.GetAllDistributionListsAsync(cancellationToken);
            }
        }
    }
    

    To get all distribution lists associated with your chatbot, you must send a command with GET method.

    Add a member to list

    client.addMessageReceiver('text/plain', async (message) => {
      await client.sendCommand({  
          "id": "2",
          "to": "postmaster@broadcast.msging.net",
          "method": "set",
          "uri": "/lists/your_distributionList@broadcast.msging.net/recipients",
          "type": "application/vnd.lime.identity",
          "resource": message.from //user identity
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "2",
      "to": "postmaster@broadcast.msging.net",
      "method": "set",
      "uri": "/lists/your_distributionList@broadcast.msging.net/recipients",
      "type": "application/vnd.lime.identity",
      "resource": "551100001111@0mn.io"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "2",
      "from": "postmaster@broadcast.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Broadcast;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBroadcastExtension _broadcastExtension;
    
            public SampleMessageReceiver(IBroadcastExtension broadcastExtension)
            {
                _broadcastExtension = broadcastExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var listName = "your_distributionList";
    
                await _broadcastExtension.AddRecipientAsync(listName, Identity.Parse("551100001111@0mn.io"));
            }
        }
    }
    

    After creating a distribution list, you must add some members to receive your broadcasts. To add a member with 551100001111@0mn.io identity to a list with your_distributionList identifier, you must send a command with SET method and resource document equal to a member identity (551100001111@0mn.io). Note that the command URI also must contains the list identifier (/lists/your_distributionList@broadcast.msging.net/recipients)

    Remove members from list

    client.addMessageReceiver('text/plain', async (message) => {
      await client.sendCommand({  
        "id": "3",
        "to": "postmaster@broadcast.msging.net",
        "method": "delete",
        "uri": "/lists/your_distributionList@broadcast.msging.net/recipients/user_identity@0mn.io"
      });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "3",
      "to": "postmaster@broadcast.msging.net",
      "method": "delete",
      "uri": "/lists/noticias@broadcast.msging.net/recipients/551100001111@0mn.io"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@broadcast.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Broadcast;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBroadcastExtension _broadcastExtension;
    
            public SampleMessageReceiver(IBroadcastExtension broadcastExtension)
            {
                _broadcastExtension = broadcastExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var listName = "your_distributionList";
    
                await _broadcastExtension.DeleteRecipientAsync(listName, Identity.Parse("551100001111@0mn.io"));
            }
        }
    }
    

    As the same way you add some members into a distribution list, it is possible to remove its members. To remove a member with 551100001111@0mn.io identity from a list with your_distributionList identifier, you must send a command with DELETE method and command URI with the list and memeber identifier (/lists/your_distributionList@broadcast.msging.net/recipients/551100001111@0mn.io)

    Send message

    client.addMessageReceiver('text/plain', async (message) => {
      await client.sendCommand({
        'id': '4',
        'to': 'your_distributionList@broadcast.msging.net',
        'type': 'text/plain',
        'content': 'Hello participants of this list!'
      });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "4",
      "to": "your_distributionList@broadcast.msging.net",
      "type": "text/plain",
      "content": "Hello participants of this list!"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@broadcast.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      event": "received"
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@broadcast.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "event": "consumed"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Broadcast;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBroadcastExtension _broadcastExtension;
    
            public SampleMessageReceiver(IBroadcastExtension broadcastExtension)
            {
                _broadcastExtension = broadcastExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var listName = "your_distributionList";
    
                await _broadcastExtension.SendMessageAsync(listName, new PlainText { Text = "Hello participants of this list!" });
            }
        }
    }
    

    If you already have a distribution list with some members, you can send messages to this list. Any message sent to a specific list will be received by all of its members.

    Send message with replacement variable

    client.addMessageReceiver('text/plain', async (message) => {
      await client.sendCommand({  
        "id": "5",
        "to": "your_distributionList@broadcast.msging.net",
        "type": "text/plain",
        "content": "Hello ${contact.name}, come to check out our prices!"
      });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "5",
      "to": "your_distributionList@broadcast.msging.net",
      "type": "text/plain",
      "content": "Hello ${contact.name}, come to check out our prices!"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Broadcast;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBroadcastExtension _broadcastExtension;
    
            public SampleMessageReceiver(IBroadcastExtension broadcastExtension)
            {
                _broadcastExtension = broadcastExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var listName = "your_distributionList";
    
                await _broadcastExtension.SendMessageAsync(listName, new PlainText { Text = "Hello ${contact.name}, come to check out our prices!" });
            }
        }
    }
    

    For more information, please check the documentation of the Contacts extension.

    Bucket

    The bucket extension allows the storage of documents in the server on an isolated chatbot's container. This extension is useful to store information about clients that have interacted with the chatbot, like preferences and navigation state.

    Each document has an identifier which is provided during the write operation and this identifier should be used for retrieving the value later. It is possible to set an optional expiration date for the document. Both the identifier and the expiration date are specified in the URI of the command which is sent to the extension.

    Note: If expiration date is not provided, the document will never expire.

    To use the bucket extension, send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The document to be stored.
    type The document type
    uri /buckets
    to postmaster@msging.net (not required)

    The command's properties resource and method can change according to the feature. The document to be stored must be passed on the resource property.

    Store a JSON document

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            'id': '1',
            'method': 'set',
            'uri': '/buckets/xyz1234',
            'type': 'application/json',
            'resource': {  
                'key1': 'value1',
                'key2': 2,
                'key3': [  
                    '3a', '3b', '3c'
                ]
            }
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    
    {  
      "id": "1",
      "method": "set",
      "uri": "/buckets/xyz1234",
      "type": "application/json",
      "resource": {  
        "key1": "value1",
        "key2": 2,
        "key3": [  
          "3a", "3b", "3c"
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Bucket;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBucketExtension _bucketExtension;
    
            public SampleMessageReceiver(IBucketExtension bucketExtension)
            {
                _bucketExtension = bucketExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var jsonDocument = new JsonDocument();
                jsonDocument.Add("key1", "value1");
                jsonDocument.Add("key2", 2);
                jsonDocument.Add("key3", new string[] { "3a", "3b", "3c"} );
    
                await _bucketExtension.SetAsync("xyz1234", jsonDocument);
            }
        }
    }
    

    Storing a JSON object {"key1": "value1", "key2": 2, "key3": ["3a", "3b", "3c"]} identified by xyz1234 key.

    Store a custom document

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({
            "id": "2",
            "method": "set",
            "uri": "/buckets/abcd9876?expiration=30000",
            "type": "application/x-my-type+json",
            "resource": {  
                "myTypeKey1": "value1",
                "myTypeKey2": 2
            }
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    
    {  
      "id": "2",
      "method": "set",
      "uri": "/buckets/abcd9876?expiration=30000",
      "type": "application/x-my-type+json",
      "resource": {  
        "myTypeKey1": "value1",
        "myTypeKey2": 2
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Bucket;
    using System.Runtime.Serialization;
    
    namespace Extensions
    {
        [DataContract]
        public class MyType : Document
        {
            public const string MIME_TYPE = "application/x-my-type+json";
    
            public static readonly MediaType MediaType = MediaType.Parse(MIME_TYPE);
    
            public MyType()
                : base(MediaType)
            {
            }
    
            [DataMember]
            public string MyTypeKey1 { get; set; }
    
            [DataMember]
            public int MyTypeKey2 { get; set; }
        }
    
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBucketExtension _bucketExtension;
    
            public SampleMessageReceiver(IBucketExtension bucketExtension)
            {
                _bucketExtension = bucketExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var myTypeDocument = new MyType();
                myTypeDocument.MyTypeKey1 = "value1";
                myTypeDocument.MyTypeKey2 = 2;
    
                await _bucketExtension.SetAsync("abcd9876", jsonDocument);
            }
        }
    }
    

    Storing a custom document with type application/x-my-type+json and abcd9876 identifier, setting the expiration to 30000 milisseconds (or 30 seconds):

    Get a document

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({  
            'id': '3',
            'method': 'get',
            'uri': '/buckets/xyz1234'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "3",
      "method": "get",
      "uri": "/buckets/xyz1234"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/json",
      "resource": {  
        "key1": "value1",
        "key2": 2,
        "key3": [  
          "3a", "3b", "3c"
        ]
      }  
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Bucket;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private readonly IBucketExtension _bucketExtension;
    
            public SampleMessageReceiver(IBucketExtension bucketExtension)
            {
                _bucketExtension = bucketExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var document = await _bucketExtension.GetAsync<JsonDocument>("xyz1234", cancellationToken);
            }
        }
    }
    

    Retrieving a JSON document identified by xyz1234 key.

    Desk

    The desk extension allows routing and exchange of messages and notifications between bot users and human agents. The human agents can reply the messages using any BLiP supported help desk application (BLiP Desk for instance). Hence, a bot can forward received messages from users to a human agent on the chosen help desk application and vice versa, in a transparent way.

    This feature is useful for enabling humans to reply some complex or unhandled messages as the bot. For example, imagine that you want a chatbot that knows a lot about soccer teams, but for some reason it doesn't know exactly the tickets prices for some matchs. In this scenario, you can use a human to help the bot answer only when users ask about ticket prices.

    Note: BLiP offers BLiP Desk, a free and powerful desk application to enable humans to reply messages sent by a bot.

    Before using this extension, check if you have already properly set a customer service tool (help desk application) on the Portal and if you already have at least one available human agent to receive and reply to messages.

    Forwarding received messages to a human agent

    Imagine a scenario where a user on Messenger channel asks for human help service. Therefore, while the ticket is still open, any message received by the bot should be sent to a human agent.

    At first, the bot receives a message and decides if it must route the user to a human agent. Imagine for instance that the message "Hello, I would like to talk to an attendant." is enough to send the user to an agent.

    {
        "id": "1",
        "from": "1654804277843415@messenger.gw.msging.net",
        "to": "bot@msging.net/instance",
        "type": "text/plain",
        "content": "Hello, I would like to talk to an attendant."
    }
    

    To foward a received message to an agent, send the message to {encoded-user-node}@desk.msging.net, where

    {encoded-user-node} is the ASCII-encoded messages' emmiter node.

    {
        "id": "1",
        "from": "bot@msging.net/instance",
        "to": "1654804277843415%40messenger.gw.msging.net@desk.msging.net",
        "type": "text/plain",
        "content": "Hello, I would like to talk to an attendant."
    }
    

    Forwarding received messages from a human agent to a final user

    Imagine a scenario where a human agent is replying to some message to a user on Messenger channel. The message received by the bot from the human agent must be fowarded to the final user.

    First, the bot receives a message as below:

    {
        "id": "2",
        "from": "1654804277843415%40messenger.gw.msging.net@desk.msging.net",
        "to": "bot@msging.net/instance",
        "type": "text/plain",
        "content": "Hello, here is a human being ;)"
    }
    

    To forward a received message to the specific final user, the bot must decode the received message node so it knows where to respond {encoded-user-node}@desk.msging.net:

    {
        "id": "2",
        "from": "bot@msging.net/instance",
        "to": "1654804277843415@messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Hello, here is a human being ;)"
    }
    

    Handling the end of an attendance

    When the human agent closes some attendance the bot receives a message with a Redirect content type. The Redirect's context property has a Ticket with information about the attendance. In order to get a closed attendance information, add a receiver to application/vnd.lime.redirect+json content type.

    {
        "id": "1",
        "to": "54f1dd2e-42d2-43f2-9100-68fbbabb9c83@tunnel.msging.net",
        "type": "application/vnd.lime.redirect+json",
        "content": {
            "context": {
                "type": ""type": "application/vnd.iris.ticket+json",
                "value": {
                    "id": "1654804277843415",
                    "sequentialId": 0,
                    "ownerIdentity": "bot@msging.net",
                    "customerIdentity": "1654804277843415@messenger.gw.msging.net",
                    "agentIdentity": "ravpacheco%40gmail.com@blip.ai",
                    "status": "ClosedAttendant",
                    "storageDate":"2018-03-20T20:41:54.330Z",
                    "externalId":"3cf18133-7b0f-47d2-8719-bbaec6ee14e4",
                    "rating":0,
                    "team":"Default",
                    "unreadMessages":0
                }
            }
        }
    }
    

    After receiving the Redirect message, the bot can change the user state and start to handle next messages automatically.

    Closing an attendance actively

    TBD

    Directory

    The directory extension allows querying information about customers of your bot, like name, photo and other personal information. BLiP will get this information on the client's channel. Because of this, the command should be sent directly to the server node responsable for the channel (postmaster@<FQDN of the channel>), using a special URI (lime://<FQDN of the channel>/accounts/<Client identity>). Click here to see all channels identifiers.

    If the information is available, an Account document is returned. The availability and detail level of the information depend on the channel, and the application should handle differences appropriately.

    The result of directory queries are automatically stored in the chatbot's roster, except when there's already an entry with the same identifier in the contacts. For more information about the roster, please refer to the extension documentation.

    To get information about a customer, send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method GET
    uri /lime://<FQDN of the channel>/accounts/<Client identity>
    to postmaster@<FQDN of the channel>

    Get client info (on Messenger)

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({  
            'id': '3',
            'method': 'get',
            'uri': '/buckets/xyz1234'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "to": "postmaster@messenger.gw.msging.net",
      "method": "get",
      "uri": "lime://messenger.gw.msging.net/accounts/1042221589186385"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@messenger.gw.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "type": "application/vnd.lime.account+json",
      "method": "get",
      "status": "success",
      "resource": {
        "fullName": "Astraugésilo de Athayde",
        "photoUri": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xtf1/v/t1.0-1/p200x200/14429_1013121325123122924983_n.jpg",
        "gender": "male",
        "culture": "pt-BR",
        "timezone": -3
      }
    }
    
    using Lime.Protocol;
    using System.Threading;
    using System.Threading.Tasks;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Directory;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private IDirectoryExtension _directoryExtension;
    
            public SampleMessageReceiver(IDirectoryExtension directoryExtension)
            {
                _directoryExtension = directoryExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var identity = Identity.Parse("1042221589186385@messenger.gw.msging.net");
                var account =
                    await _directoryExtension
                            .GetDirectoryAccountAsync(identity, cancellationToken);
            }
        }
    }
    

    Get client info (Telegram)

    client.addMessageReceiver('text/plain', async (message) => {
        await client.sendCommand({  
            'id': '2',
            'to': 'postmaster@telegram.gw.msging.net',
            'method': 'get',
            'uri': 'lime://telegram.gw.msging.net/accounts/255600202'
        });
    });
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "2",
      "to": "postmaster@telegram.gw.msging.net",
      "method": "get",
      "uri": "lime://telegram.gw.msging.net/accounts/255600202"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@telegram.gw.msging.net/#irismsging2",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.account+json",
      "resource": {
        "fullName": "João da Silva Sauro"
      }
    }
    
    using Lime.Protocol;
    using System.Threading;
    using System.Threading.Tasks;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Directory;
    
    namespace Extensions
    {
        public class SampleMessageReceiver : IMessageReceiver
        {
            private IDirectoryExtension _directoryExtension;
    
            public SampleMessageReceiver(IDirectoryExtension directoryExtension)
            {
                _directoryExtension = directoryExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var identity = Identity.Parse("255600202@telegram.gw.msging.net");
                var account =
                    await _directoryExtension
                            .GetDirectoryAccountAsync(identity, cancellationToken);
            }
        }
    }
    

    Resources

    The resources extension allows the storage of documents in the server in an isolated space for each chatbot, similar to the bucket extension. The main difference is that these documents can be mapped as contents for messages sent to the chatbot destinations, through the resource key. This means that the chatbot developer can choose to store the content of its messages in the server instead of keeping them on the chatbot code side.

    To manage all resources programmatically, use resources extension sending a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The resource document.
    type The type of the resource document
    uri /resources
    to postmaster@msging.net (not required)

    The BLiP portal offers a resource management interface which helps with the edition of content, avoiding the need to update the code on the application side in case of changes in the chatbot.

    In order to send a resource message, the developer must use the resource content type.

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "method": "set",
      "uri": "/resources/xyz1234",
      "type": "application/vnd.lime.media-link+json",
      "resource": {
        "title": "Cat",
        "text": "Here is a cat image for you!",
        "type": "image/jpeg",
        "uri": "http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg",
        "size": 227791,
        "previewUri": "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX",
        "previewType": "image/jpeg"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Resource;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class ResourceMessageReceiver : IMessageReceiver
        {
            private IResourceExtension _resourceExtension;
    
            public ResourceMessageReceiver(IResourceExtension resourceExtension)
            {
                _resourceExtension = resourceExtension;
            }
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken = default(CancellationToken))
            {
                var mediaLink = new MediaLink
                {
                    Title = "Cat",
                    Text = "Here is a cat image for you!",
                    Uri = new Uri("http://2.bp.blogspot.com/-pATX0YgNSFs/VP-82AQKcuI/AAAAAAAALSU/Vet9e7Qsjjw/s1600/Cat-hd-wallpapers.jpg"),
                    Size = 227791,
                    Type = MediaType.Parse("image/jpeg"),
                    PreviewType = MediaType.Parse("image/jpeg"),
                    PreviewUri = new Uri("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS8qkelB28RstsNxLi7gbrwCLsBVmobPjb5IrwKJSuqSnGX4IzX")
                };
    
                await _resourceExtension.SetAsync("xyz1234", mediaLink);
            }
        }
    }
    

    Storing a media link document with xyz1234 key.

    Store a text/plain resource

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "2",
      "method": "set",
      "uri": "/resources/help-message",
      "type": "text/plain",
      "resource": "To use our services, please send a text message."
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Resource;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class ResourceMessageReceiver : IMessageReceiver
        {
            private IResourceExtension _resourceExtension;
    
            public ResourceMessageReceiver(IResourceExtension resourceExtension)
            {
                _resourceExtension = resourceExtension;
            }
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken = default(CancellationToken))
            {
                var plainText = new PlainText
                {
                    Text = "To use our services, please send a text message."
                };
    
                await _resourceExtension.SetAsync("help-message", plainText);   
            }
        }
    }
    

    Storing a text plain document with help-message key.

    Replacement variables

    It is possible to use contact replacement variables in the created resources. For more information, please check the documentation of the Contacts extension.

    Store a text/plain resource with replacement variable

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "3",
      "method": "set",
      "uri": "/resources/welcome-message",
      "type": "text/plain",
      "resource": "Welcome to our service, ${contact.name}!"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Resource;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class ResourceMessageReceiver : IMessageReceiver
        {
            private IResourceExtension _resourceExtension;
    
            public ResourceMessageReceiver(IResourceExtension resourceExtension)
            {
                _resourceExtension = resourceExtension;
            }
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken = default(CancellationToken))
            {
                var plainText = new PlainText
                {
                    Text = "Welcome to our service, ${contact.name}!"
                };
    
                await _resourceExtension.SetAsync("welcome-message", plainText);            
            }
        }
    }
    

    Storing a text plain document with welcome-message key using replacement variables.

    Sending a resource message

    Click here to see how can you send a resource message.

    Contacts

    The contacts extension allows the management of the chatbot's roster, which can be used to store data of the chatbot's clients. It is possible to save information like name, address, gender and other generic information, using the extras property. It is also possible to use the contacts fields as variables of the messages sent by the chatbot. This property only allows string values and does not allows complex objects. You can also set the group property for contacts organization. Events where the identity property is from a special group called 'testers' will be ignored on BLiP events dashboard.

    To use any feature of contacts extension send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The contact document.
    type "application/vnd.lime.contact+json"
    uri /contacts
    to postmaster@msging.net (not required)

    The command's properties resource and method can change according to the feature. A contact object passed as a document resource has the following properties:

    Property Description Example
    identity The client identity in a specific channel. 11121023102013021@messenger.gw.msging.net (Messenger user)
    name Optional The client's name (string). "Rafael Pacheco"
    gender Optional The client's gender (string). "male"
    group Optional The client's group tag (string). "testers"
    address Optional The client's address (string). "83, Paraguassu Street"
    city Optional The client's city (string). "Belo Horizonte"
    email Optional The client's email (string). "rafaelpa@take.net"
    phoneNumber Optional The client's phone number (string). "5531000000000"
    cellPhoneNumber Optional The client's cell phone number (string). "5531999999999"
    timezone Optional The client's timezone id (int). -3
    culture Optional The client's culture info (string). "pt-br"
    extras Optional The client's extra informations. {"customerExternalId": "41231", "cpf": "00000000000" }

    For more information about the supported fields, please refer to the Lime protocol documentation.

    Message variable replacement

    The contacts fields can be used to replace variables on messages sent by the chatbot. To make a replacement in a message, the metadata key #message.replaceVariables should be present with the value true and the message text should have variables in the ${contact.<propertyName>} format, where <propertyName> is the contact property for replacement. It is possible to use all fields from the contact, including the keys in the extras property. In this case, is only required to use the ${contact.extras.<extraPropertyName>} convention, where <extraPropertyName> is the value for replacement. If the value is not available, it is only removed from the message.

    Add (or update) a contact

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "method": "set",
      "uri": "/contacts",
      "type": "application/vnd.lime.contact+json",
      "resource": {
        "identity": "11121023102013021@messenger.gw.msging.net",
        "name": "John Doe",
        "gender":"male",
        "group":"friends",    
        "extras": {
          "plan":"Gold",
          "code":"1111"      
        }
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Contacts;
    using Lime.Messaging.Resources;
    using System.Collections.Generic;
    
    namespace Extensions
    {
        public class ContactMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IContactExtension _contactExtension;
    
            public ContactMessageReceiver(IMessagingHubSender sender, IContactExtension contactExtension)
            {
                _sender = sender;
                _settings = settings;
                _contactExtension = contactExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var identity = new Identity("11121023102013021", "messenger.gw.msging.net");
                var contact = new Contact
                {
                    Name = "John Doe",
                    Gender = Gender.Male,
                    Group = "friends",
                    Extras = new Dictionary<string, string>
                    {
                        {"plan", "gold" },
                        {"code", "1111" },
                    }
                };
    
                await _contactExtension.SetAsync(identity, contact, cancellationToken);
            }
        }
    }
    

    In order to store informations about a chatbot's client, it is possible to save and update data using contacts extension. This sample shows how to add a Messenger customer with identity 11121023102013021@messenger.gw.msging.net to the chatbot's roster.

    Get contact

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "2",
      "method": "get",
      "uri": "/contacts/11121023102013021@messenger.gw.msging.net"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.contact+json",
      "resource": {
        "identity": "11121023102013021@messenger.gw.msging.net",
        "name": "John Doe",
        "gender":"male",
        "group":"friends",
        "extras": {
          "plan":"Gold",
          "code":"1111"      
        }
      }  
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Contacts;
    
    namespace Extensions
    {
        public class ContactMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IContactExtension _contactExtension;
    
            public ContactMessageReceiver(IMessagingHubSender sender, IContactExtension contactExtension)
            {
                _sender = sender;
                _settings = settings;
                _contactExtension = contactExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var identity = new Identity("11121023102013021", "messenger.gw.msging.net");
    
                var contact = await _contactExtension.GetAsync(identity, cancellationToken);
            }
        }
    }
    

    For the same contact 11121023102013021@messenger.gw.msging.net, it is possible to get all of its information using a GET contact command.

    Get contacts with paging

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "3",
      "method": "get",
      "uri": "/contacts?$skip=0&$take=3"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType":"application/vnd.lime.contact+json",
        "total":10,
        "items": [
          {"identity": "11121023102013021@messenger.gw.msging.net","name": "John Doe","gender":"male", "group":"friends", "extras":{"plan":"Gold","code":"1111"}},
          {"identity": "213121@telegram.gw.msging.net","name": "Joseph from Telegram","email":"ze@gmail.com"},
          {"identity": "5511999990000@take.io","name": "Mary"}
        ]    
      }  
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Contacts;
    
    namespace Extensions
    {
        public class ContactMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IContactExtension _contactExtension;
    
            public ContactMessageReceiver(IMessagingHubSender sender, IContactExtension contactExtension)
            {
                _sender = sender;
                _settings = settings;
                _contactExtension = contactExtension;
            }
    
            public async Task ReceiveAsync(Message message, CancellationToken cancellationToken)
            {
                var identity = new Identity("11121023102013021", "messenger.gw.msging.net");
    
                var contact = await _contactExtension.GetAsync(identity, cancellationToken);
            }
        }
    }
    

    If you need to get more than one chatbot's contact, you can use a query pagination. This sample shows how to take the three first roaster's contacts.

    Send message with contact name

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "to": "11121023102013021@messenger.gw.msging.net",
      "type": "text/plain",
      "value": "Hello ${contact.name}, welcome to the ${contact.extras.plan} plan!",
      "metadata": {
        "#message.replaceVariables": "true"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {  
      "id": "1",
      "to": "11121023102013021@messenger.gw.msging.net",
      "type": "text/plain",
      "value": "Hello John Doe, welcome to the Gold plan!",
      "metadata": {
        "#message.replaceVariables": "true"
      }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Lime.Messaging.Contents;
    
    namespace Extensions
    {
        public class PlainTextMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
    
            public PlainTextMessageReceiver(IMessagingHubSender sender)
            {
                _sender = sender;
                _settings = settings;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                var message = new Message
                {
                    To = Node.Parse("11121023102013021@messenger.gw.msging.net"),
                    Id = Guid.NewGuid().ToString(),
                    Content = new PlainText
                    {
                        Text = "Hello ${contact.name}, welcome to the ${contact.extras.plan} plan!"
                    },
                    Metadata = new Dictionary<string, string>
                    {
                        {"#message.replaceVariables", "true" }
                    }
                };
    
                await _sender.SendMessageAsync(message, cancellationToken);
            }
        }
    }
    

    If you have information of some client stored on the chatbot's roster, you can send a customized message using these values as message variables. To do this, add a metadata { "#message.replaceVariables": "true" } and use any property of the contact resource. This sample shows how to replace a contact name on a welcome message.

    Chat history

    The threads (or chat history) extension allows the chatbot to retrieve the last threads and messages exchanged with the customers.

    To get client's threads or messages exchanged with a bot, send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method get
    uri /threads
    to postmaster@msging.net (not required)

    Get last threads

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "0094447a-2581-4597-be6a-a5dff33af156",
      "method": "get",
      "uri": "/threads"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "method": "get",
      "status": "success",
      "id": "0094447a-2581-4597-be6a-a5dff33af156",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "total": 2,
        "itemType": "application/vnd.iris.thread+json",
        "items": [
          {
            "ownerIdentity": "contact@msging.net",
            "identity": "1180740631991418@messenger.gw.msging.net",
            "lastMessage": {
              "id": "39ed84b9-f89e-4090-a27e-6bd1e69bdfef",
              "direction": "sent",
              "type": "text/plain",
              "content": "Welcome to our service!",
              "date": "2016-12-06T12:32:44.799Z"
            },
            "unreadMessages": 0
          },
          {
            "ownerIdentity": "contact@msging.net",
            "identity": "29%3A1SaTsDWumQFx72srIXI8uhTlpRzPwuJ4TRVhRpSBB7mQ@skype.gw.msging.net",
            "lastMessage": {
              "id": "cc2b70ce-921b-4856-ae41-f00d897f1423",
              "direction": "received",
              "type": "text/plain",
              "content": "Hi",
              "date": "2016-11-24T20:41:38.940Z"
            },
            "unreadMessages": 1
          }
        ]
      }
    }
    

    Getting the last chatbot's threads. By default, BLiP returns the last 50 threads.

    The following uri filters are available to get chatbot's threads:

    QueryString Description
    $take Limit of total of items to be returned
    messageDate Initial date on the threads query

    Get last messages

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "0094447a-2581-4597-be6a-a5dff33af156",
      "method": "get",
      "uri": "/threads/1180740631991418@messenger.gw.msging.net"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "method": "get",
      "status": "success",
      "id": "0094447a-2581-4597-be6a-a5dff33af156",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "total": 3,
        "itemType": "application/vnd.iris.thread-message+json",
        "items": [
          {
            "id": "39ed84b9-f89e-4090-a27e-6bd1e69bdfef",
            "direction": "sent",
            "type": "text/plain",
            "content": "Welcome!",
            "date": "2016-12-06T12:32:44.799Z",
            "status": "consumed"
          },
          {
            "id": "15073ef5-9bab-493c-b630-8636eacba33e",
            "direction": "sent",
            "type": "text/plain",
            "content": "This is a test chatbot.",
            "date": "2016-12-06T12:32:40.640Z",
            "status": "consumed"
          },
          {
            "id": "9b49a7d6-d025-4bb6-a370-1d48fb457deb",
            "direction": "received",
            "type": "text/plain",
            "content": "Good morning",
            "date": "2016-12-06T12:32:35.398Z",
            "status": "accepted"
          }
        ]
      }
    }
    

    Getting the last chatbot's messages in a specific thread. The thread is identified by a client identity (for example: 1180740631991418@messenger.gw.msging.net). By default, BLiP will return the last 20 thread messages.

    The following uri filters are available to get a chatbot's thread:

    QueryString Description
    $take Limit of total of items to be returned
    messageId Initial message id for the thread messages query
    direction Possible values: asc and desc. Define if will be returned de messages after or before respectively

    Transcription

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "0094447a-2581-4597-be6a-a5dff33af156",
        "method": "get",
        "uri": "/threads/1180740631991418@messenger.gw.msging.net/transcription?accessKey=<ACCESS_KEY>"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
        "type": "application/vnd.lime.web-link+json",
        "resource": {
            "target": "blank",
            "uri": "https://goo.gl/iT3oAW",
            "text": "Transcription"
        },
        "method": "get",
        "status": "success",
        "id": "534f447a-2531-4897-fade-a5dffabcd56",
        "from": "postmaster@msging.net/#hmgirismsging2",
        "to": "someawesomebot@msging.net"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using System;
    using Lime.Messaging.Contents;
    using System.Collections.Generic;
    using Take.Blip.Client.Extensions.Threads;
    
    namespace Extensions
    {
        public class PlainTextMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
                private readonly string ACCESS_KEY = "your_access_key";
    
            public PlainTextMessageReceiver(IMessagingHubSender sender)
            {
                _sender = sender;
                _settings = settings;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
    
                      Document transcript = await new ThreadExtension(_sender).GetTranscriptionAsync(Uri.EscapeDataString(m.From.ToIdentity()), ACCESS_KEY, cancellationToken);
                      await _sender.SendMessageAsync(transcript, m.From, cancellationToken);
            }
        }
    }
    

    Returns a link to show a past conversation between the bot and one of its existing contacts.

    The ACCESS_KEY parameter is mandatory for this extension to work.

    Also, remember to remove the instance from the thread identifier (if any) when requesting for a transcription; please refer to the Addressing section for more information about instances.

    NOTE: When the user requests a transcript from an email channel or a Skype channel, you must escape the thread's identity, as shown in the C# example code's ReceiveAsync() method for instance. This also holds for requesting the transcript through HTTP/other SDKs as well.

    Chatbot profile

    The profile extension allows the configuration of chatbot profile properties, which can reflect on the clients in the published channel - if supported. Each property is a document of a type supported by the platform.

    To manage chatbot's profile information, send commands with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The profile property document.
    type The resource document type
    uri /profile
    to postmaster@msging.net (not required)

    The command's properties resource and method can change according to the feature.

    The current supported profile properties are:

    Name Identifier Document type Supported channels
    Start button get-started Text Messenger, BLiP Chat
    Greeting message greeting Text Messenger, BLiP Chat
    Persistent menu persistent-menu Multimedia menu Messenger

    Note: In Messenger, the value of get-started must be defined before the value of persistent-menu.

    Setting Greeting Message

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "method": "set",
      "uri": "/profile/greeting",
      "type": "text/plain",
      "resource": "Hello and welcome to our service!"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Lime.Messaging.Contents;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Profile;
    
    namespace Extensions
    {
        public class ProfileMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IProfileExtension _profileExtension;
    
            public ProfileMessageReceiver(IMessagingHubSender sender, IProfileExtension profileExtension)
            {
                _sender = sender;
                _settings = settings;
                _profileExtension = profileExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                await _profileExtension.SetGreetingAsync(new PlainText { Text = "Hello and welcome to our service!" }, cancellationToken);
            }
        }
    }
    

    In order to set a text greeting message for your chatbot, use a set command on /profile/greeting URI. This sample shows how to add a greeting message with the content "Hello and welcome to our service!".

    Setting simple persistent menu

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "2",
      "method": "set",
      "uri":"/profile/persistent-menu",
      "type":"application/vnd.lime.document-select+json",
      "resource": {
        "options":[
          {
            "label":{
              "type":"text/plain",
              "value":"Option 1"
            }
          },
          {
            "label":{
              "type":"text/plain",
              "value":"Option 2"
            }
          },
          {
            "label":{
              "type":"text/plain",
              "value":"Option 3"
            }
          }
        ]
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Lime.Messaging.Contents;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Profile;
    
    namespace Extensions
    {
        public class ProfileMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IProfileExtension _profileExtension;
    
            public ProfileMessageReceiver(IMessagingHubSender sender, IProfileExtension profileExtension)
            {
                _sender = sender;
                _settings = settings;
                _profileExtension = profileExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                var menu = new DocumentSelect
                {
                    Options = new DocumentSelectOption[]
                    {
                        new DocumentSelectOption
                        {
                            Label = new DocumentContainer
                            {
                                Value = new PlainText
                                {
                                    Text = "Option 1"
                                }
                            }
                        },
                        new DocumentSelectOption
                        {
                            Label = new DocumentContainer
                            {
                                Value = new PlainText
                                {
                                    Text = "Option 2"
                                }
                            }
                        },
                        new DocumentSelectOption
                        {
                            Label = new DocumentContainer
                            {
                                Value = new PlainText
                                {
                                    Text = "Option 3"
                                }
                            }
                        }
                    }
                };
    
                await _profileExtension.SetPersistentMenuAsync(menu, cancellationToken);
            }
        }
    }
    

    In order to set a Messenger persistent menu for your chatbot, use a set command on /profile/persistent-menu URI. This sample shows how to add a simple persistent menu (only on Facebook Messenger channel) with 3 options Option 1, Option 2 and Option 3.

    Setting complex persistent menu

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "3",
      "method": "set",
      "uri":"/profile/persistent-menu",
      "type":"application/vnd.lime.document-select+json",
        "resource":{
          "options":[
            {
              "label":{
                "type":"application/vnd.lime.document-select+json",
                "value":{
                  "header":{
                    "type":"text/plain",
                    "value":"Option 1"
                  },
                  "options":[
                    {
                      "label":{
                        "type":"text/plain",
                        "value":"Option 1.1"
                      }
                    },
                    {
                      "label":{
                        "type":"application/vnd.lime.web-link+json",
                      "value":{
                        "text":"Option 1.2",
                        "uri":"https://address.com/option1.2"
                      }
                    }
                  },
                  {
                    "label":{
                      "type":"application/vnd.lime.document-select+json",
                      "value":{
                        "header":{
                          "type":"text/plain",
                          "value":"Option 1.3"
                        },
                        "options":[
                          {
                            "label":{
                              "type":"text/plain",
                              "value":"Option 1.3.1"
                            }
                          },
                          {
                            "label":{
                              "type":"text/plain",
                              "value":"Option 1.3.2"
                            }
                          },
                          {
                            "label":{
                              "type":"text/plain",
                              "value":"Option 1.3.3"
                            }
                          }
                        ]
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            "label":{
              "type":"text/plain",
              "value":"Option 2"
            }
          },
          {
            "label":{
              "type":"application/vnd.lime.web-link+json",
              "value":{
                "text":"Option 3",
                "uri":"https://address.com/option1.3"
              }
            }
          }
        ]
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Lime.Messaging.Contents;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Profile;
    using System;
    
    namespace Extensions
    {
        public class ProfileMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IProfileExtension _profileExtension;
    
            public ProfileMessageReceiver(IMessagingHubSender sender, IProfileExtension profileExtension)
            {
                _sender = sender;
                _settings = settings;
                _profileExtension = profileExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                var complexMenu = new DocumentSelect
                {
                    Options = new DocumentSelectOption[]
                    {
                        new DocumentSelectOption
                        {
                            Label = new DocumentContainer
                            {
                                Value = new DocumentSelect
                                {
                                    Header = new DocumentContainer{
                                        Value = new PlainText
                                        {
                                            Text = "Option 1"
                                        }
                                    },
                                    Options = new DocumentSelectOption[]
                                    {
                                        new DocumentSelectOption
                                        {
                                            Label = new DocumentContainer
                                            {
                                                Value = new PlainText
                                                {
                                                    Text = "Option 1.1"
                                                }
                                            }
                                        },
                                        new DocumentSelectOption
                                        {
                                            Label = new DocumentContainer
                                            {
                                                Value = new WebLink
                                                {
                                                    Text = "Option 1.2",
                                                    Uri = new Uri("https://address.com/option1.2")
                                                }
                                            }
                                        },
                                        new DocumentSelectOption
                                        {
                                            Label = new DocumentContainer
                                            {
                                                Value = new DocumentSelect
                                                {
                                                    Header = new DocumentContainer{
                                                        Value = new PlainText
                                                        {
                                                            Text = "Option 1.3"
                                                        }
                                                    },
                                                    Options = new DocumentSelectOption[]
                                                    {
                                                        new DocumentSelectOption
                                                        {
                                                            Label = new DocumentContainer{
                                                                Value = new PlainText
                                                                {
                                                                    Text = "Option 1.3.1"
                                                                }
                                                            },
                                                        },
                                                        new DocumentSelectOption
                                                        {
                                                            Label = new DocumentContainer{
                                                                Value = new PlainText
                                                                {
                                                                    Text = "Option 1.3.2"
                                                                }
                                                            },
                                                        },
                                                        new DocumentSelectOption
                                                        {
                                                            Label = new DocumentContainer{
                                                                Value = new PlainText
                                                                {
                                                                    Text = "Option 1.3.3"
                                                                }
                                                            },
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        new DocumentSelectOption
                        {
                            Label = new DocumentContainer
                            {
                                Value = new PlainText
                                {
                                    Text = "Option 2"
                                }
                            }
                        },
                        new DocumentSelectOption
                        {
                            Label = new DocumentContainer
                            {
                                Value = new PlainText
                                {
                                    Text = "Option 3"
                                }
                            }
                        }
                    }
                };
    
                await _profileExtension.SetPersistentMenuAsync(complexMenu, cancellationToken);
            }
        }
    }
    

    Last but not least, you can also add a complex persistent menu (with links and submenus) using a SET command on /profile/persistent-menu URI. This sample shows how to add a complex persistent menu (only on Facebook Messenger channel) with 3 options SubMenu 1, Option 2 and Option 3 as a web link.

    Set start button

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "4",
      "method": "set",
      "uri": "/profile/get-started",
      "type": "text/plain",
      "resource": "Start now"
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Lime.Messaging.Contents;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Profile;
    
    namespace Extensions
    {
        public class ProfileMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IProfileExtension _profileExtension;
    
            public ProfileMessageReceiver(IMessagingHubSender sender, IProfileExtension profileExtension)
            {
                _sender = sender;
                _settings = settings;
                _profileExtension = profileExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                await _profileExtension.SetGetStartedAsync(new PlainText { Text = "Start now" }, cancellationToken);
            }
        }
    }
    

    In order to set a get started button for your chatbot, use a set command on /profile/get-started URI. This sample shows how to add a button that sends the text Start now to your chatbot during the first client interaction.

    Get greeting message

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "5",
      "method": "get",
      "uri": "/profile/greeting"  
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "text/plain",
      "resource": "Hello and welcome to our service!"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Profile;
    
    namespace Extensions
    {
        public class ProfileMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IProfileExtension _profileExtension;
    
            public ProfileMessageReceiver(IMessagingHubSender sender, IProfileExtension profileExtension)
            {
                _sender = sender;
                _settings = settings;
                _profileExtension = profileExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                var greetingMessage = await _profileExtension.GetGreetingAsync(cancellationToken);
            }
        }
    }
    

    Retrieve a saved chatbot's greeting message using a get command on /profile/greeting URI.

    Artificial Intelligence

    Address
    postmaster@ai.msging.net

    The Artificial Intelligence extension allows the creation, training and publication of artificial intelligence models in the providers associated with the chatbot, besides performing sentence analysis to identify intentions and entities. The configuration of the chatbot providers is done through the Artificial Intelligence menu in the BLiP portal.

    You can associate response documents with the model that should be submitted when an intent is matched in a sentence. In addition, the extension can be used to improve the model by associating questions with intentions.

    The training of the model is performed simultaneously on all of the AI ​​providers associated with chatbot. In that case, a snapshot of the model is stored and can be retrieved later to compare its effectiveness with other versions. To use a trained template, you must publish it.

    All manipulation of the model can be done through the portal of the BLiP, and this extension can be used only to perform the analysis of sentences of the users of the chabot.

    Resources

    URI Method Description
    /intentions set Creates a new intention. The id of the intention is returned in the command response.
    /intentions get Search in all intentions that are associated to the chatbot. It is possible to paginate the request using $skip and $take arguments.
    /intentions/{id} get Retrieves an intention by its id.
    /entities set Creates a new entity. The id of the entity is returned in the command response.
    /entities get Search in all intentions that are associated to the chatbot. It is possible to paginate the request using $skip and $take arguments.
    /entities/{id} get Retrieves an entity by its id.
    /intentions/{id}/questions set Create questions associated to the intention id.
    /intentions/{id}/questions get Search in all questions that are associated to the intention id. It is possible to paginate the request using $skip and $take arguments.
    /intentions/{id}/questions/{qid} delete Removes the question with id qid.
    /intentions/{id}/answers set Create answers associated to the intention id.
    /intentions/{id}/answers get Search in all answers that are associated to the intention id. It is possible to paginate the request using $skip and $take arguments.
    /intentions/{id}/answers/{aid} delete Removes the answer with id aid.
    /models set Executes the training or publishing of the model. The action depends of the type of the resource (see the table below).
    /models get Search in all trained and/or published models.
    /analysis set Analyzes an user sentence using a published model.
    /analysis get Retrieves the history of performed analysis. It is possible to paginate the request using using $skip and $take arguments and filter with $filter, using the OData syntax.
    /analysis/{id}/feedback set Provides feedback to a performed analysis and suggest an intention to improve the model.

    The resource types are:

    Name MIME Type Description
    Intention application/vnd.iris.ai.intention+json Intention expressed through a sentence.
    Entity application/vnd.iris.ai.entity+json Entity identified in an intention, with its synonyms.
    Question application/vnd.iris.ai.question+json A user's question that is associated with an intention for model training.
    Answer application/vnd.iris.ai.answer+json Response that can be sent in case a user's intention is identified.
    Training application/vnd.iris.ai.model-training+json Model training request.
    Publishing application/vnd.iris.ai.model-publishing+json Model publishing request, to make it available for use.
    Analisys request application/vnd.iris.ai.analysis-request+json Sentence analysis request.
    Analisys response application/vnd.iris.ai.analysis-response+json Sentence analysis response with the identified intentions and entities.
    Analisys application/vnd.iris.ai.analysis+json History information about a performed analysis.
    Analisys feedback application/vnd.iris.ai.analysis-feedback+json Feedback information about a performed analysis.

    Create an entity

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"1",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/entities",
      "type":"application/vnd.iris.ai.entity+json",
      "resource":{
        "name":"Flavor",
        "values":[
          {
            "name":"Pepperoni",
            "synonymous":[
              "Peperoni",
              "Pepperonee",
              "Pepperouni",
              "Peperony"
            ]
          },
          {
            "name":"Mushrooms",
            "synonymous":[
              "Mashrooms",
              "Mushroom",
              "Mshrooms"
            ]
          }
        ]
      }
    }
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"1",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/entities",
      "type":"application/vnd.iris.ai.entity+json",
      "resource":{
        "name":"Flavor",
        "values":[
          {
            "name":"Pepperoni",
            "synonymous":[
              "Peperoni",
              "Pepperonee",
              "Pepperouni",
              "Peperony"
            ]
          },
          {
            "name":"Mushrooms",
            "synonymous":[
              "Mashrooms",
              "Mushroom",
              "Mshrooms"
            ]
          }
        ]
      }
    }
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"1",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/entities",
      "type":"application/vnd.iris.ai.entity+json",
      "resource":{
        "name":"Flavor",
        "values":[
          {
            "name":"Pepperoni",
            "synonymous":[
              "Peperoni",
              "Pepperonee",
              "Pepperouni",
              "Peperony"
            ]
          },
          {
            "name":"Mushrooms",
            "synonymous":[
              "Mashrooms",
              "Mushroom",
              "Mshrooms"
            ]
          }
        ]
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.entity+json",
      "resource": {
          "id": "flavor"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.entity+json",
      "resource": {
          "id": "flavor"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "1",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.entity+json",
      "resource": {
          "id": "flavor"
      }
    }
    

    Create an intention

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "2",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions",
      "type": "application/vnd.iris.ai.intention+json",
      "resource": {
          "name": "Order pizza"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "2",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions",
      "type": "application/vnd.iris.ai.intention+json",
      "resource": {
          "name": "Order pizza"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "2",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions",
      "type": "application/vnd.iris.ai.intention+json",
      "resource": {
          "name": "Order pizza"
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.intention+json",
      "resource": {
          "id": "order_pizza"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.intention+json",
      "resource": {
          "id": "order_pizza"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "2",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.intention+json",
      "resource": {
          "id": "order_pizza"
      }
    }
    

    Delete an intention

    Where {intention_id} is the intention identifier of an already created intention.

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "10",
      "to": "postmaster@ai.msging.net",
      "method": "delete",
      "uri": "/intentions/{intention_id}/questions",
    }
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "10",
      "to": "postmaster@ai.msging.net",
      "method": "delete",
      "uri": "/intentions/{intention_id}/questions",
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "10",
      "to": "postmaster@ai.msging.net",
      "method": "delete",
      "uri": "/intentions/{intention_id}/questions",
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "10",
      "from": "postmaster@ai.msging.net",
      "to": "contact@msging.net/default",
      "method": "delete",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "10",
      "from": "postmaster@ai.msging.net",
      "to": "contact@msging.net/default",
      "method": "delete",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "10",
      "from": "postmaster@ai.msging.net",
      "to": "contact@msging.net/default",
      "method": "delete",
      "status": "success"
    }
    

    Query the first 10 intentions

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "3",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/intentions?$skip=0&$take=10"
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "3",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/intentions?$skip=0&$take=10"
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "3",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/intentions?$skip=0&$take=10"
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
          "total": 2,
          "itemType": "application/vnd.iris.ai.intention+json",
          "items": [
            {
              "id": "order_pizza",
              "name": "Order pizza"
            },
            {
              "id": "choose_flavor",
              "name": "Choose flavor"
            }
          ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
          "total": 2,
          "itemType": "application/vnd.iris.ai.intention+json",
          "items": [
            {
              "id": "order_pizza",
              "name": "Order pizza"
            },
            {
              "id": "choose_flavor",
              "name": "Choose flavor"
            }
          ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "3",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
          "total": 2,
          "itemType": "application/vnd.iris.ai.intention+json",
          "items": [
            {
              "id": "order_pizza",
              "name": "Order pizza"
            },
            {
              "id": "choose_flavor",
              "name": "Choose flavor"
            }
          ]
      }
    }
    

    Associate questions to an intention

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "4",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions/order_pizza/questions",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.ai.question+json",
        "items":[
          {
            "text": "I want a pizza"
          },
          {
            "text": "I wanna order a pizza"
          },
          {
            "text": "Give me a pizza"
          }
        ]
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "4",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions/order_pizza/questions",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.ai.question+json",
        "items":[
          {
            "text": "I want a pizza"
          },
          {
            "text": "I wanna order a pizza"
          },
          {
            "text": "Give me a pizza"
          }
        ]
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "4",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions/order_pizza/questions",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.ai.question+json",
        "items":[
          {
            "text": "I want a pizza"
          },
          {
            "text": "I wanna order a pizza"
          },
          {
            "text": "Give me a pizza"
          }
        ]
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "4",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    

    Associate answers to an intention

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "5",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions/order_pizza/answers",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.ai.answer+json",
        "items":[
          {
            "type":"text/plain",
            "value":"Which flavor do you want?"
          }
        ]
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "5",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions/order_pizza/answers",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.ai.answer+json",
        "items":[
          {
            "type":"text/plain",
            "value":"Which flavor do you want?"
          }
        ]
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "5",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/intentions/order_pizza/answers",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType": "application/vnd.iris.ai.answer+json",
        "items":[
          {
            "type":"text/plain",
            "value":"Which flavor do you want?"
          }
        ]
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "5",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    

    Train model

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "6",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/models",
      "type": "application/vnd.iris.ai.model-training+json",
      "resource": {
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "6",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/models",
      "type": "application/vnd.iris.ai.model-training+json",
      "resource": {
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "6",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/models",
      "type": "application/vnd.iris.ai.model-training+json",
      "resource": {
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "6",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "6",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "6",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    

    Query the trained

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "7",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/models"
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "7",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/models"
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "7",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/models"
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "7",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
          "total": 1,
          "itemType": "application/vnd.iris.ai.model+json",
          "items": [
            {
              "id":"d3190b46-c723-4831-b9e8-fe43c1816f80",
              "provider":"Watson",
              "externalId":"b518633d-26f6-454c-bd17-890b426f2d40",
              "storageDate":"2017-07-07T18:13:00.000Z",
              "trainingDate":"2017-07-07T18:13:00.000Z"
            },
            {
              "id":"fa0aa23b-5c62-4b90-9c13-986148c0d171",
              "provider":"Luis",
              "externalId":"713331f2-0375-462d-aa58-ff9b8c5075be",
              "storageDate":"2017-07-07T18:13:00.000Z",
              "trainingDate":"2017-07-07T18:13:00.000Z"
            }
          ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "7",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
          "total": 1,
          "itemType": "application/vnd.iris.ai.model+json",
          "items": [
            {
              "id":"d3190b46-c723-4831-b9e8-fe43c1816f80",
              "provider":"Watson",
              "externalId":"b518633d-26f6-454c-bd17-890b426f2d40",
              "storageDate":"2017-07-07T18:13:00.000Z",
              "trainingDate":"2017-07-07T18:13:00.000Z"
            },
            {
              "id":"fa0aa23b-5c62-4b90-9c13-986148c0d171",
              "provider":"Luis",
              "externalId":"713331f2-0375-462d-aa58-ff9b8c5075be",
              "storageDate":"2017-07-07T18:13:00.000Z",
              "trainingDate":"2017-07-07T18:13:00.000Z"
            }
          ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "7",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
          "total": 1,
          "itemType": "application/vnd.iris.ai.model+json",
          "items": [
            {
              "id":"d3190b46-c723-4831-b9e8-fe43c1816f80",
              "provider":"Watson",
              "externalId":"b518633d-26f6-454c-bd17-890b426f2d40",
              "storageDate":"2017-07-07T18:13:00.000Z",
              "trainingDate":"2017-07-07T18:13:00.000Z"
            },
            {
              "id":"fa0aa23b-5c62-4b90-9c13-986148c0d171",
              "provider":"Luis",
              "externalId":"713331f2-0375-462d-aa58-ff9b8c5075be",
              "storageDate":"2017-07-07T18:13:00.000Z",
              "trainingDate":"2017-07-07T18:13:00.000Z"
            }
          ]
      }
    }
    

    Publish model

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "8",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/models",
      "type": "application/vnd.iris.ai.model-publishing+json",
      "resource": {
        "id":"d3190b46-c723-4831-b9e8-fe43c1816f80"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "8",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/models",
      "type": "application/vnd.iris.ai.model-publishing+json",
      "resource": {
        "id":"d3190b46-c723-4831-b9e8-fe43c1816f80"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "8",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/models",
      "type": "application/vnd.iris.ai.model-publishing+json",
      "resource": {
        "id":"d3190b46-c723-4831-b9e8-fe43c1816f80"
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "8",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "8",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "8",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    

    Analyze a sentence in the last published model

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "9",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/analysis",
      "type": "application/vnd.iris.ai.analysis-request+json",
      "resource": {
        "text":"I want a pepperoni pizza"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "9",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/analysis",
      "type": "application/vnd.iris.ai.analysis-request+json",
      "resource": {
        "text":"I want a pepperoni pizza"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "9",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/analysis",
      "type": "application/vnd.iris.ai.analysis-request+json",
      "resource": {
        "text":"I want a pepperoni pizza"
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "9",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.analysis-response+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "intentions":[
          {
            "id":"order_pizza",
            "name":"Order pizza",
            "score": 0.95
          }
        ],
        "entities":[
          {
            "id":"flavor",
            "name":"Flavor",
            "value":"Pepperoni"
          }
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "9",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.analysis-response+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "intentions":[
          {
            "id":"order_pizza",
            "name":"Order pizza",
            "score": 0.95
          }
        ],
        "entities":[
          {
            "id":"flavor",
            "name":"Flavor",
            "value":"Pepperoni"
          }
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "9",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.analysis-response+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "intentions":[
          {
            "id":"order_pizza",
            "name":"Order pizza",
            "score": 0.95
          }
        ],
        "entities":[
          {
            "id":"flavor",
            "name":"Flavor",
            "value":"Pepperoni"
          }
        ]
      }
    }
    

    Analyze a sentence with a specific model

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "10",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/analysis",
      "type": "application/vnd.iris.ai.analysis-request+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "modelId":"fa0aa23b-5c62-4b90-9c13-986148c0d171"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "10",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/analysis",
      "type": "application/vnd.iris.ai.analysis-request+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "modelId":"fa0aa23b-5c62-4b90-9c13-986148c0d171"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "10",
      "to": "postmaster@ai.msging.net",
      "method": "set",
      "uri": "/analysis",
      "type": "application/vnd.iris.ai.analysis-request+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "modelId":"fa0aa23b-5c62-4b90-9c13-986148c0d171"
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "10",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.analysis-response+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "intentions":[
          {
            "id":"order_pizza",
            "name":"Order pizza",
            "score": 0.95
          }
        ],
        "entities":[
          {
            "id":"flavor",
            "name":"Flavor",
            "value":"Pepperoni"
          }
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "10",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.analysis-response+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "intentions":[
          {
            "id":"order_pizza",
            "name":"Order pizza",
            "score": 0.95
          }
        ],
        "entities":[
          {
            "id":"flavor",
            "name":"Flavor",
            "value":"Pepperoni"
          }
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "10",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success",
      "type": "application/vnd.iris.ai.analysis-response+json",
      "resource": {
        "text":"I want a pepperoni pizza",
        "intentions":[
          {
            "id":"order_pizza",
            "name":"Order pizza",
            "score": 0.95
          }
        ],
        "entities":[
          {
            "id":"flavor",
            "name":"Flavor",
            "value":"Pepperoni"
          }
        ]
      }
    }
    

    Get the last 10 analysis

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "11",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/analysis?$take=10&$filter=feedback%20eq%20none"
    }
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "11",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/analysis?$take=10&$filter=feedback%20eq%20none"
    }
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id": "11",
      "to": "postmaster@ai.msging.net",
      "method": "get",
      "uri": "/analysis?$take=10&$filter=feedback%20eq%20none"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "11",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType":"application/vnd.iris.ai.analysis+json",
        "items":[
          {
            "id": "7363369c-8c99-4293-883f-aaabac7dd822",
            "requestDateTime": "2017-07-13T12:28:14.040Z",
            "text": "quero uma pizza marguerita",
            "intention": "I want a pepperoni pizza",
            "score": 1.0,
            "intentions": [
              {
                "id":"order_pizza",
                "name":"Order pizza",
                "score": 1.0
              }
            ],
            "entities": [
              {
                "id":"flavor",
                "name":"Flavor",
                "value":"Pepperoni"
              }
            ],
          }
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "11",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType":"application/vnd.iris.ai.analysis+json",
        "items":[
          {
            "id": "7363369c-8c99-4293-883f-aaabac7dd822",
            "requestDateTime": "2017-07-13T12:28:14.040Z",
            "text": "quero uma pizza marguerita",
            "intention": "I want a pepperoni pizza",
            "score": 1.0,
            "intentions": [
              {
                "id":"order_pizza",
                "name":"Order pizza",
                "score": 1.0
              }
            ],
            "entities": [
              {
                "id":"flavor",
                "name":"Flavor",
                "value":"Pepperoni"
              }
            ],
          }
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "11",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "get",
      "status": "success",
      "type": "application/vnd.lime.collection+json",
      "resource": {
        "itemType":"application/vnd.iris.ai.analysis+json",
        "items":[
          {
            "id": "7363369c-8c99-4293-883f-aaabac7dd822",
            "requestDateTime": "2017-07-13T12:28:14.040Z",
            "text": "quero uma pizza marguerita",
            "intention": "I want a pepperoni pizza",
            "score": 1.0,
            "intentions": [
              {
                "id":"order_pizza",
                "name":"Order pizza",
                "score": 1.0
              }
            ],
            "entities": [
              {
                "id":"flavor",
                "name":"Flavor",
                "value":"Pepperoni"
              }
            ],
          }
        ]
      }
    }
    

    Send an 'approved' feedback

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"12",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"approved"
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "12",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "12",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "12",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    

    Send a 'rejected' feedback

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"13",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"rejected",
        "intentionId":"other_intention"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"13",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"rejected",
        "intentionId":"other_intention"
      }
    }
    
    
    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
      "id":"13",
      "to":"postmaster@ai.msging.net",
      "method":"set",
      "uri":"/analysis/7363369c-8c99-4293-883f-aaabac7dd822/feedback",
      "type":"application/vnd.iris.ai.analysis-feedback+json",
      "resource":{
        "feedback":"rejected",
        "intentionId":"other_intention"
      }
    }
    
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "13",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "13",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": "13",
      "from": "postmaster@ai.msging.net/#irismsging1",
      "to": "contact@msging.net/default",
      "method": "set",
      "status": "success"
    }
    

    Delegation

    The delegation extension allows the chatbot to give permissions to other BLiP identities - like another chatbots - to execute actions on its behalf, like sending messages. The delegation can be required by some extensions. It is required to be executed only once for each delegated identity.

    To use the delegation extension, send a command with the following properties:

    Name Description
    id Unique identifier of the command.
    method The command verb
    resource The delegation document
    type The document type
    uri /delegations
    to postmaster@msging.net (not required)

    The command's properties resource and method can change according to the feature. A delegation object passed as a resource document has the following properties:

    Property Description Example
    target Identity that will receive permission to make request as the caller. postmaster@broadcast.msging.net
    envelopeTypes Envelope types for the target which receives permission to send on behalf of the caller ["message", "notification"]

    For more details, check the delegation resource on LIME protocol specification.

    Give permissions

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "1",
      "method": "set",
      "type": "application/vnd.lime.delegation+json",
      "uri": "/delegations",
      "resource": {  
        "target": "postmaster@broadcast.msging.net",
        "envelopeTypes": [  
          "message"
        ]
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "method": "set",
      "status": "success",
      "id": "1",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Delegation;
    
    namespace Extensions
    {
        public class DelegationMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IDelegationExtension _delegationExtension;
    
            public DelegationMessageReceiver(IMessagingHubSender sender, IDelegationExtension delegationExtension)
            {
                _sender = sender;
                _settings = settings;
                _delegationExtension = delegationExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                var envelopeTypes = new EnvelopeType[]
                {
                    EnvelopeType.Message
                };
    
                await _delegationExtension.DelegateAsync(Identity.Parse("postmaster@broadcast.msging.net"), envelopeTypes, cancellationToken);
            }
        }
    }
    

    Giving permission to another identity send message as the caller (the bot).

    Revoke permissions

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {  
      "id": "2",
      "method": "delete",
      "uri": "/delegations/postmaster@broadcast.msging.net?envelopeTypes=message"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "method": "delete",
      "status": "success",
      "id": "2",
      "from": "postmaster@msging.net/#irismsging1",
      "to": "contact@msging.net/default"
    }
    
    using System.Threading;
    using System.Threading.Tasks;
    using Lime.Protocol;
    using Take.Blip.Client;
    using Take.Blip.Client.Receivers;
    using Take.Blip.Client.Extensions.Delegation;
    
    namespace Extensions
    {
        public class DelegationMessageReceiver : IMessageReceiver
        {
            private readonly IMessagingHubSender _sender;
            private readonly IDelegationExtension _delegationExtension;
    
            public DelegationMessageReceiver(IMessagingHubSender sender, IDelegationExtension delegationExtension)
            {
                _sender = sender;
                _settings = settings;
                _delegationExtension = delegationExtension;
            }
    
            public async Task ReceiveAsync(Message m, CancellationToken cancellationToken)
            {
                var envelopeTypes = new EnvelopeType[]
                {
                    EnvelopeType.Message
                };
    
                await _delegationExtension.UndelegateAsync(Identity.Parse("postmaster@broadcast.msging.net"), envelopeTypes, cancellationToken);
            }
        }
    }
    

    Revoking granted permission.

    Tunnel

    The tunnel extension allows routing and exchange of messages and notifications between different chatbots of the BLiP platform. In this way, a sender bot can forward received messages to a receiver bot in a transparent way, and the mechanism of reception for this is exactly the same as the messages coming from external channels (Messenger, Telegram, SMS , BLiP Chat, etc.). Therefore, the receiver bot does not need to be specifically implemented to receive forwarded messages, and the notifications and response messages generated by the receivers are automatically forwarded to the sender.

    This feature is useful for isolating different parts of navigation in independent bots with only one published on the channel. For example, imagine that you want to have a chatbot on a Facebook page that has an automatic navigation (static answers), part questions and answers and part attendance made by an human operator. You would then need a bot main (SDK / Webhook) that will act as a switcher and three sub-bots - the first of the SDK/Webhook template, the second FAQ and the last human operator. These last three would not be published directly on the channel, but would only receive messages from the main bot, this one - published on Facebook and other channels. The main bot would be the sender and the other receivers of the tunnel.

    Note: The BLiP portal offers the master template that uses the tunnel extension and acts as a switcher for the sub-bots, so the implementation is not necessary in most cases.

    To create a tunnel between two chatbots, the sender needs to send a message to a address using the following convention:

    [receiver-identifier]@tunnel.msging.net/[originator-address]
    

    Where:

    The receiver receives messages, sends notifications and response messages to an adress in the following format:

    [tunnel-id]@tunnel.msging.net
    

    Where:

    Address Base URI
    postmaster@tunnel.msging.net N/A

    Creating Flow Bot(5 steps)

    Imagine a scenario where there are two bots: flow and operator, where the first is responsible for presenting an automatic navigation and the second receiving the handover of an eventual manual attendance. Only the flow bot is published in Messenger and it needs, at a certain point in its flow, to forward the messages to the operator bot that controls the manual attendance.

    The complete path of a message from this external channel to the service bot is:

    The main bot receives a message from a Messenger user.

    {
        "id": "1",
        "from": "1654804277843415@messenger.gw.msging.net",
        "to": "flow@msging.net/instance",
        "type": "text/plain",
        "content": "Hello, I would like to talk to an attendant."
    }
    

    According to its internal rules, the flow bot decides to forward this message to the operator bot. To do this, it changes the recipient of the message and sends it as bellow:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "from": "flow@msging.net/instance",
        "to": "operator@tunnel.msging.net/1654804277843415%40messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Hello, I would like to talk to an attendant."
    }
    

    Internally, the server creates an id for the tunnel and forwards the message to the operator bot, which receives it as follows:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "1",
        "from": "ecb99cf5-fb5c-4376-8acd-4b478091de15@tunnel.msging.net",
        "to": "operator@msging.net",
        "type": "text/plain",
        "content": "Hello, I would like to talk to an attendant."
    }
    

    The operator bot generates a reply to the message and forwards it to the source address, without differentiating a message received directly from a channel (the same goes for received/consumed notifications):

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "from": "operator@msging.net/instance",
        "to": "ecb99cf5-fb5c-4376-8acd-4b478091de15@tunnel.msging.net",
        "type": "text/plain",
        "content": "Hi, my name is Andre. How may I help you?"
    }
    

    The server uses the tunnel id to change the address of the response message and forwards it to the flow bot:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "from": "operator@tunnel.msging.net/1654804277843415%40messenger.gw.msging.net",
        "to": "flow@msging.net/instance",
        "type": "text/plain",
        "content": "Hi, my name is Andre. How may I help you?"
    }
    

    The bot flow identifies the message received from a receiver, decodes the original address that is in instance and sends the message to the final recipient:

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "from": "flow@msging.net/instance",
        "to": "1654804277843415@messenger.gw.msging.net",
        "type": "text/plain",
        "content": "Hi, my name is Andre. How may I help you?"
    }
    

    Querying information

    The tunnel extension also allows querying information from the message originator in the directory, as long as the information is stored in the contact roster of the sender bot. To use this feature, the bot just needs to send a common directory request:

    Sending a command to the query in the directory using the tunnel id:

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "3",
        "from": "operator@msging.net/instance",
        "to": "postmaster@tunnel.msging.net",
        "method":"get",
        "uri": "lime://tunnel.msging.net/accounts/ecb99cf5-fb5c-4376-8acd-4b478091de15"
    }
    

    The server identifies that the query is for a tunnel user and performs the query on behalf of the sender directly in its contacts roster and returns the information:

    POST https://msging.net/commands HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "3",
        "from": "postmaster@tunnel.msging.net",
        "to": "operator@msging.net/instance",
        "method":"get",
        "status": "success",
        "type": "application/vnd.lime.account+json",
        "resource": {
            "fullName": "John Deere",
            "gender": "male"
        }
    }
    

    For more information about the contacts extension, please refer to the extension documentation.

    Integrations

    BLiP Chat

    FQDN Identifier type
    @0mn.io Internal BLiP Chat value

    BLiP Chat is the official channel of BLiP, providing your chatbot embedded in your website, Android or iOS apps.

    E-mail

    FQDN Identifier type
    @mailgun.gw.msging.net E-mail address on URL encoded format

    E-mail channel allows sending and receiving messages through e-mail messages. Each chatbot has an unique address automatically created by the platform.

    Facebook

    FQDN Identifier type
    @messenger.gw.msging.net Internal Messenger value (client by page) / MSISDN (via customer matching)

    Facebook channel is Messenger messages platform channel. It is accessible through mobile apps for Android, iOS and Windows.

    Skype

    FQDN Identifier type
    @skype.gw.msging.net Live ID

    Skype channel allows sending messages through Skype Microsoft’s app.

    Take.io (SMS)

    FQDN Identifier type
    @take.io MSISDN

    Take.io channel allows SMS messages exchange through the Take’s platform with the same name.

    Tangram (SMS)

    FQDN Identifier type
    @tangram.com.br MSISDN

    Tangram channel allows sending SMS messages through the Take’s platform with the same name.

    Telegram

    FQDN Identifier type
    @telegram.gw.msging.net Chat ID

    Telegram channel allows sending messages through Telegram Messenger app. Available for Web, Android, iOS, Windows and OSX.

    PagSeguro (Payments)

    FQDN Identifier type
    @pagseguro.gw.msging.net Identity ([name and original channel domain]
    (http://www.w3schools.com/tags/ref_urlencode.asp)

    PagSeguro is the UOL's payments channel to receive and send payments with flexibility and safety.

    Payment channels are integrations with payment suppliers connected to Blip Messaging Hub, in which the contacts may receive/send payment from/to customers. Each channel has one identifier that is utilized in the addressing, located before the @ of the address.

    In order to receive or send payments to a channel, the contact must be configured on it. Configuration is made through the portal, where some specific channel information, such as the APIs’ tokens for example, will be requested. It is necessary to fullfill a previous registration form on each channel, normally through the supplier’s site.

    Payment Request

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "to": "1042221589186385%40messenger.gw.msging.net@pagseguro.gw.msging.net",
        "type": "application/vnd.lime.invoice+json",
        "content": {
            "created": "2016-08-26T19:03:37.024Z",
            "dueTo": "2016-08-27T19:03:37.024Z",
            "currency": "BRL",
            "total": 10.85,
            "items": [{
                    "quantity": 1.0,
                    "unit": 10.85,
                    "currency": "BRL",
                    "total" :10.85,
                    "description": "Item 1"
                }
            ]
        }
    }
    

    Example of how to send a payment request to a Facebook Messenger user using PagSeguro.

    Payment Status

    POST https://msging.net/messages HTTP/1.1
    Content-Type: application/json
    Authorization: Key {YOUR_TOKEN}
    
    {
        "id": "2",
        "from": "1042221589186385%40messenger.gw.msging.net@pagseguro.gw.msging.net",
        "to": "contact@msging.net/default",
        "pp": "postmaster@pagseguro.gw.msging.net",
        "type": "application/vnd.lime.invoice-status+json",
        "content": {
            "status": "completed",
            "date": "2016-08-26T19:31:31.000Z",
            "code": "215BF6B5-01EF-4F9A-A944-0BC05FD0F228"
        }
    }
    

    When there is payment status change (for example: user has payed), a payment status message will be sent to the chatbot, the message identifier will be the same as the original payment request’s.