Step 3: Develop your app
Each app has its own architecture and components required, but the overall process of developing your app is the same.
- Create the app shell
- Develop the core functionality of your app
- Create and connect the configuration page and settings DB, and connect to middleware/context card (optional)
- Connect your app to Infobip by updating the manifest
- Test your app.
- List to marketplace (optional)
Create the app shell
To get started creating an app, you’ll need to create the app shell which contains the information Infobip needs to use your app’s functionality. This also creates the app’s Client ID and Client Secret that can be used in the OAuth process.
When the app shell is first created, it is available to your account, but not available to anyone else. This is called private access. To make your app available to additional accounts, see the section on Listing your app on the Exchange marketplace.
To create your app shell:
-
Log into your Infobip account and go to Exchange (opens in a new tab).
-
Click Publish. If you can't see the Publish option, contact the Infobip Support (opens in a new tab) team to request access.
-
Click Create App.
-
Enter a name for your app in the App Name You can choose any name you prefer, but if you want to list your app on the public Exchange marketplace, you need to choose a unique name.
-
From the Works withdrop-down list, select the products that your app uses. You can select all the relevant products.
Product Notes Conversations If your app is a context card, you do not need to select a channel as the app works natively with the channels supported by Conversations. Answers If your app is a chatbot block, you do not need to select a channel as the app works natively with the channels supported by Answers. Moments Flow If your app is a Moments Flow element, you do not need to select a channel as the app works natively with the channels supported by Moments. People If your app syncs data via the People API, then you do not need to select the channel as the app works with the channels supported by People. Channels If you have integrated a channel into your product using an API, then select the relevant channel. You'll then see an embedded text editor where you can build your manifest by editing the values. If you have chosen more than one product from the Works with drop-down list, you see separate tabs for each integration point manifest. Choose whether to use YAML or JSON to define your manifest.
-
Edit the example manifest in the embedded text editor to define how your app connects to Infobip. At this stage, you can still create the app using default or dummy values, but be sure to update your manifest when you have the relevant information. See the section Define your manifest to correctly structure your manifest.
-
Specify the URLs for: Settings URL for the location of the settings and configuration for the app. This is a web page where users can save settings and configure your app. This field is optional. Redirect URL for redirecting after authentication. If you use OAuth to connect your app to Infobip, this is the URL that redirects back to your app after authentication.
-
Add a URL to an image for the logo in the Logo URL field. The logo file must be SVG format (.svg), with a size of 40 x 40 pixels.
-
Click Create App to save your app settings and generate the app's credentials for connecting to Infobip.
You see the app created and listed in the Exchange Publish page.
The app details show the name and a Private label to show that it is available only to your account.
You'll also see the Infobip products that relate to this app.
The three-dot menu gives you a number of options.
Option | Description |
Edit | Make changes to the settings that you entered in the publish stage. You can also view the Client ID, Client Secret and Signing secret. |
Configure | Open the settings URL page for the app settings and configuration. |
View ID | View the client ID and client secret, the OAuth credentials used in authorization. |
Delete | Remove the app from Exchange. |
Once you've created your app, it is active for your account only. If the app includes a context card, the card is available to all agents in your account. If the app includes an Answers bot block, the block is available in the bot builder canvas.
If you intend to use the OAuth 2.0 flow with your app, you need to save the client ID and client secret. To validate the execution signature in Answers, you need to save the signing secret.
Develop core functionality of your app
In this step, you create the core functionality for the app. Depending on the needs of your app, you may create a UI experience through a website embedded via an iframe, an API, or middleware to interpret the call from Answers to your API endpoint.
Conversations
The following core functionality can be developed for Conversations:
- Context Card UI: standard and XL sizes
- Full page UI
Context Card UI
Conversations context cards allow you to show custom information to contact center agents in their workspace, as they assist end customers. Your context card UI should be a web page or web site that can be embedded into the agent experience using an iframe.
Context cards are available in two sizes: standard and XL.
Standard size context cards
Standard size context cards are loaded in the right-side panel of the agent’s workspace in My Work. By default, standard size context cards are not expanded. Agents can open the context card by clicking on the context card’s title to expand it.
To ensure the best display in the context card, design the content in your app with a maximum size of 425 x 500.
XL size context cards
XL size context cards are loaded in a separate panel in the agent’s workspace in My Work. By default, XL context cards are expanded when the conversation is loaded. Agents only see one XL card, even if multiple are installed. Not all Infobip accounts are configured to support XL cards, so please reach out to us if you plan to use this setup.
The area available to the XL card changes based on the screen available, so responsive UI displays best. If the user has a screen less than 750px wide, the XL card is not visible.
Creating the context card UI and functionality
Your context card UI can be created however you like. There is some information available from Infobip that can help tailor the user’s experience.
On page load, Conversations loads your UI, and include the Conversations ID as a query parameter in the referrer header.
You can use this data to get more information about the Conversation using the Conversations API (opens in a new tab). To use Infobip APIs on behalf of the customer, you need to complete the OAuth 2.0 flow.
Example header content:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"referer": "https://portal.infobip.com/conversations/my-work?conversationId=1f073950-5c7f-417e-990d-ae0efd8af797",
"sec-ch-ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "iframe",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "cross-site",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"x-forwarded-for": "89.164.98.239",
"x-forwarded-host": "appendpoint.free.beeceptor.com",
"x-forwarded-proto": "https"
}
The following table shows the features commonly used on Context cards:
Action | Source |
---|---|
Get customer’s account key | OAuth 2.0 |
Get user’s email | OAuth 2.0 |
Get user’s preferred language | OAuth 2.0 |
Get Infobip token to use in API calls | OAuth 2.0 |
Get customer’s channel | Conversations API: get Messages (opens in a new tab) |
Get customer phone or email address | Conversations API: get Messages (opens in a new tab) |
Get conversation messages | Conversations API: get Messages (opens in a new tab) |
Send message in conversation | Conversations API: create Message (opens in a new tab) |
Create note | Conversations API: create Note (opens in a new tab) |
Get customer information | People API: get Person (opens in a new tab) |
Update customer information | People API: update Person (opens in a new tab) |
Create a new customer | People API: create Person (opens in a new tab) |
Create an event to a customer | People API: create Event (opens in a new tab) |
Full page UI
Conversations full page apps allow you to show custom information to contact center agents and supervisors on a separate area within Conversations. Your full page UI should be a web page or web site that can be embedded using an iframe. There are no limitations on the size of the content for this app, but we recommend creating the UI in a responsive way so that it displays correctly on a variety of screen sizes, including mobile.
Your full page UI can be created however you like. There is some information available to your UI from Infobip that can help tailor the user’s experience.
On page load, Conversations loads your UI. As this experience isn’t tied to a specific conversation, the referrer does not include a Conversations ID. To get information about the customer’s account, use Infobip APIs on behalf of the customer, you need to complete the OAuth 2.0 flow.
The following table shows the features commonly used on full page apps:
Action | Source |
---|---|
Get customer’s account key | OAuth 2.0 |
Get user’s email | OAuth 2.0 |
Get user’s preferred language | OAuth 2.0 |
Get Infobip token to use in API calls | OAuth 2.0 |
Get agents | Conversations API: get Agents (opens in a new tab) |
Get Queues | Conversations API: get Queues (opens in a new tab) |
Update working hours | Conversations API: update Working Hours (opens in a new tab) |
Get Conversation routing information | Conversations API: get Routing (opens in a new tab) |
Get customer information | People API: get Person (opens in a new tab) |
Get list of tags | People API: get Tags (opens in a new tab) |
Add a tag to a batch of people | People API: add Tag (opens in a new tab) |
Answers
The following core functionality can be developed for Answers:
- API connection to Answers
- Passing variables to your API
- Designer experience
- Account level variables
- Arrays and complex data lists
- Webhooks
Setting up the API to connect Answers
Answers connects to your app via an API call. It can call your API directly or through a middleware. Direct connections can be a quick way to create your app, however there are some limitations. Depending on the needs of your API and the experience you want to offer to users, you may need or want to develop middleware to translate the call from Answers into the call format needed for your API. Once your API is ready, update the Manifest to connect Answers to your API.
Passing variables to your API
Answers can send chatbot variables to your API in two ways: query and path parameters. Header parameters are not currently supported. If your API requires that variables be sent using a header, you must use a middleware API to translate the call from Answers into the correct format for your API.
Note: We do not recommend this option for information like platform credentials, tokens, etc as data set in bot attributes are not stored securely.
Answers Designer experience
When setting and receiving variables in the API call, Answers uses values set in bot Attributes by the Answers Designer. If the Answers Designer is unlikely to know how to populate a specific variable as an attribute, we recommend having the integration manager define the variable in the Configuration page, and use a middleware to combine the attributes set in the bot with the variables set in the configuration page.
Account level variables
If some variables are always the same for a specific account (such as account credentials), we recommend having the integration manager define the variable in the Configuration page, and use a middleware to combine the attributes set in the bot with the variables set in the configuration page.
Arrays and complex data types
Arrays are stored as a List in Answers. At this time, there isn’t a way to map a variable-length array response from your API directly to a List. We recommend returning the array to a JSON or Text attribute, then requiring the Answers Designer to parse the response to a List using a Code Block.
Handling webhooks
If the chatbot needs to wait for a change in state in your app, you need to manage this in your API or middleware. The Answers Designer can create a webhook for the bot instance as part of their bot setup. If the Answers Designer assigns the sessionId to an attribute using a Code Block, it can be sent to your API. Then your app can continue the bot by calling the webhook at https://api.infobip.com/bots/webhook/\{\{sessionId\}\} (opens in a new tab).
Moments - Flow
The following core functionality can be developed for Moments - Flow:
- API connection to Flow
- Passing variables to your API
Setting up the API to connect Flow
Flow connects to your app via an API call. It can call your API directly or through middleware.
Direct connections are a quick way to create your app, however there are some limitations.
Depending on the needs of your API and the experience you want to offer to users, you may need or want to develop middleware to translate the call from Flow into the call format needed for your API. Once your API is ready, update the Manifest to connect Flow to your API.
Passing Flow variables and People attributes to your API
You can send variables to your API in the following ways:
- path and query - also known as the URL parameters
- body
- headers - only supported in Flow
Handling authorization tokens
If your API requires authorization tokens, and especially if they expire, you need to manage the token lifecycle within your API or middleware.
Creating a configuration page and settings DB
In this optional step, you’ll set up the configuration page UI and any supporting database and API connections needed. We recommend using a configuration page for the best user experience when your API requires account level information or you have additional settings that is used by your middleware, or if you would like to have more information available to the person who sets up your app for use. The configuration page can also be used to help with the onboarding process, offering access to templates and additional documentation users need to best use your app. You can store any settings defined by the Integrations Manager in a settings database, and use your middleware to insert the appropriate calls into your API endpoint call.
Configuration page UI
Configuration pages allow integration managers to define settings that can apply to any usage of the app. Integrations managers can access this page through the My Apps section of Exchange. Your configuration page UI should be a web page or web site that can be embedded using an iframe. There are no limitations on the size of the content for this page, but we recommend creating the UI in a responsive way so that it displays correctly on a variety of screen sizes, including mobile. This page is defined in the App shell by populating the Settings URL field.
Your configuration page UI can be created however you like. There is some information available to your UI from Infobip that can help tailor the user’s experience.
On page load, Exchange loads your UI. To get information about the customer’s account, use Infobip APIs on behalf of the customer, you need to complete the OAuth 2.0 flow. Some features commonly used on the configuration page:
Action | Source |
---|---|
Get customer’s account key | OAuth 2.0 |
Get user’s email | OAuth 2.0 |
Get user’s preferred language | OAuth 2.0 |
Get Infobip token to use in API calls | OAuth 2.0 |
You can point to the location of page in the Settings URL when publishing your app, or select the Edit option on your app to change this location.
When you have entered a settings page URL for your app, your app three-dot menu also shows a Configure option.
To open the settings page so that you can see the app settings, select Configure.
Update the manifest
The manifest is the interface between your app and Infobip. The manifest contains all the information that Infobip needs to display and use your app.
Manifests can be in either JSON or YAML format. The full structure of the manifest depends on whether you are building an app for Conversations, Answers, or Moments.
Conversations
A Conversations manifest includes dictionaries for each entry point that the app supports. Currently each app can support one context card and full-page app.
The Conversations manifest contains the following key-value pairs for context card.
Card Key | Card Value description |
card | The integration point type for context card. |
title | The name of the app that is displayed to the user. This is a required field. The default example is My App Name. |
src | The URL of the page that is inserted into the iframe in Conversations. HTTPS links are strongly recommended. This is a required field. The default example is https://awesome.app.com/context-card (opens in a new tab) . |
size | The size of the context card in the Conversations right-side panel. The default is standard.· standard: context card is shown along with other cards· XL: the context card is shown on its own and spans the whole height of the screen |
The Conversations manifest contains the following key-value pairs for a full page app.
Page Key | Page Value description |
page | The integration point type for full-page. |
title | The name of the app that is displayed to the user. This is a required field. The default example is My App Name. |
src | The URL of the page that is inserted into the iframe in Conversations. HTTPS links are strongly recommended. This is a required field. The default example is https://awesome.app.com/context-card (opens in a new tab). |
path | The path where the integration is presented. The path should start with "/". For example, /my-app |
This is an example YAML manifest for Conversations:
card:
title: My App Name
src: https://awesome.app.com/context-card
This is an example JSON manifest for Conversations:
{
"page": {
"title": "My full-page app",
"src": "https://awesome.app.com/fullpage-source",
"path": "/documents/my-app"
}
}
This is an example YAML manifest for Conversations using both entry points:
card:
title: My Super Context Card
src: https://awesome.app.com/context-card
page:
title: My Super Full-Page App
src: https://awesome.app.com/fullpage
Answers
You can choose one of the following layout types when creating your manifest for Answers:
- Verbose layout: defining the full structure of the functions used in your api call, including input and output fields
- Simplified layout: specifying an endpoint in the manifest that returns the full function details
Each of the manifest layouts are outlined below.
The Answers manifest may contain some or all of the following key-value pairs.
Key | Value description |
functions | Define a list of all available functions in this dictionary. |
name | The name of the function (default is My Order App). This value is shown to the chatbot editor. Each app can have multiple functions. |
method | Defines how to call your function. The accepted methods are GET, POST, DELETE, POST, and PATCH. |
description | Use this field to describe what the function does. For example, this function retrieves order details by Order ID. This description is shown to the chatbot editor. |
uri | This is the endpoint the chatbot calls to execute the function. For example,https://my-shopping-app.com/app/8/invoke/getOrderDetails (opens in a new tab) . |
inSchema | Defines the variables that are inputs to your function request, including variable type, customer readable descriptions, variable names and whether the variable is required. type: The type, for example, object. required: Lists the properties that are required. These are the properties that you describe in the properties field. properties: A list of each property that could be passed to your endpoint call. You can define multiple properties. property_name: The name of any input property used in the endpoint request, for example, a property name like order_id. type: The type of property. The possible values are: string, number. title: A UI-friendly name of the input property. This property title is displayed to the chatbot editor. example: Provides example values for the property. This is used to show the user how this information will look. |
outSchema | Defines the variables that are outputs from your function response, including variable type, customer readable descriptions and variable names. type: The type, for example, object. required: Lists the properties that are required. These are the properties that you describe in the properties field. properties: A list of each property that could be returned in your endpoint response. You can define multiple properties. property_name: The name of any output property used in the endpoint request. type: The type of property, for example, integer or string. title: A UI-friendly name of the input property. This property title is displayed to the chatbot editor. default: The default value of the property. For integer types, the default is 0. For string types, the default is ''. example: Provides example values for the property. This is used to show the user how this information will look. pattern: The expected schema pattern. The default is ^(.*)$ |
Making changes to the manifest
Take care when updating your manifest after users have implemented your integration. Adding optional variables to your inSchema and outSchema are likely to have minimal impact, but adding required variables to the inSchema may break users in production. If you need to make significant changes to your manifest, contact Infobip to help migrate customers to a new version of your manifest.
Query parameters and path parameters
The Answers manifest gives you the ability to add supporting query parameters and path parameters. This means that you can include chatbot attributes as parameters within your function. To use chatbot attributes within your functions, you surround the attribute with curly braces { }.
For example, a function that calls the endpoint:
https://my-shoping-app.com/app/8/invoke/getOrderDetails (opens in a new tab)
If you obtain the "orderId" from your chatbot, the uri value in your manifest becomes:
https://my-shoping-app.com/app/8/invoke/getOrderDetails/{orderId} (opens in a new tab)
Another example of using query parameters is:
https://my-shoping-app.com/app/orders?limit={limit} (opens in a new tab)
You do not need to include the parameters as inSchema properties.
When using the bot block within Answers, you can choose the value of each of the defined parameters.
Verbose manifest layout
Use this layout if the overall structure for your app does not change from user to user, and you don't anticipate the endpoints or function schemas changing frequently.
To define your manifest, you'll specify each function that your app uses, its endpoint, and all input and output fields that the function uses.
This is an example YAML verbose manifest for Answers:
functions:
- name: getOrderDetails
method: GET
description: Gets Order details by Order ID
uri: https://my-shoping-app.com/app/8/invoke/getOrderDetails
inSchema:
type: object
required:
- order_id
properties:
order_id:
type: number
title: Order ID
outSchema:
type: object
title: The Items Schema
required:
- id
- email
properties:
id:
type: integer
title: The Id schema
default: 0
examples:
- 450789469
email:
type: string
title: The Email Schema
default: ''
examples:
- [email protected]
pattern: ^(.*)$
This is an example JSON verbose manifest for Answers:
{
"functions": [
{
"name": "getOrderDetails",
"method": "GET",
"description": "Gets Order details by Order ID",
"uri": "https://my-shoping-app.com/app/8/invoke/getOrderDetails",
"inSchema": {
"type": "object",
"required": [
"order_id"
],
"properties": {
"order_id": {
"type": "number",
"title": "Order ID"
}
}
},
"outSchema": {
"type": "object",
"title": "The Items Schema",
"required": [
"id",
"email"
],
"properties": {
"id": {
"type": "integer",
"title": "The Id schema",
"default": 0,
"examples": [
450789469
]
},
"email": {
"type": "string",
"title": "The Email Schema",
"default": "",
"examples": [
"[email protected]"
],
"pattern": "^(.*)$"
}
}
}
}
]
}
This is an example YAML verbose manifest for Answers with two functions: getOrderDetails and getShippingDetails.
functions:
- name: getOrderDetails
method: GET
description: Gets Order details by Order ID
uri: https://my-shoping-app.com/app/8/invoke/getOrderDetails
inSchema:
type: object
required:
- order_id
properties:
order_id:
type: number
title: Order ID
outSchema:
type: object
title: The Items Schema
required:
- id
- email
properties:
id:
type: integer
title: The Id schema
default: 0
examples:
- 450789469
email:
type: string
title: The Email Schema
default: ''
examples:
- [email protected]
pattern: ^(.*)$
- name: getShippingDetails
method: POST
description: Get shipping details based on an input order id.
uri: https://awesome.app.com/getShippingDetails
inSchema:
type: object
required:
- orderId
properties:
orderId:
type: number
title: Order ID
outSchema:
type: object
properties:
shippingStatus:
type: string
title: Order status
trackingNumber:
type: number
title: Number of items in order
expectedDeliveryDate:
type: string
title: Expected delivery date
Simplified manifest layout
Use this layout if you plan to use different endpoints based on the logged-in user. Answers queries this endpoint to get the list of functions and their inputs and outputs.
This is an example of a YAML simplified manifest:
uri: https://awesome.app.com/getFunctions
This is an example of a JSON simplified manifest:
{"url": "https://awesome.app.com/getFunctions"
}
Moments - Flow
A Moments - Flow manifest includes the functions that define Flow elements in the Flow editor. A Moments – Flow manifest consists of the parameters that build an element and define how it is rendered in the Flow.
The Moments - Flow manifest consists of the following main sections:
- Functions - define any procedure that can be executed on a third-party service
- Action - every action defines an element in Flow and it will execute some function when the flow is started
- Render - defines the list of input fields used by an action and which specifics how the user sees the function in the Flow editor
Functions
The following table describes the function fields and examples from the default manifest in Exchange.
Both inSchema and outSchema support the https://json-schema.org/ (opens in a new tab) standard.
Field | Field description | Example |
---|---|---|
name | Defines the name of the function as the function identifier. Each app can have multiple functions. This is the function that will be executed when the flow element is processed. When you define an action, make sure that the action name has a corresponding function with the same name. For every render option that has the field model set, there needs to be defined a function with the same name as the model. This is the function that will be executed when the predefined values for this field are fetched. | { "functions": [ { "name": "Create reservation", ... } ] } |
method | Defines how to call your function. The valid methods are GET, POST, DELETE, POST, and PATCH. | { "functions": [ { "name": "Create reservation", "method": "POST", ... } ] } |
description | Use this field to describe what the function does.This description is shown to the user as the function definition in the Flow editor. | { "functions": [ { "name": "Create reservation", "method": "POST", "description": "Creates a reservation", ... } ] } |
uri | This is the endpoint call to execute the function. This endpoint is used by Exchange when executing the function. | { "functions": [ { "name": "Create reservation", "method": "POST", "description": "Creates a reservation", "uri": "https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations (opens in a new tab)", ... } ] } |
Optionally, you can add supporting query parameters and path parameters. This allows you to include attributes as parameters within your function. To use attributes within your functions, you surround the attribute with curly braces { }. For example, a function that calls the endpoint:https://api.example.com/\{path1\}/v1?query1=\{query1 (opens in a new tab)} Map parameters to the properties in inSchema, for example, the query parameter query1={query1} maps to the property as: "_query1": { | ..."uri": "https://api.example.com/\{path1\}/v1?query1=\{query1 (opens in a new tab)}", "inSchema": { | |
inSchema | Defines the input parameters to a function, including variable type, customer readable descriptions, variable names and whether the variable is required. inSchema must include the following parameters:
| ... "inSchema": { "type": "object", "properties": { "host_name": { "type": "string", "title": "Host's Name" }, "host_email": { "type": "string", "title": "Host's email" }, "date": { "type": "string", "title": "Reservation date" } }, "required": [ "date", "host_name" ] }, |
outSchema | Defines the output parameters from your function response, including variable type, customer readable descriptions and variable names. outSchema must include the following parameters:
| ... "outSchema": { "type": "object", "properties": { "id": { "type": "string", "title": "Reservation ID" }, "host_name": { "type": "string", "title": "Host's Name" }, "host_email": { "type": "string", "title": "Host's email" }, "date": { "type": "string", "title": "Reservation date" }, "status": { "path": "statusCode" "type": "string", "title": "Reservation status" }, } |
Example using type array: A map of properties should include two properties to identify which values will be used for SelectView (dropdown) field as Option Name and Option ID.
| ... |
Actions
The following table describes the actions fields and examples from the default manifest in Exchange.
Actions are only used in Moments - Flow manifests and are not supported in manifests for other products.
Field | Field description | Example |
---|---|---|
name | Defines the name for the action. This is a string. Every action must have a corresponding function with the same name. For example, if you define an action in the manifest, which will correspond with the function called getActionOne, then you must define the action name also as getActionOne.There can be many functions related to one action but there must be one function that has the same name as the action. | { ... "actions": [ { "name": "Delete reservation", ... } ] }
|
render | Defines the list of input fields used by the action. These input fields are used to define how to user sees the the function in the Flow editor.Each input field must specify the following:
| { ... "actions": [ { "name": "Create reservation", "render": [ { "field": "host_name", "viewClass": "TextFieldView", "personalization": true, "dependencies": [] } ... ] ... }, { "name": "Delete reservation", "render": [ { "field": "_id", "viewClass": "SelectView", "model": "Get all reservations", "personalization": false, "dependencies": [] } ... ] } ] }
|
Example Manifest
The following is an example JSON manifest for Moments Flow. This manifest represents a working integration with a demo application to manage imaginary restaurant reservations.
Go to the demo application at the following link: https://restaurant-reservations-demo.azurewebsites.net/ (opens in a new tab)
The demo application is published on Github: https://github.com/infobip-community/restaurant-reservations-demo (opens in a new tab)
You may use this manifest and test how integration works with the app from your Infobip account.
The app is used only as an example representation of an Exchange integration and to show the manifest capabilities. Do not use the demo application in any production scenarios and do not share personal data with the application.
{
"icon": "https://cdn-web.infobip.com/uploads/2023/01/Infobip-logo.svg",
"functions": [
{
"name": "Get all reservations",
"description": "Get all reservations",
"method": "GET",
"uri": "https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations",
"inSchema": {},
"outSchema": {
"type": "object",
"properties": {
"_id": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Reservation ID"
},
"host_name": {
"type": "string",
"title": "Host's Name"
},
"host_email": {
"type": "string",
"title": "Host's email"
},
"date": {
"type": "string",
"title": "Reservation date"
},
"hour": {
"type": "string",
"title": "Reservation time"
},
"party_size": {
"type": "number",
"title": "Number of participants"
}
}
}
],
"selectViewOptionIdPath": "$.reservations[*].id",
"selectViewOptionNamePath": "$.reservations[*].host_email"
}
}
}
},
{
"name": "Create reservation",
"description": "Creates a reservation",
"method": "POST",
"uri": "https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations",
"inSchema": {
"type": "object",
"properties": {
"host_name": {
"type": "string",
"title": "Host's Name"
},
"host_email": {
"type": "string",
"title": "Host's email"
},
"date": {
"type": "string",
"title": "Reservation date"
},
"hour": {
"type": "string",
"title": "Reservation time"
},
"party_size": {
"type": "number",
"title": "Number of participants"
}
},
"required": [
"date",
"host_name",
"host_email",
"hour",
"party_size"
]
},
"outSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Reservation ID"
},
"host_name": {
"type": "string",
"title": "Host's Name"
},
"host_email": {
"type": "string",
"title": "Host's email"
},
"date": {
"type": "string",
"title": "Reservation date"
},
"hour": {
"type": "string",
"title": "Reservation time"
},
"party_size": {
"type": "number",
"title": "Number of participants"
}
}
}
},
{
"name": "Update reservation",
"description": "Updates a reservation",
"method": "PUT",
"uri": "https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations/{id}",
"inSchema": {
"type": "object",
"properties": {
"_id": {
"type": "string",
"title": "Reservation ID"
},
"host_name": {
"type": "string",
"title": "Host's Name"
},
"host_email": {
"type": "string",
"title": "Host's email"
},
"date": {
"type": "string",
"title": "Reservation date"
},
"hour": {
"type": "string",
"title": "Reservation time"
},
"party_size": {
"type": "number",
"title": "Number of participants"
}
},
"required": ["_id"]
},
"outSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Reservation ID"
},
"host_email": {
"type": "string",
"title": "Host Email"
},
"host_name": {
"type": "string",
"title": "Host Name"
},
"hour": {
"type": "string",
"title": "Hour"
},
"date": {
"type": "string",
"title": "Date"
},
"party_size": {
"type": "number",
"title": "Party Size"
}
}
}
},
{
"name": "Delete reservation",
"description": "Deletes a reservation",
"method": "DELETE",
"uri": "https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations/{id}",
"inSchema": {
"type": "object",
"properties": {
"_id": {
"type": "string",
"title": "Reservation ID"
}
},
"required": ["_id"]
},
"outSchema": {}
}
],
"actions": [
{
"name": "Create reservation",
"render": [
{
"field": "host_name",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "host_email",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "date",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "hour",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "party_size",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
}
],
"async": false
},
{
"name": "Update reservation",
"render": [
{
"field": "_id",
"viewClass": "SelectView",
"model": "Get all reservations",
"personalization": false,
"dependencies": []
},
{
"field": "host_name",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "host_email",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "date",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "hour",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
},
{
"field": "party_size",
"viewClass": "TextFieldView",
"personalization": true,
"dependencies": []
}
],
"async": false
},
{
"name": "Delete reservation",
"render": [
{
"field": "_id",
"viewClass": "SelectView",
"model": "Get all reservations",
"personalization": false,
"dependencies": []
}
],
"async": false
}
],
"triggers": []
API request example
The following is an example of an API request. Exchange calls the defined uri with the data provided in this format.
The example show the raw body for function the "Creation reservation" https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations (opens in a new tab).
{
"host_email": "[email protected]",
"host_name": "Test",
"hour": "11:00",
"date": "2/15/2024",
"party_size": "2"
}
API response example
The following is an examples of an API response. Exchange expects the function to return data in this format for the manifest configuration.
The example shows the response for the function "Get all reservations" https://restaurant-reservations-demo.azurewebsites.net/exchange/restaurant/reservations (opens in a new tab).
{
"reservations": [
{
"host_email": "[email protected]",
"host_name": "Test",
"hour": "15:30",
"date": "2/14/2024",
"party_size": "2",
"additionalFields": [],
"id": "fde30afb-f563-40b1-aa6c-d8106e3f278d"
},
{
"host_email": "[email protected]",
"host_name": "Bob",
"hour": "11:00",
"date": "2/15/2024",
"party_size": "2",
"additionalFields": [],
"id": "c96734da-1f1c-4aba-8129-5c3e9848ba14"
}
]
}
Model
If a function corresponds to a model for an input field, then its inSchema properties can be any from the list except array, and its outSchema properties should be array. In the outSchema, the name of the property should match the name of the field in the render option. Also, in inSchema, property names should match the field names from the render options that this field depends upon. The following is an example of the manifest.
The field definition for render in the actions (fields field3 , field4 and field5 are defined in the same list as field6 ):
{
"field": "field6",
"viewClass": "SelectView",
"model": "ref6",
"dependencies": [
"field3",
"field4",
"field5"
],
"personalization": false
}
The function definition for the model of the field:
{
"name": "ref6",
"description": "",
"method": "GET",
"uri": "some uri",
"inSchema": {
"properties": {
"field3": {
"type": "string",
"title": "field3"
},
"field4": {
"type": "string",
"title": "field4"
},
"field5": {
"type": "string",
"title": "field5"
}
}
},
"outSchema": {
"properties": {
"field6": {
"type": "array",
"title": "field6"
}
}
}
}
The format for the values from array is:
[
{
"id": "value1",
"name": "Value 1"
},
{
"id": "value2",
"name": "Value 2"
}
]
This is a list of objects with the fields id (used during processing) and name (shown in the drop-down menu).
Dependencies
The dependencies field for the render options has a number of use cases. This example demonstrates how it works:
Select continent, and once you select the continent another select field appears which allows you to select a country, and once you select a country a third select field appears to select a city.
In this example, field0 is TextFieldView, and the other fields are SelectView. The dependencies are:
- field1 has no dependencies
- field2 depends on field1
- field3 depends on field1 and field2
- field4 depends on field3
- field5 depends on field3 and field4
- field6 depends on field3 , field4 and field5
The order in which the fields are resolved is numerical, from field1 to field6.
This is the state at the beginning:
If you choose a value for field1, the field2 gets its predefined values and becomes unlocked.
Choose the values for the next fields.
If you change the value of field2 , all the fields that transitively but not directly depend on it are erased and disabled, in this example field4 . Fields that directly depend on it are also be erased, but new predefined values are fetched and the fields are disabled, as they can be resolved. In this example field3 .
Making changes to the manifest
Take care when updating your manifest after users have implemented your integration. Adding optional variables to your inSchema and outSchema are likely to have minimal impact, but adding required variables to the inSchema may break users in production. If you need to make significant changes to your manifest, contact Infobip to help migrate customers to a new version of your manifest.
Tips for testing
To test your app, first ensure that you have access to and are familiar with the Infobip product. Depending on the communication channel you’d like to use, you may need to configure senders/numbers.
It’s recommended to create a simple app first, then start to layer on more complex experiences like managing additional variables, page navigation and OAuth.
See the Troubleshooting section for common issues.
Testing Answers chatbots
For Answers apps, we recommend setting up a bot outlining the full experience, to ensure all pieces are connected properly. You can also export the chatbot and provide it to customers to use as a template for their own chatbots.
Testing Moments - Flow elements
For Moments - Flow elements, we recommend setting up a flow outlining the full customer journey to ensure all pieces are connected properly. You can also save the flow as a template to use again.
For more information about using the Flow editor and managing a flow, see Manage flow.