Connect an external Plugin

get.chat provides to you ready to use Plugins. See Integrations section for a list of available Plugins.

If you want to create your own Plugin, or you want to connect to an external plugin developed by a third party, see the guide below.

Overview

get.chat provides an HTTP API Endpoint to connect your Inbox to external plugins.

To integrate/connect an external plugin, please follow the below steps:

  • Login to the get.chat Inbox Admin panel

  • On the sidebar, click on Plugins

  • Click the Connect an external plugin button

  • Enter a name for the plugin

  • Enter the Plugin server url. This is the public url of your plugin server. E.g https://my-awesome-plugin.com

  • Click on Save.

The plugin server must expose the below endpoints:

  • “/”

  • “/features”

  • “/initialize”

If the plugin is a contact provider, the plugin server must expose the below endpoints:

  • “/contacts/”

  • “/contacts/{contact_id}”

If the plugin is a message sender or reciever, the plugin server must expose the below endpoints:

  • “/webhook”

  • “/configure_api”

Endpoints

GET “/”

The endpoint must return the name and type of your plugin.

Parameters:

Name

Type

name

String

Mandatory

type

String

Mandatory

Example implemented in Python:

    @routes.get('/')
    async def index(request: web.Request):
        resp = {"name": "Demo", "type": "demo"}
        return web.json_response(resp)

GET “/features”

This endpoint defines the features of the Plugin.

Parameters:

Name

Type

is_contact_provider

Boolean

Mandatory

is_message_reciever

Boolean

Mandatory

is_message_sender

Boolean

Mandatory

There are 3 features:

  • is_contact_provider: return here True if your Plugin is a Contact Provider.

  • is_message_reciever: return here True if your Plugin is able to receive messages from the Inbox or via Webhook.

  • is_message_sender: return here True if your Plugin is able to send messages to the Inbox or via Webhook.

Example implemented in Python:

    @routes.get('/features')
    async def features(request: web.Request):
        resp = {"is_contact_provider": True}
        return web.json_response(resp)

GET “/initialize”

This endpoint is called on plugin initialization.

Parameters:

Name

Type

status

String

Mandatory

error_message

String

Mandatory

method

String

Mandatory

external_url

String

Mandatory

The inbox expects a response as follows:

  • In case everything goes well, the response should be:

    {"status": "initialized"}
  • In case it doesn’t go well:

    {
        "status": "init_failed",
        "error_message": "YOUR ERROR MESSAGE"
    }
  • In case authorization is needed:

    {
        "status": "authorization_needed",
        "authorization_needed": {
            "method": "external_url",
            "external_url": "YOUR URL TO USER AUTHORIZATION PROCESS"
        }
    }

Example implemented in Python:

    @routes.get("/initialize")
    async def initialize(request: web.Request):
        resp = {"status": "initialized"}
        return web.json_response(resp)

GET “/contacts/”

This endpoint lists all contacts. It offers pagination of the contacts and limits. It also supports search in the contacts.

Parameters:

Name

Type

results

Array

Mandatory

name

String

Mandatory

contact_id

String

Mandatory

avatar

String

Mandatory

large_avatar

String

Mandatory

companies

String

Mandatory

phone_numbers

String

Mandatory

email_addresses

String

Mandatory

urls

String

Mandatory

count

Number (integer)

Mandatory

next_page_param

String

Mandatory

contact_provider

Object

Mandatory

Example implemented in Python:

    @routes.get("/contacts/")
    async def contacts(request: web.Request):
        resp = {
            "results": [
                {
                    "contact_id": "1",
                    "name": "Demo",
                    "avatar": None,
                    "large_avatar": None,
                    "companies": [{"company_name": "Demo Corp", "job_title": "CEO"}],
                    "phone_numbers": [{"phone_number": "1234567898", "description": "phone number"}],
                    "email_addresses": [{"email_address": "a@example.com", "description": "email"}],
                    "urls": [{"url": "www.example,com", "description": "url"}],
                }
            ],
            "count": 1,
            "next_page_param": "",
            "contact_provider": {}
        }
        return web.json_response(resp)

Note: All parameters listed in the above example are required to be sent in the response payload.

GET “/contacts/{contact_id}”

