/bookbot

Book a class and schedule time with init.ai and actuity

Primary LanguageJavaScript

Init.ai sample logic server

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:

Quickstart

  1. Install dependencies and start development task:

    npm i && npm run dev

    You should see this in your terminal: demo-server

  2. 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.

Scaffold

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.

Server

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.

Logic

Running your logic

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.

Running the server locally

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.

Environment variables

  • 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 an ngrok URL

Exposing localhost

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.

Configuring webhooks

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.

Migrating your logic

Using sendResult

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.

Logic created prior to 5/1/2017

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.

Deployments

Heroku

Deploy

Support

  • 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

Coming soon

PRs for these are welcome!