TwilioHackathon - Autopilot, Node.js, PostgreSQL
Tags: twiliohackathon, twilio, node, postgres
Published: 2020-04-16 01:20:13

# My journey throught Twilio Hackathon on DEV 2020
This a is post describing my submission for the contest.

## The beginnings
Immediately after I read the post announcing the hackathon, I decided I will participate. I have never taken part in any hackathon before and since there is a whole month to complete this was a perfect opportunity.

I have been playing with a few ideas, but unfortunately I did not come up with any breakthroughts. So, on the 13th of April I took an idea that was on my mind in that particular moment and, having more free time than usual, I started working on my submission.

## What I built
I built a chat bot using Twilio Autopilot, currently integrated with WhatsApp sandbox.

## The user flow
As described [here](https://dev.to/petr7555/comment/nmhn), the idea is pretty simple.
After some formality on the beginning, the chat bot gives you two options.
Either to make a confession or to react to someone else's confession. 
- If you choose to submit a confession, you are prompted to enter some text. Then you are asked to wait until someone reacts to it.
- If you choose to react to a confession, a confession from the server is fetched for you and once you answer it, the person who submitted it is notified with your answer.

Here is what it looks like in action:
1. First person makes a confession.
![making a confession](https://github.com/petr7555/TwilioHackathon/blob/master/img/img_submit_1.jpg?raw=true)
2. Second person reacts to it.
![reacting to confession](https://github.com/petr7555/TwilioHackathon/blob/master/img/img_react_1.jpg?raw=true)
3. First person receives a reaction.
![receiving reaction](https://github.com/petr7555/TwilioHackathon/blob/master/img/img_submit_2.jpg?raw=true)

## Inside logic
The text of confession is stored with unique **id**, together with you **UserIdentifier**, which is in case of WhatsApp your telephone number prepended with `whatsapp:`. There is also a column keeping track of how many times this confession has been reacted upon.

When someone chooses to react to a confession, a row with smallest reaction count is picked and shown to the user. The user types some reaction. Then, because of the **UserIdentifier** that is store along the confession, I am able to send a message via Twilio message client to the user who submitted it. Finally, the counter is incremented.
 
## The stack
Initially, I wanted to stick only with Twilio. Twilio provides Functions, which could be used for some logic, but I needed a database. I thought I could use DigitalOcean and set up some droplet with Node.js and Postgres, but after I have been told that my account was blocked immediately after registration, I have decided to move somewhere else.

I tried Google Firebase Functions and Realtime Database, but I have little understanding of how the Realtime Database works and my SQL approach did not fit well. After trying to get a record from the database for more than hour, I moved once again, for the last time.

I created a Heroku app with Express to process requests and PostgreSQL to store data. From now on, everything went much faster.
There was unfortunately a hiccup with processing the POST request body that I was receiving from Twilio, but setting body-parser solved it.
```javascript
app.use(bodyParser.urlencoded({
    extended: false
}));
```

## Integration
Twilio offers multiple channels for the Autopilot. 
- **Programmable messaging** requires a mobile number. The provided international one does not behave well in my country. The messages are sent to that number, but the response is received from a universal *Info* number.
Currently I am in the middle of process of issuing a Regulatory Bundle, which is required for buying a Czech number.
- Setting **Facebook Messenger** gives me *500 Internal Server Error*. Probably something wrong on Twilio side.
- **WhatsApp** would have to formally approve my account. But, fortunately, Twilio offers a sandbox, which is currently the way I am testing my chat bot.

## How I used Autopilot
Autopilot uses *tasks*. The tasks can be trained by specifying *samples* that trigger them. For example my `make_a_confession` task can be triggered by user saying *'I want to make a confession'*. 
They are programmed what to do when they are triggered. The following JSON tells Autopilot to ask user for input and then make a POST request on the specified uri.
```json
{
	"actions": [
		{
			"collect": {
				"name": "collect_confession",
				"questions": [
					{
						"question": "What is your confession?",
						"name": "confession"
					}
				],
				"on_complete": {
					"redirect": {
						"method": "POST",
						"uri": "https://twilio-hackathon.herokuapp.com/confession"
					}
				}
			}
		}
	]
}
```

## The outcomes
The whole project has been a lot of fun. Twilio platform was intuitive to use, but sometimes I found myself going in circles in their documentation. I think this is something that should be improved.

## Link to Code
The whole backend code is available on GitHub.
{% github petr7555/TwilioHackathon %}