This repo contains a pre-configured webhook server for use in an Init.ai project. The server can be used to facilitate testing from within the Init.ai console and can also be deployed remotely to handle your production traffic.
Note: When taking your server to production, make sure to customize it to your needs and ensure it is fully tested!
Before getting started, make sure you have:
- An Init.ai account and project (https://console.init.ai)
- Node v6.10 or later (Download)
- Take a look at nvm
-
Install dependencies and start development task:
npm i && npm run dev -
Provide your server's address to the Init.ai console
Note: The
devtask is not supported on Windows. If you are using Windows, see the exposing localhost for instructions.
This application contains a basic server configuration for handling webhooks as well as a boilerplate implementation of the Init.ai Node.js SDK. Out of the box, this application can be deployed to Heroku, but is designed to facilitate local development and testing as well.
The server is written using express.js – you may use any framework you like (or build your own, we respect that too!). Out of the box, it is configured to handle a POST request to the / root endpoint.
The handler for the webhook endpoint will invoke the runLogic function which can be found in the runLogic.js file. This function returns a Promise which will provide the result generated by the Init.ai client.
If you are using existing logic that was previously hosted by Init.ai, you may keep what you have written. See migrating your logic for more.
Sending the result: Prior to version 0.0.14 of the Node.js SDK, it was left to you, the developer to send the result of your logic run to the Init.ai API manually. A
sendResultmethod has since been added which will make this request for you.
To start the server and watch tasks:
$ npm run devThe dev task automatically provisions an ngrok URL to expose localhost and uses nodemon to restart the server as you save changes. The server itself will default to http://localhost:3022.
- PORT - Set this if you wish to use a port other than the default (
3022) - LOCAL - Set this to
falseto skip automatic configuration of anngrokURL
This application can be run on any service you would like and ships completely ready to deploy to Heroku. During development however, it is recommended you make your local machine accessible to external services. We suggest using a tool such as ngrok or localtunnel.
This app contains an ngrok wrapper as a dependency. If you do not have ngrok installed you can run: npm run ngrok to generate a URL which you can provide to the Init.ai console for testing your project.
If you are using Windows, it is recommended that you start the server/watch task using npm run watch and then setup ngrok manually.
Init.ai facilitates both "development" and "production" webhooks. The intention is that the "development" webhook may be used to help you iterate on and test your project from the Init.ai console without having to connect to an external messaging service.
See docs for more.
Prior to version 0.0.14 of the Node.js SDK, it was left to you, the developer to send the result of your logic run to the Init.ai API manually. A sendResult method has since been added which will make this request for you.
If you used the Node.js SDK prior to 0.0.14, you likely used client.done in conjunction with a succeed callback like this:
const client = InitClient.create(data, {succeed: callback})
// In your code elsewhere you would call .done()
client.done()To use the new sendResult method, you should amend your code as follows.
First, remove the configuration object from the create call:
const client = InitClient.create(data)Next, create a done wrapper (so you don't have to call client.sendResult multiple places in your code):
const done = () => client.sendResult()
.then(() => console.log('Success!'))
.catch((err) => console.log('Error', err))sendResult returns a Promise which you can use to handle the success or failure of your logic run.
Now that you have your own done wrapper, you can replace instances of client.done with a call to your done function.
In early versions of the Init.ai platform, logic was hosted on AWS Lambda instances provisioned automatically for each project. As such, certain patterns were applied to our node library and the projects scaffolded by Init.ai. Namely, this included a file located at behavior/scripts/index.js which exported a handle function to which an instantiated client was provided as an arugment:
exports.handle = function (client) {
...
}This pattern still works, however, now you are in charge of provisioning the client instance yourself. To do this from your webhook handler you may replace the Logic.run code block with the following:
const InitClient = require('initai-node')
const logicScript = require('./behavior/scripts')
const axios = require('axios')
const initNodeClient = InitClient.create(data, {
succeed(result) {
// Make a request to the Init.ai API to send the result of the logic run
// Docs: https://docs.init.ai/docs/webhooks#section-logicinvocation
const {
current_application: {id: app_id},
invocation_data: {api: {base_url}, auth_token, invocation_id},
users,
} = data.payload
// TODO: This needs to be v2 when released
const url = `${base_url}/api/v1/remote/logic/invocations/${invocation_id}/result`
const headers = {
'authorization': `Bearer ${auth_token}`,
'content-type': 'application/json',
}
const data = {
invocation: {app_id, app_user_id: Object.keys(users)[0], invocation_id},
result,
}
axios.request({data, headers, method: 'post', url})
.then(() => console.log('Success!'))
.catch((error) => {console.log(new Error(error))})
}
})
logicScript.handle(initNodeClient)Make sure to install the axios library and delete the accompanying runLogic.js file in this case.
- Email [email protected]
- File an issue on this repo (Please limit issues to those related to running this webhook server)
- Join our Slack comunity
PRs for these are welcome!
- now.sh deployment guide
- serverless deployment guide