visit
Let’s start with the frontend code for the signup form. The form is constructed with your typical HTML form elements: <form>
, <label>
, <input>
, and <button>
:
<main>
<h1>Fun Facts SMS</h1>
<p>
Enter your phone number (including country code) to receive an SMS text.
</p>
<form id="phoneNumberForm">
<label for="phone" class="sr-only">
Phone Number (with country code)
</label>
<input
type="text"
name="phone"
id="phone"
placeholder="1 555 777 9999"
autocomplete="off"
/>
<button type="submit">Submit</button>
</form>
<div id="result" class="hidden"></div>
</main>
(function () {
const resultContainer = document.querySelector('#result');
const submitPhoneNumberForm = (e) => {
e.preventDefault();
const phoneNumber = e.target.phone.value.replace(/\D/g, '');
if (!phoneNumber) {
return;
}
fetch(`api/send-sms/${phoneNumber}`)
.then((response) => response.json())
.then(() => {
resultContainer.textContent = `Success! Sent text message to: ${phoneNumber}`;
resultContainer.classList.remove('hidden');
})
.catch(() => {
resultContainer.textContent = `Error. Unable to send text message to: ${phoneNumber}`;
resultContainer.classList.remove('hidden');
});
};
const phoneNumberForm = document.querySelector('#phoneNumberForm');
phoneNumberForm.addEventListener('submit', submitPhoneNumberForm);
})();
const fetch = require('node-fetch');
const express = require('express');
const router = express.Router();
const funFacts = require('../fun-facts.json');
router.get('/send-sms/:phoneNumber', function (req, res) {
const phoneNumber = req.params.phoneNumber;
const funFact = funFacts[Math.floor(Math.random() * funFacts.length)];
const requestBody = {
messages: [
{
from: 'InfoSMS',
destinations: [
{
to: phoneNumber,
},
],
text: `Fun fact: ${funFact}`,
},
],
};
const fetchOptions = {
method: 'post',
body: JSON.stringify(requestBody),
headers: {
Authorization: `App ${process.env.API_KEY}`,
'Content-Type': 'application/json',
},
};
const URL = `${process.env.API_BASE_URL}/sms/2/text/advanced`;
fetch(URL, fetchOptions)
.then((response) => response.json())
.then((json) => {
res.json(json);
})
.catch((error) => {
res.json({ data: error });
});
});
module.exports = router;
Why make a server-side API request you ask? Primarily because we want to keep our API key a secret. The Infobip SMS API uses an that requires us to provide our API key, and we wouldn’t want that to be fully visible to all users in their browser’s network requests. So instead, we can protect that API key by storing it in an .env
file and only accessing it from the server, not the client.