# Connect an external Plugin get.chat provides to you ready to use Plugins. See [Integrations](/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](https://portal.get.chat/wa-integration-api#section/Integration/WABA-Webhook), 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](https://developers.facebook.com/docs/whatsapp/api/webhooks). ### 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) ```