Search code examples
herokutwiliowebhooksphone-number

How can I get Twilio webhooks to work with Heroku?


Hi I am using Twilio to send text messages to several phone numbers.

When the user gets the text message from my React.js application, I would like them to be able to respond back to that text message and have my application do some processing, then texting back that the processing is completed.

Based on the Twilio web page.

However I keep getting a 404 response.

Here are the details of this issue:

The application is a REACT application running on Heroku

Important stuff from my 'server.js' file

const express = require('express');
const bodyParser = require('body-parser');
const passport = require('passport');
const path = require('path');

const mongoose = require('mongoose');

const sms = require('./routes/api/sms');

const app = express();


// body parser
let size = '50mb';
app.use(bodyParser.urlencoded({limit: size,extended: false}));
app.use(bodyParser.json({limit: size}));


// passport middleware
app.use(passport.initialize());

// passport config file.
// passport uses a strategy
require('./config/passport')(passport);

// use routes

app.use('/api/sms', sms);


// server static assests if in production
if (process.env.NODE_ENV === 'production') {
    // Set static folder
    app.use(express.static('client/build'));

    app.get('*', (req, res) => {
      res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
    });
  }

const serverPort = require('./config/keys').serverPort;

const port = process.env.PORT || serverPort;

app.listen(port, () => console.log(`server running on port ${port}`));

Here is sms.js file contents (the URL that 'should' respond to the web hook call)

router.post('/twiml', (req, res) => {

    let debugThis = true;
    if(debugThis){
        console.log('post api/sms/twiml');
        console.log(req.body);
    }

    const twiml = new MessagingResponse();

    if (req.body.Body == 'hi') {
        twiml.message('Hello!');
      } else if (req.body.Body == 'bye') {
        twiml.message('Goodbye');
      } else {
        twiml.message(
          'No Body param match, Twilio sends this in the request to your server.'
        );
      }

      res.writeHead(200, { 'Content-Type': 'text/xml' });
      res.end(twiml.toString());

});

So I think when I make the call the URL I should be using as a web hook should be configured on my phone number in Twilio like this : ( the missing part from the front is HTTPS:// )

enter image description here

when I text my Twilio number, this is what I get in the log:

2020-01-25T23:53:17.755941+00:00 heroku[router]: at=info method=POST path="/sms/twiml" host=choremonger.herokuapp.com request_id=7d44f910-2850-4282-aa14-08270384e99a fwd="54.198.69.37" dyno=web.1 connect=36ms service=23ms status=404 bytes=393 protocol=https

In other words:

My Twilio number is 555-555-5555 Joe's number is 111-111-1111

I envision the messaging looking like this:

SEND from 555-555-5555 to 111-111-1111 "Is Task A completed"

RC'd on 111-111-1111 "Is Task A completed"

SEND from 111-111-1111 to 555-555-5555 "Yes"

RC'd on 555-555-5555 "Yes"

This is where my application is notified via the web hook that "Yes" was texted.

< some processing occurs and sender's phone number is used to reply >

SEND from 555-555-5555 to 111-111-1111 "Task A is closed"

Update 1

the reason I added this is due to a comment that the web hook URL is incorrect.

When I use 'npm run server' from Visual Studio Code and Postman to check the URL I get this:

server output in Visual Studio

[nodemon] 1.18.10
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node server.js`
server running on port 5000
DB connected
post api/sms/twiml
{ Body: 'hi' }

PostMan URL call:

http://localhost:5000/api/sms/twiml

PostMan body:

{
    "Body" :"hi"
}

PostMan result: Status: 200 OK

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>Hello!</Message>
</Response>

Update 2

When I removed the 'twilml' from the webhook URL in Twilio and texted, I got this:

2020-01-26T18:05:09.862565+00:00 heroku[router]: at=info method=POST path="/sms" host=choremonger.herokuapp.com request_id=8b0d0987-2907-4796-a8b2-d4e6d14e209a fwd="54.208.241.142" dyno=web.1 connect=0ms service=2ms status=404 bytes=387 protocol=https

When I put it back in and texted again, and got this:

2020-01-26T18:06:26.639155+00:00 heroku[router]: at=info method=POST path="/sms/twiml" host=choremonger.herokuapp.com request_id=0af446f3-4432-40fe-b6e6-1b64ecf6608c fwd="3.89.83.196" dyno=web.1 connect=0ms service=3ms status=404 bytes=393 protocol=https

Update 3

I thought it might be due to HTTPS vs HTTP, so I changed the web hook to HTTP and tried again... the request picked up the http change... but same result.

2020-01-27T03:13:51.506124+00:00 heroku[router]: at=info method=POST path="/sms/twiml" host=choremonger.herokuapp.com request_id=539604b1-3b08-47d9-a124-3d2e30596043 fwd="54.166.158.158" dyno=web.1 connect=1ms service=2ms status=404 bytes=393 protocol=http

Update 4

I went to Twilio's debugger and pulled some information... hopefully somebody can help direct me on how to fix this

enter image description here

Phone numbers and SIDS are correct

enter image description here

enter image description here

enter image description here

enter image description here

Thanks !


Solution

  • OK... for all those that are just as new to web programming and REACT as I am...

    THIS is the cause:

    This the line in my server.js file that puts the URL into the world:

    const sms = require('./routes/api/sms');

    I was missing the 'api' from the URL in the Twilio configuration link