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
dev
task 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
sendResult
method has since been added which will make this request for you.
To start the server and watch tasks:
$ npm run dev
The 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
false
to skip automatic configuration of anngrok
URL
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 support@init.ai
- 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