Null isTrue
Null isTrue

Reputation: 1906

Twilio JavaScript - SMS from client to server

I've found docs teaching on how to implement Twilio on server-side using Node, however, I couldn't find an end-end example where I can send a SMS coming from my client app.

Can anyone tell me what the implementation would look like to send a post custom SMS from client to server?

Disclaimer my server file is named as app.js and my client file is named as index.js enter image description here

**1- This is what I have currently setup on my app.js

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

   //JSON DATA
   const guests= require('./public/data/Guests');

    app.use(bodyParser.urlencoded({extended: false}));
    app.use(express.static('public'));

    //SET PORT
    app.set("port", process.env.PORT || 3000);

   //GET JSON DATA
   app.get('/data', function(req, res) {
    Promise.all([guests])//combine requests into one object
        .then(([guests]) => {
            res.send({guests});
        });
});

//CATCHALL
app.get("/*", function(req,res){
    let file = req.params[0] || "/views/index.html";
    res.sendFile(path.join(__dirname, "/public/", file));
});

//LISTEN ON PORT
app.listen(app.get("port"), function(){
    console.log("Listening on port: " , app.get("port"));
});

let client = new twilio('xxxxxxxxxx', 'xxxxxxxxxxxxx');

app.post('/sms', (request, result) => {
    const message = request.body.message;

    client.messages.create({
        to: +1847820802492359,
        from: +8475302725792530 ,
        body: message
    }).then(() => {
        // message sent successfully, redirect to the home page.
        res.redirect('/');
    }).catch((err) => {
        console.error(err);
        res.sendStatus(400);
    });
});

-2 am trying to process a dynamic message in my index.js. The code works on the DOM properly, it is just the SMS with Twilio that isn't posting the message to the server

$(function() {
    $.ajax({
        type: "GET",
        url: "/data",
        success: res => {
            //console.log(res);
            handleMessage(res);
        },
        error: err => console.log(err)
    });

    //message method
    let handleMessage = (res) => {
        const getFirstName = res.guests.map(name => name.firstName);
        //populate drop-down select
        let handleSelect = () => {
            //adds first names to select dropDown
            $.each(getFirstName, function(i, value) {
                $('#selectName').append($('<option>').text(value).attr('value', value));
            });

        };
        handleSelect();

        let handleSubmit = () => {
            $("#form").submit(function(e) {
                e.preventDefault();
                let name = $('#selectName').val();
                let greetGuest = `Welcome ${name}!`;
                console.log(greetGuest);

                //append to Dom
                $('.showMessage').append(`<div class="newMessage"><span>${greetGuest}</span></div>`);

            });
        };
        handleSubmit()
    };
});

-3 HTML form

<form id="form" action="/sms" method="POST">
        <label>
            <label for=selectName>Guest
                <select id="selectName" class="select " name="sms">
                </select>
            </label>
        </label>
        <input type="submit" value="send" class="btn btn-success" />
    </form>

Am I having an asynchronicity issue here?

Upvotes: 1

Views: 569

Answers (1)

philnash
philnash

Reputation: 73029

Twilio developer evangelist here.

I can give you a basic example here, which should give you a good idea of how to achieve this. I'll start with the server side, which you already have the basics of.

Firstly, I would recommend you use a POST request rather than a GET, simply because GETs can be easily repeated by users or cached by proxies. I assume you are using Express as the web application server. You will also need the body-parser module to read the data that we send from the client side.

const Twilio = require('twilio');
const express = require('express');
const bodyParser = require('body-parser');

const app = new express();

app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static('public'));

const twilio = new Twilio(YOUR_ACCOUNT_SID, YOUR_AUTH_TOKEN);

app.post('/messages', (request, result) => {
  const message = request.body.message;

  twilio.messages.create({
    to: TO_NUMBER,
    from: FROM_NUMBER,
    body: message
  }).then(() => {
    // message sent successfully, redirect to the home page.
    res.redirect('/');
  }).catch((err) => {
    console.error(err);
    res.sendStatus(400);
  });
});

app.listen(3000);

This sets up a server which is serving static files from a public directory and then has one endpoint, POST to /messages, that sends a message.

We now need to create the client side. I shall do this in HTML only for simplicity. You need a form that will POST to the /messages endpoint with, in this case, a single field for the message. I've included a textarea to write the message in and a button to submit the form. If you save this as index.html in the public directory where you run the application from then it should work.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Send a message!</title>
</head>
<body>
  <h1>Send a message!</h1>

  <form action="/messages" method="POST">
    <label for="message">What would you like to send?</label>
    <textarea name="message" id="message"></textarea>
    <button type="submit">Send!</button>
  </form>
</body>
</html>

Let me know if that helps at all.

Update

So you're looking to make the request to the server using Ajax so your page doesn't reload and you can display a different message. Your current form seems to have removed the message textarea that I added, I'll put it back in again. I assume you also want to send the message to whichever guest you are welcoming at the time, but I don't know how that works in your system, so I'm going to avoid that for now and hopefully you can sort it out.

So, if you update your form to something like this:

<form id="form" action="/sms" method="POST">
    <label>
        <label for=selectName>Guest
            <select id="selectName" class="select " name="sms">
            </select>
        </label>
    </label>
    <label for="message">Message</label>
    <textarea id="message" name="message"></textarea>
    <input type="submit" value="send" class="btn btn-success" />
</form>

Then you need to add to your JavaScript a way to actually submit the form (since you are preventing the submission with e.preventDefault().

const $form = $('#form');
$form.submit(function(e) {
  e.preventDefault();
  let name = $('#selectName').val();
  let greetGuest = `Welcome ${name}!`;
  console.log(greetGuest);

  $.ajax({
    url: $form.attr('action'),
    type: $form.attr('method'),
    data: $form.serialize(),
    success: function(data) {
      console.log("The message has been sent");
    },
    error: function() {
      console.error("The message couldn't be sent");
      console.error(...arguments);
    }
  })

  //append to Dom
  $('.showMessage').append(
    `<div class="newMessage"><span>${greetGuest}</span></div>`
  );
});

In this case we are hooking into the callback for the submit event to make a new $.ajax request to the form's action, using the method (POST), and including the form data (which we get from $form.serialize()). We then setup success and error callbacks as you've done at the top of the function.

Let me know if this helps.

Upvotes: 2

Related Questions