In this blog post, we will use Node.js to build a simple library (Node.js) package that will enable us to send SMS messages over Infobip API using a single function call. The developed library can then be used in any number of projects to send any number of basic SMS text messages, with a minimum amount of configuration needed.
We also have a Node.js SDK which should get you up and running in no time. Note that the example below creates a Node.js project from scratch with no packages or libraries.
- Infobip account
- Working Node.js evironment, including npm
This post assumes basic knowledge of JavaScript, Node.js, and HTTP.
We will begin by setting up an empty Node.js project.
Inside an empty directory (let's call it sendsms
), run the npm init
command to initialize a new Node.js project. You will need to answer a few questions that will be asked by npm
, like the name and the version of the project. You can accept all the defaults suggested by npm
, or fill out some information according to your preferences. In the end, npm
will generate a package.json
file containing something like:
{
"name": "sendsms",
"version": "1.0.0",
"description": "a simple Node.js project to send SMS messages",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Our project will be very simple - we will only need one dependency. We'll add a popular open-source HTTP client library called Axios. Inside your project directory, run
npm install axios
You'll notice that axios
was added under dependencies
inside your package.json
file.
Our goal is to create a function with a signature.
sendSms(config, destinationNumber, message)
Which we could use to send a single SMS message at a time.
The parameters to use:
config
is an object with data, needed to execute the actual HTTP request against Infobip API.\- your custom Infobip API domain,
baseUrl
(e.g.8935q9.api.infobip.com
) and your InfobipAPIkey
that you can access from within your Infobip account. You would typically store such information somewhere in your application's configuration.\ destinationNumber
is the phone number (MSISDN) of the handset to which you want to send an SMS message. It must be in international format - that is, prefixed with the country and network prefix.message
is the actual text of the SMS message that you want to send.
The function will need to do the appropriate HTTP POST call to Infobip Send SMS API in order to send the SMS message. To implement it, we will split the work into three parts: constructing the URL, constructing request headers, and constructing the request body.
The URL will always look like this: https://<your-custom-domain>/sms/2/text/advanced
. We can create a helper function that will use the custom domain from the configuration to build the correct URL:
const buildUrl = (domain) => {
return `https://${domain}/sms/2/text/advanced`;
}
The request to Infobip API needs to contain appropriate HTTP headers for authentication purposes, as described in the documentation. We will use the "API Key Header" authentication method, placing the API key into the Authentication
header. We'll also provide a header for the content type - we'll be using JSON
.
const buildHeaders = (apiKey) => {
return {
'Content-Type': 'application/json',
'Authorization': `App ${apiKey}`
};
}
The /sms/2/text/advanced
endpoint expects SMS message properties to be provided in the HTTP request body. We only need two properties for the basic case, the destination phone number and the message text. Following the format for the message body provided in the documentation, we can make a helper function for that, too:
const buildRequestBody = (destinationNumber, message) => {
const destinationObject = {
to: destinationNumber
};
const messageObject = {
destinations: [destinationObject],
text: message
};
return {
messages: [messageObject]
}
}
Once the HTTP request is executed, the response body will differ depending on whether the request was a success or a failure. Here, we'll parse the response from the Axios HTTP client to a simple object containing a success
boolean flag and message status information in case of success, or the error message in case of failure.
const parseSuccessResponse = (axiosResponse) => {
const responseBody = axiosResponse.data;
const singleMessageResponse = responseBody.messages[0];
return {
success: true,
messageId: singleMessageResponse.messageId,
status: singleMessageResponse.status.name,
category: singleMessageResponse.status.groupName
};
}
const parseFailedResponse = (axiosError) => {
if (axiosError.response) {
const responseBody = axiosError.response.data;
return {
success: false,
errorMessage: responseBody.requestError.serviceException.text,
errorDetails: responseBody
};
}
return {
success: false,
errorMessage: axiosError.message
};
}
We'll add two more helper functions. One is to serve as a validation helper, to ensure that the sendSms
function is called with the correct arguments. The other one is a helper function that wraps HTTP headers in an object as required by Axios's POST
function.
const validateNotEmpty = (value, fieldName) => {
if (!value) {
throw `${fieldName} parameter is mandatory`;
}
}
const buildAxiosConfig = (apiKey) => {
return {
headers: buildHeaders(apiKey)
};
}
Finally, we have everything needed to put together for the sendSms
function. The code itself is very straightforward:
const sendSms = (config, destinationNumber, message) => {
validateNotEmpty(config.domain, 'config.domain');
validateNotEmpty(config.apiKey, 'config.apiKey');
validateNotEmpty(destinationNumber, 'destinationNumber');
validateNotEmpty(message, 'message');
const url = buildUrl(config.domain);
const requestBody = buildRequestBody(destinationNumber, message);
const axiosConfig = buildAxiosConfig(config.apiKey);
return axios.post(url, requestBody, axiosConfig)
.then(res => parseSuccessResponse(res))
.catch(err => parseFailedResponse(err));
}
To test out the code, we can put all the functions described so far in a single file called send.js
in the root of our project.
We want to export the sendSms()
function to use it elsewhere, so place the export at the end of the file:
module.exports = sendSms;
Now, create a file index.js
inside the same directory (project root). We can import the send
module and use it to send an SMS. We'll just log the results to the console. Remember that if your Infobip account is in free trial mode, you can only send SMS to the phone number you used to create your Infobip account.
const sendSms = require('./send.js');
const config = {
domain: '<your-domain-here>',
apiKey: '<your-api-key-here>'
};
sendSms(config,'<your-phone-number-here>', `hello world` ).then(result => console.log(result));
Replace the placeholders with your actual API key, domain, and phone number, and that's it, you can now run node index.js
to send an SMS message!
Note: You can also download the completed project source files here).
Here is an example output in case of success, indicating that the message was accepted and is pending delivery:
{
success: true,
messageId: '36807858316207371400',
status: 'PENDING_ACCEPTED',
category: 'PENDING'
}
Here, is an example response returned in the case that the provided API key is invalid:
{
success: false,
errorMessage: 'Invalid login details',
errorDetails: { requestError: { serviceException: [Object] } }
}
For more details on status and error codes, visit documentation.