How to Send SMS through the SMPP API using Javascript/Node.js

The Short Message Peer-to-Peer (SMPP) API is a widely adopted protocol for exchanging SMS messages between SMS entities. For JavaScript/Node.JS developers working with Ozeki SMS Gateway, this guide explains how to implement SMPP protocol interactions using Node.js, complete with practical examples for connection management and message sending.

Setting Up an SMPP API Client in JavaScript (Node.js) for SMS Sending

To send SMS via SMPP API, you must first setup an SMPP user, and then bind your client to the Ozeki SMS Gateway's SMPP server.

Once this is done, you can use the smpp package from npm to handle SMPP protocol operations:

npm install smpp

Basic Connection Setup

Here's how to establish an SMPP connection in Node.js:

const smpp = require('smpp');
const session = smpp.connect({
    host: 'your.ozeki.server',
    port: 2775
});

session.on('connect', () => {
    console.log('Connected to SMPP server');
    
    session.bind_transceiver({
        system_id: 'your_username',
        password: 'your_password'
    }, (pdu) => {
        if (pdu.command_status === 0) {
            console.log('Successfully bound to SMPP server');
        } else {
            console.error('Bind failed:', pdu.command_status);
        }
    });
});

session.on('error', (error) => {
    console.error('SMPP connection error:', error);
});

Managing SMPP API Connections in Node.js for SMS Messaging

SMPP connections require keep-alive messages to maintain the session:

// Send enquire_link every 30 seconds
const keepAliveInterval = setInterval(() => {
    session.enquire_link({}, (pdu) => {
        if (pdu.command_status !== 0) {
            console.error('Keep-alive failed:', pdu.command_status);
        }
    });
}, 30000);

// Handle session close
session.on('close', () => {
    clearInterval(keepAliveInterval);
    console.log('SMPP connection closed');
});

Sending SMS with JavaScript via the SMPP API (Node.js Example)

To send an SMS using the submit_sm PDU:

function sendSMS(from, to, message) {
    session.submit_sm({
        source_addr: from,
        destination_addr: to,
        short_message: message,
        data_coding: 0, // GSM 7-bit encoding
        source_addr_ton: 1, // International format
        source_addr_npi: 1, // ISDN numbering plan
        dest_addr_ton: 1,  // International format
        dest_addr_npi: 1    // ISDN numbering plan
    }, (pdu) => {
        if (pdu.command_status === 0) {
            console.log(`Message sent successfully, message_id: ${pdu.message_id}`);
        } else {
            console.error('Message submission failed:', pdu.command_status);
        }
    });
}

// Example usage
sendSMS('12345', '+1234567890', 'Hello from Node.js SMPP client!');

Handling SMS Delivery Reports in JavaScript Using the SMPP API

To receive delivery notifications:

session.on('pdu', (pdu) => {
    if (pdu.command === 'deliver_sm') {
        const messageId = pdu.receipted_message_id;
        const status = pdu.message_state;
        
        console.log(`Delivery report for ${messageId}: ${status}`);
        
        // Send response
        session.deliver_sm_resp({
            sequence_number: pdu.sequence_number
        });
    }
});

Complete SMPP API Client Implementation in JavaScript (Node.js) for SMS Sending

Here's a complete implementation with error handling and reconnection:

const smpp = require('smpp');

class SMPPClient {
    constructor(config) {
        this.config = config;
        this.session = null;
        this.keepAliveInterval = null;
        this.connect();
    }

    connect() {
        this.session = smpp.connect(this.config);
        
        this.session.on('connect', () => {
            console.log('Connected to SMPP server');
            this.bind();
        });

        this.session.on('error', (error) => {
            console.error('Connection error:', error);
            this.reconnect();
        });

        this.session.on('close', () => {
            console.log('Connection closed');
            this.cleanup();
            this.reconnect();
        });
    }

    bind() {
        this.session.bind_transceiver({
            system_id: this.config.system_id,
            password: this.config.password
        }, (pdu) => {
            if (pdu.command_status === 0) {
                console.log('Successfully bound to SMPP server');
                this.startKeepAlive();
            } else {
                console.error('Bind failed:', pdu.command_status);
                this.session.close();
            }
        });
    }

    startKeepAlive() {
        this.keepAliveInterval = setInterval(() => {
            this.session.enquire_link({}, (pdu) => {
                if (pdu.command_status !== 0) {
                    console.error('Keep-alive failed:', pdu.command_status);
                }
            });
        }, 30000);
    }

    sendSMS(from, to, message) {
        return new Promise((resolve, reject) => {
            this.session.submit_sm({
                source_addr: from,
                destination_addr: to,
                short_message: message,
                data_coding: 0
            }, (pdu) => {
                if (pdu.command_status === 0) {
                    resolve(pdu.message_id);
                } else {
                    reject(new Error(`SMPP error: ${pdu.command_status}`));
                }
            });
        });
    }

    cleanup() {
        if (this.keepAliveInterval) {
            clearInterval(this.keepAliveInterval);
            this.keepAliveInterval = null;
        }
    }

    reconnect() {
        this.cleanup();
        setTimeout(() => {
            console.log('Attempting to reconnect...');
            this.connect();
        }, 5000);
    }
}

// Usage example
const client = new SMPPClient({
    host: 'your.ozeki.server',
    port: 2775,
    system_id: 'your_username',
    password: 'your_password'
});

client.sendSMS('12345', '+1234567890', 'Hello from complete SMPP client!')
    .then(messageId => console.log('Message ID:', messageId))
    .catch(err => console.error('Error:', err));

Error Handling and Best Practices

  • Always implement proper error handling for network issues
  • Use promises/async-await for better flow control
  • Implement message queuing for high-volume sending
  • Monitor connection state and implement automatic reconnection
  • Handle different character encodings properly

Conclusion

This guide has demonstrated how to implement an SMPP client in JavaScript/Node.JS to work with Ozeki SMS Gateway. The complete example includes connection management, message sending, and delivery report handling. By using the smpp package, you can focus on your application logic while the library handles the low-level protocol details.

For production use, consider implementing additional features like message queuing, proper logging, and monitoring. The SMPP protocol supports many advanced features like message concatenation and different encoding schemes that can be explored as your needs grow.

More information