BaaS

ServisBOT BaaS is the home for mappings between the ServisBOT platform and external services such as APIs and SDKs. We currently have two kinds:

BaaS API connectors work best for RESTfull APIs, but with the full power of AWS available in the platform, providing custom integrations other services should still be possible.

Getting started with the BaaS

We have created a mock API and examples for creating your first series of API connectors.

Get Started

API Connector

The api-connector is used to hit HTTP endpoints. For example:

{
  "Alias": "phoneNumberValidate",
  "Body": {},
  "Endpoint": "https://password-reset.herokuapp.com/validatePhoneNumber",
  "Headers": {
    "Authorization": "************************",
    "Content-Type": "application/json"
  },
  "Method": "POST",
  "RequestMapping": {
    "telephoneNumber": {
      "inputPath": "$.telephoneNumber",
      "requestBodyPath": "$.telephoneNumber",
      "type": "requestBody"
    }
  },
  "ResponseMapping": {
    "telephoneNumber": {
      "outputPath": "$.telephoneNumber",
      "responseBodyPath": "$.telephoneNumber",
      "type": "responseBody"
    }
  }
}

This BAAS will hit the endpoint called out in the Endpoint parameter with a POST from the Method parameter. The Authorization and Content-Type headers will be added to the request and the RequestMapping and ResponseMapping will work per the next section of this document.

Private API Connector

The private-api-connector is used to hit HTTP endpoints, via VPC and NAT so it always comes from a known host ip address. For example:

{
  "Alias": "phoneNumberValidate",
  "Type": "private-api-connecter",
  "Body": {},
  "Endpoint": "https://password-reset.herokuapp.com/validatePhoneNumber",
  "Headers": {
    "Authorization": "************************",
    "Content-Type": "application/json"
  },
  "Method": "POST",
  "RequestMapping": {
    "telephoneNumber": {
      "inputPath": "$.telephoneNumber",
      "requestBodyPath": "$.telephoneNumber",
      "type": "requestBody"
    }
  },
  "ResponseMapping": {
    "telephoneNumber": {
      "outputPath": "$.telephoneNumber",
      "responseBodyPath": "$.telephoneNumber",
      "type": "responseBody"
    }
  }
}

This will perform the same request as above in the API Connector, but instead go out via an VPC and NAT.

AWS SDK Connector

The aws-sdk BaaS connector allows you to directly call a functionality within the AWS SDK.

{
  "Alias": "detectSentiment",
  "Body": {},
  "Credentials": "srn:vault::goes::here",
  "Type": "aws-sdk",
  "Endpoint": "Comprehend",
  "Method": "detectSentiment",
  "RequestMapping": {
    "LanguageCode": {
      "inputPath": "$.LanguageCode",
      "requestBodyPath": "$.LanguageCode",
      "type": "requestBody"
    },
    "Text": {
      "inputPath": "$.Text",
      "requestBodyPath": "$.Text",
      "type": "requestBody"
    }
  },
  "Region": "eu-west-1"
}

aws-sdk BaaS entries require your AWS credentials in order to function. They should be saved a Secret, and then referenced by the Credentials property.

The Endpoint is the AWS service to talk to according to the AWS SDK. In this example, we’re using the Comprehend service; the Method is the function to call in that service, which is detectSentiment in this case.

Request/response parameters

There are 5 different parameter types that can be passed:

  • Request body
  • Request URL
  • Request header
  • Response body
  • Response header

You can see the examples below for an idea of what each one does.

Terminology

To fully understand the various properties that belong to each parameter type, it can be helpful to know about the meaning of the terms used:

  • Input: content that is sent to the BaaS service from the outside world (e.g. a bot)
  • Output: content that the BaaS service returns back to the outside world
  • Request: content that the BaaS service sends to the specified API endpoint
  • Response: content that the API endpoint returns to the BaaS after being called

Request body

new BaaS.API({
    "RequestMapping": {
        "convId": {
            "type": "requestBody",
            "inputPath": "$.token.contents.public.${convoId}.jwt",
            "requestBodyPath": "$.users.${convoId}.jwt"
        }
    },
    // every other field ...
});
// context
{
  token: { contents: { public: { myconv: { jwt: 'theJwt' } } } },
  convoId: 'myconv'
}
// outputs request body
{ users: { myconv: { jwt: "theJwt" } } }

The Request body also supports encoding of files that are stored within s3. Currently only files uploaded via messenger into the gossip attachment folder are support.

new BaaS.API({
    "RequestMapping": {
        "policyDoc": {
            "encoding": "Base64", // type of encoding, currently only Base64 is supported
            "inputPath": "$.fileUrl", // location of the image in the bucket
            "requestBodyPath": "$.policyDoc",
            "type": "requestBody"
    }
  },
    // every other field ...
});
// context
{
  fileUrl: 'https://servisbot-heupper-gossip.s3.eu-west-1.amazonaws.com/attachments/flowit/eu-west-1:123/7YCU-2qCF.jpg?'
}
// outputs request body
{
    policyDoc: '<Base64 encoded string of the file>'
}

If for any reason you want to send some important info in the body, you can supply an SRN secret for this too

new BaaS.API({
    "body":{
        "importantToken":"srn:vault:global:myorg:secret:my-secret-name:78",
    },
    "RequestMapping": {
  },
    // every other field ...
});

Request URL

new BaaS.API({
    "RequestMapping": {
        "jwt": {
            "type": "requestURL",
            "inputPath": "$.token.contents.public.type",
            "requestParameter": "type"
        }
    },
    Endpoint: "http://www.servisbot.com/widgets/${type}"
    // every other field ...
});
// context
{
  token: { contents: { public: { type: 'myType'} } },
  convoId: 'myconv'
}
// outputs
'http://www.servisbot.com/widgets/myType'

Request header

new BaaS.API({
    "RequestMapping": {
        "jwt": {
            "type": "requestHeader",
            "inputPath": "$.token.contents.public.jwt",
            "requestParameter": "jwt"
        }
    },
    "Headers": {
        "Authorization": "Bearer ${jwt}",
        "X-AMZ-Auth-${jwt}": "${jwt}"
        //Headers can also contain an SRN now to hide Authorization tokens, i.e.
        "Authorization": "srn:vault:global:myorg:secret:my-secret-name:78"
    }
    // every other field ...
});
// context
{
  token: { contents: { public: { jwt: '1a2b3c'} } },
  convoId: 'myconv'
}
// outputs headers
{ "Authorization": "Bearer 1a2b3c", "X-AMZ-Auth-1a2b3c": "1a2b3c" }

Response body

new BaaS.API({
    "ResponseMapping": {
        "jwt": {
            "type": "responseBody",
            "responseBodyPath": "$.token.contents.${somevalue}.jwt",
            "outputPath": "$.users.jwt"
        }
    }),
    // every other field ...
});
// output from the API
{
    somevalue: 'public', // $.token.contents.${somevalue}.jwt gets replaced with $.token.contents.public.jwt
    token: { contents: { public: { jwt: '1a2b3c'} } },
}

// outputs response body
{
    "users": { "jwt": "1a2b3c" }
}

Response header

new BaaS.API({
    "ResponseMapping": {
        "jwt": {
            "type": "responseHeader",
            "responseHeaderKey": "content-type",
            "outputPath": "$.contentType"
        }
    }),
    // every other field ...
});
// response has header
`'content-type', 'application/json; charset=utf-8'`

// outputs
{
    response: { ... },
    status: 200,
    headers: { contentType: "application/json; charset=utf-8" }
}