Create a Bulk Text Messaging System by Using Telerivet and Vue.Js
Telerivet as derived from the two parts of the name tele-rivet is a platform that shortens distance by helping people and organizations communicate with the wide range of services it provides from SMS messages, automated calls, call forwarding, voicemail to USSD services.
In today's post I am going to focus on the SMS messaging part of Telerivet and demonstrate how you can send bulk SMSes in integration with Vue.js.
Setting up Telerivet
Start by creating a Telerivet account. On successful registration, login into your telerivet account and navigate to Routes. Click on Add route on the top right corner.
The route helps Telerivet servers connect with Telecom operators and there are a number of options to choose from, here proceed by selecting your country, SMS and "Android Phone".
Follow the instructions to download the android app and set up your Telerivet project on an android phone. To use Telerivet's REST API you need to create an API key which we are going to need later while making API requests. Note: With this setup Telerivet's text messages will cost you your network's regular SMS fees.
Navigate to Account > Developer API and click on +Generate API Key
. Copy the generated key and the project ID and store them on an ignored .env file. Note: You will be able to see the full API Key only once, so store it safely.
Project Layout and Deployment
We are going to deploy our project on Netlify, for those who are not familiar with it here is a link to a post explaining how to set it up. Netlify is easy to set up and use and it's lambda functions are quite useful when it comes to hiding our secret keys from the public's eyes.
Install the Vue.Js CLI tool if you don't have it yet in your system and proceed with creating a new Vue.Js app.
vue create vuerivet-sms
Install the following packages which are going to assist us with the next steps:
npm i axios dotenv
Let's add a form that we'll be composing our SMS message on inside the Vue.js project. Start by the HelloWorld.vue
file from the components directory and add a TextComposition.vue
file within the same folder and add the following code to this new component.
<!-- TextComposition.vue -->
<template>
<div class="section">
<div class="container content">
<div class="columns is-multiline">
<div class="column is-8 is-offset-2 register message-form">
<div class="card">
<div class="card-header">
<h4 class="card-header-title">Compose New Message <small></small></h4>
</div>
<div class="card-content">
<form onsubmit="return false" key.enter="sendMessage()">
<div class="field">
<div class="control">
<label class="label">Message Content (<em :style="charactersLeft < 10 ? 'color: red' : ''">[[charactersLeft + ' left']]</em>)</label>
<textarea v-model="message" :class="error.message ? 'textarea is-danger' : 'textarea'" placeholder="Message content"></textarea>
</div>
<p v-if="error.message" class="help is-danger">[[error.message]]</p>
</div>
<div class="field is-centered">
<div class="control">
<button :class="'button is-primary is-center ' + (buttonLoading ? 'is-loading':'')" @click="sendMessage()" :disabled="!allContacts || (allContacts.legth === 0)">Send Mesage</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'TextComposition',
data() {
return {
charactersLeft: 0,
maxCharacters: 280,
buttonLoading: false,
longestMessageContentAllowed: '',
message: '',
error: {
message: '',
},
allContacts: [/* array of phone numbers */]
};
},
delimiters: ["[[", "]]"],
mounted(){
this.charactersLeft = this.maxCharacters
},
watch: {
message(){
this.charactersLeft = this.maxCharacters - this.message.length;
// limit text to 280 characters
if(this.message.length === this.maxCharacters){
this.longestMessageContentAllowed = this.message;
}
if(this.message.length > this.maxCharacters){
this.message = this.longestMessageContentAllowed;
}
}
},
methods: {
sendMessage() {
this.buttonLoading = true;
let error = 0;
this.error = {
message: '',
}
if(this.message === ''){
console.log('Message can\'t be empty');
error++;
}
if(this.allContacts.length <= 0){
console.log("Contacts not loaded!");
}
if(error === 0){
let sendMessage = confirm(`Ready to send this message? [ ${this.message} ]`);
if(sendMessage) axios.post(`/.netlify/functions/send-text`, {
message: this.message,
contacts: this.allContacts,
from: this.from
})
.then(response => {
console.log(response.data.status);
this.buttonLoading = false;
})
.catch(err => {
console.log("An error occured, couldn't send message!", err);
this.buttonLoading = false;
})
} else {
this.buttonLoading = false;
return false;
}
}
}
}
</script>
<style>
.message-form{
margin-top: 1rem !important;
}
</style>
What we've created is a Vue.js component containing the message composition template and a method that posts our message to the endpoint /.netlify/functions/send-text
which delivers our data to the serverless function that will handle the sending of the message to Telerivet. We will be using the REST API method to send the message to Telerivet's servers, one among a couple of ways to send messages within the service.
before proceeding with creating the serverless function create a netlify.toml
file at the root of the project. This is a Netlify config file and we are going to set two things in it, the deployment settings and the location of our serverless functions.
#netlify.toml
[dev]
command = "npm run serve"
[build]
command = "npm run build"
publish = "dist"
functions = "functions"
Now, create a functions
directory in the project's root and in it add a send-text.js
file. Add the following code inside it.
// functions/send-text.js
require('dotenv').config();
const axios = require('axios');
exports.handler = async (event, context, callback) => {
const data = JSON.parse(event.body)
if (!data.contacts || !data.message) {
return { statusCode: 422, body: 'contacts & message are required.' }
}
const buff = new Buffer.from(process.env.TELERIVET_API_KEY);
const base64data = buff.toString('base64');
// send messages to contacts
const phoneNumbers = data.contacts.map(contact => contact);
try {
axios.post(`https://api.telerivet.com/v1/projects/${process.env.TELERIVET_PROJECT_ID}/send_broadcast`, {
to_numbers: phoneNumbers,
content: data.message
},{
headers: {
'Authorization': `Basic ${base64data}`
}})
return {
statusCode: 200,
body: JSON.stringify({status: 'success', message: `Message sent successfully!.`})
}
} catch (err) {
return {
statusCode: 200,
body: JSON.stringify({status: 'failure', message: `Sorry, couldn\'t send message. ${err}`})
}
}
}
In the function above we are performing HTTP Basic authentication into Telerivet's REST API then sending a broadcast message to the array of numbers that we intend to deliver this message to. For more on Telerivet's REST API consult it's official docs.
Add the project Id and API Key to Netlify's environmental variables before deploying your project.
Deploy your app and there you go!
Get creative and have fun texting.