This endpoint is used by the Contact Provider to resolve contact details. It returns the contact details of the specified contact.

Parameters:

Name

Type

results

Array

Mandatory

name

String

Mandatory

contact_id

String

Mandatory

avatar

String

Mandatory

large_avatar

String

Mandatory

companies

String

Mandatory

phone_numbers

String

Mandatory

email_addresses

String

Mandatory

urls

String

Mandatory

count

Number (integer)

Mandatory

next_page_param

String

Mandatory

contact_provider

Object

Mandatory

Example implemented in Python:

    @routes.get("/contacts/")
    async def contacts(request: web.Request):
        resp = {
            "results": [
                {
                    "contact_id": "1",
                    "name": "Test",
                    "avatar": None,
                    "large_avatar": None,
                    "companies": [{"company_name": "Zoey Corp", "job_title": "CEO"}],
                    "phone_numbers": [{"phone_number": "1234567898", "description": "phone number"}],
                    "email_addresses": [{"email_address": "a@example.com", "description": "email"}],
                    "urls": [{"url": "www.example,com", "description": "url"}],
                }
            ],
            "count": 1,
            "next_page_param": "",
            "contact_provider": {}
        }
        return web.json_response(resp)

Note: All parameters listed in the above example are required to be sent in the response payload.

POST “/webhook”

This endpoint is used for our WABA webhooks for receiving events. It is used when we receive events from the Inbox. You can subscribe to different events.

From WhatsApp Integration API, correctly configured WABA Webhook will propagate webhooks incoming from WABA to each of your endpoints. Propagated webhook call will be exactly the same POST call as the original WhatsApp Business API webhook.

POST “/configure_api”

The api_url and api_token are passed to this endpoint.

Parameters:

Name

Type

api_url

String

Mandatory

api_token

String

Mandatory

  • param: api_url -> Base URL to Integration API. ‘None’ if you are not allowed to access the API

  • param: api_token -> API KEY you need to use with the “Authorization: Token” header. ‘None’ if you are not allowed to access the API.

  • return: None

Example Payload:

{
    "api_url": "some url",
    "api_token": "some token",
}

POST “/public/webhook/”

Receives and responds to whatever is needed.

External Plugin implementation example

Below is an example of a simple contact provider written in Python using AIOHttp library:

    from aiohttp import web

    routes = web.RouteTableDef()

    @routes.get("/contacts/{contact_id}")
    async def contact(request: web.Request):
        resp = {
            "results": [
                {
                    "contact_id": "1990",
                    "name": "Demo",
                    "avatar": None,
                    "large_avatar": None,
                    "companies": [{"company_name": "Demo Corp", "job_title": "CEO"}],
                    "phone_numbers": [{"phone_number": "123456789", "description": "phone number"}],
                    "email_addresses": [{"email_address": "a@example.com", "description": "email"}],
                    "urls": [{"url": "www.example,com", "description": "url"}],
                }
            ],
            "count": 1,
            "next_page_param": "",
            "contact_provider": {}
        }
        return web.json_response(resp)

    @routes.get("/contacts/")
    async def contacts(request: web.Request):
        resp = {
            "results": [
                {
                    "contact_id": "1990",
                    "name": "Demo",
                    "avatar": None,
                    "large_avatar": None,
                    "companies": [{"company_name": "Demo Corp", "job_title": "CEO"}],
                    "phone_numbers": [{"phone_number": "123456789", "description": "phone number"}],
                    "email_addresses": [{"email_address": "a@example.com", "description": "email"}],
                    "urls": [{"url": "www.example,com", "description": "url"}],
                }
            ],
            "count": 1,
            "next_page_param": "",
            "contact_provider": {}
        }
        return web.json_response(resp)

    @routes.get("/initialize")
    async def initialize(request: web.Request):
        resp = {"status": "initialized"}
        return web.json_response(resp)

    @routes.get('/')
    async def index(request: web.Request):
        resp = {"name": "Demo", "type": "demo"}
        return web.json_response(resp)

    @routes.get('/features')
    async def features(request: web.Request):
        resp = {"is_contact_provider": True}
        return web.json_response(resp)


    if __name__ == '__main__':
        app = web.Application()
        app.add_routes(routes)
        web.run_app(app)