Node JS client module to send SMS messages using GOSMS.GE SMS Gateway.
To use this library, you must have a valid account on https://gosms.ge.
Please note SMS messages sent with this library will be deducted by your GOSMS.GE account credits.
For any questions, please contact us at [email protected]
$ npm install @gosmsge/gosmsge-node --saveconst { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
sms
.send('995555555555', 'Hello!', 'GOSMS.GE')
.then(body => {
console.log('Message sent successfully');
console.log('Message ID:', body.messageId);
console.log('Balance:', body.balance);
})
.catch(err => console.log('Error:', err.message));
// Send urgent message
sms
.send('995555555555', 'Urgent message!', 'GOSMS.GE', true)
.then(body => console.log(body))
.catch(err => console.log(err.message));const { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
sms
.sendBulk('GOSMS.GE', ['995555111111', '995555222222', '995555333333'], 'Hello everyone!')
.then(body => {
console.log(`Sent: ${body.successCount}/${body.totalCount}`);
body.messages.forEach(msg => {
if (!msg.success) console.log(`Failed: ${msg.to} - ${msg.error}`);
});
})
.catch(err => console.log('Error:', err.message));const { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
sms
.status('message_id')
.then(body => {
console.log('Message status:', body.status);
console.log('From:', body.from);
console.log('To:', body.to);
})
.catch(err => console.log('Error:', err.message));const { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
sms
.balance()
.then(body => {
console.log('Balance:', body.balance);
})
.catch(err => console.log('Error:', err.message));const { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
sms
.sendOtp('995555555555')
.then(body => {
console.log('OTP sent successfully');
console.log('Hash:', body.hash); // Save this hash for verification
console.log('Balance:', body.balance);
// Rate limit info (available since v4.5.0)
if (body.rateLimitInfo) {
console.log('Remaining attempts:', body.rateLimitInfo.remaining);
console.log('Max attempts:', body.rateLimitInfo.limit);
}
})
.catch(err => console.log('Error:', err.message));const { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
// Use hash from sendOtp response and code from user
sms
.verifyOtp('995555555555', 'hash_from_sendOtp', '1234')
.then(body => {
if (body.verify) {
console.log('OTP verified successfully');
} else {
console.log('Invalid OTP code');
}
// Rate limit info
if (body.rateLimitInfo) {
console.log('Remaining attempts:', body.rateLimitInfo.remaining);
}
})
.catch(err => console.log('Error:', err.message));const { SMS } = require('@gosmsge/gosmsge-node');
const sms = new SMS('your_api_key');
sms
.createSender('MyCompany')
.then(body => {
console.log('Sender created:', body.success);
})
.catch(err => console.log('Error:', err.message));import { SMS, SmsSendResponse, SmsError, GoSmsErrorCode } from '@gosmsge/gosmsge-node';
const sms = new SMS('your_api_key');
async function sendMessage() {
try {
const response = (await sms.send(
'995555555555',
'Hello from TypeScript!',
'GOSMS.GE'
)) as SmsSendResponse;
console.log('Message ID:', response.messageId);
console.log('Balance:', response.balance);
} catch (error) {
const smsError = error as SmsError;
if (smsError.errorCode === GoSmsErrorCode.INSUFFICIENT_BALANCE) {
console.error('Not enough credits!');
} else {
console.error('Error:', smsError.message);
}
}
}
sendMessage();When OTP rate limits are exceeded, the error includes retryAfter (seconds until lockout expires):
import { SMS, SmsError, GoSmsErrorCode } from '@gosmsge/gosmsge-node';
const sms = new SMS('your_api_key');
try {
const result = await sms.sendOtp('995555555555');
console.log('Remaining attempts:', result.rateLimitInfo?.remaining);
} catch (error) {
const smsError = error as SmsError;
if (smsError.errorCode === GoSmsErrorCode.TOO_MANY_REQUESTS) {
console.error(`Too many attempts. Retry after ${smsError.retryAfter}s`);
} else if (smsError.errorCode === GoSmsErrorCode.ACCOUNT_LOCKED) {
console.error(`Account locked. Retry after ${smsError.retryAfter}s`);
}
}Creates a new SMS client instance.
Parameters:
api_key(string, required) - Your API key from https://gosms.geoptions(object, optional) - Configuration optionsdebug(boolean) - Enable debug logging (default:false)timeout(number) - Request timeout in milliseconds (default:30000)retries(number) - Number of retry attempts for failed requests (default:1)
Example:
const sms = new SMS('your_api_key');
// With options
const smsDebug = new SMS('your_api_key', {
debug: true,
timeout: 15000,
retries: 3,
});send(phoneNumber: string, text: string, senderName: string, urgent?: boolean): Promise<SmsSendResponse>
Sends an SMS message to a phone number.
Parameters:
phoneNumber(string, required) - Phone number as a string (e.g., '995555555555')text(string, required) - Message text to sendsenderName(string, required) - Sender name (must be pre-registered on GOSMS.ge)urgent(boolean, optional) - Send as urgent message (default:false)
Returns: Promise resolving to SmsSendResponse
Example:
const result = await sms.send('995555555555', 'Hello!', 'GOSMS.GE');
console.log('Message ID:', result.messageId);
console.log('Balance:', result.balance);
// Send urgent message
await sms.send('995555555555', 'Urgent alert!', 'GOSMS.GE', true);sendBulk(senderName: string, phoneNumbers: string[], text: string, urgent?: boolean, noSmsNumber?: string): Promise<SendBulkSmsResponse>
Sends a bulk SMS message to multiple recipients (max 1000).
Parameters:
senderName(string, required) - Sender name (must be pre-registered on GOSMS.ge)phoneNumbers(string[], required) - Array of phone numbers (max 1000)text(string, required) - Message text to sendurgent(boolean, optional) - Send as urgent message (default:false)noSmsNumber(string, optional) - Opt-out number for advertising campaigns
Returns: Promise resolving to SendBulkSmsResponse with per-recipient results
Example:
const result = await sms.sendBulk('GOSMS.GE', ['995555111111', '995555222222'], 'Hello everyone!');
console.log(`Sent: ${result.successCount}/${result.totalCount}`);
result.messages.forEach(msg => {
if (!msg.success) console.log(`Failed: ${msg.to} - ${msg.error}`);
});Sends an OTP (One-Time Password) SMS message. Returns rate limit information via rateLimitInfo.
Parameters:
phoneNumber(string, required) - Phone number to send OTP to
Returns: Promise resolving to OtpSendResponse with hash for verification and rate limit info
Example:
const result = await sms.sendOtp('995555555555');
console.log('OTP Hash:', result.hash); // Save this for verification
console.log('Balance:', result.balance);
// Check rate limit
if (result.rateLimitInfo) {
console.log(`Attempts: ${result.rateLimitInfo.remaining}/${result.rateLimitInfo.limit}`);
}Verifies an OTP code sent to a phone number. Returns rate limit information via rateLimitInfo.
Parameters:
phoneNumber(string, required) - Phone number that received the OTPhash(string, required) - Hash received fromsendOtp()responsecode(string, required) - OTP code entered by the user
Returns: Promise resolving to OtpVerifyResponse with verify boolean and rate limit info
Example:
const result = await sms.verifyOtp('995555555555', 'hash_from_sendOtp', '1234');
if (result.verify) {
console.log('OTP verified successfully');
} else {
console.log('Invalid OTP code');
}
console.log('Remaining attempts:', result.rateLimitInfo?.remaining);Checks the delivery status of a sent SMS message.
Parameters:
messageId(string, required) - Message ID received fromsend()response
Returns: Promise resolving to CheckStatusResponse with message status information
Example:
const result = await sms.status('12345');
console.log('Status:', result.status); // e.g., 'delivered', 'pending', 'failed'
console.log('From:', result.from);
console.log('To:', result.to);Checks the current SMS balance of your account.
Returns: Promise resolving to BalanceResponse with balance information
Example:
const result = await sms.balance();
console.log('Balance:', result.balance); // Number of SMS credits remainingCreates a new sender name for your account. Note: Sender names must be approved by GOSMS.ge before use.
Parameters:
name(string, required) - Sender name to create (e.g., 'MyCompany', 'MyApp')
Returns: Promise resolving to SenderCreateResponse
Example:
const result = await sms.createSender('MyCompany');
if (result.success) {
console.log('Sender name created successfully');
console.log('Note: Wait for approval before using it');
}{
success: boolean;
messageId: number;
from: string;
to: string;
text: string;
balance: number;
sendAt: string; // ISO 8601 date string
segment: number;
smsCharacters: number;
encode: string;
}{
success: boolean;
totalCount: number;
successCount: number;
failedCount: number;
balance: number;
from: string;
text: string;
encode: string;
segment: number;
smsCharacters: number;
messages: BulkSmsResult[];
}{
messageId: number;
to: string;
success: boolean;
error?: string;
}{
success: boolean;
hash: string;
balance: number;
to: string;
sendAt: string; // ISO 8601 date string
segment: number;
smsCharacters: number;
encode: string;
rateLimitInfo?: RateLimitInfo;
}{
success: boolean;
verify: boolean;
rateLimitInfo?: RateLimitInfo;
}Rate limit information extracted from OTP endpoint response headers.
{
limit?: number; // Maximum attempts allowed
remaining?: number; // Attempts remaining
retryAfter?: number; // Seconds until lockout expires (only on error)
}{
success: boolean;
messageId: number;
from: string;
to: string;
text: string;
status: string;
sendAt: string; // ISO 8601 date string
segment: number;
smsCharacters: number;
encode: string;
}{
success: boolean;
balance: number;
}{
success: boolean;
}{
errorCode?: number;
message?: string;
retryAfter?: number; // Seconds until lockout expires (for error codes 109, 110)
}{
INVALID_API_KEY: 100;
INVALID_SENDER: 101;
INSUFFICIENT_BALANCE: 102;
INVALID_PARAMETERS: 103;
MESSAGE_NOT_FOUND: 104;
INVALID_PHONE: 105;
OTP_FAILED: 106;
SENDER_EXISTS: 107;
NOT_CONFIGURED: 108;
TOO_MANY_REQUESTS: 109;
ACCOUNT_LOCKED: 110;
OTP_EXPIRED: 111;
OTP_ALREADY_USED: 112;
INVALID_NO_SMS_NUMBER: 113;
}This package includes a comprehensive test suite with 100% code coverage.
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage report
npm run test:coverageThe test suite covers:
- ✅ Constructor validation (API key requirements)
- ✅ SMS sending (regular and urgent messages)
- ✅ Bulk SMS sending (multiple recipients, partial failures)
- ✅ OTP sending and verification
- ✅ Message status checking
- ✅ Balance checking
- ✅ Sender name creation
- ✅ Input validation for all methods
- ✅ Error handling (API errors and network failures)
- ✅ Retry logic with exponential backoff
- ✅ Integration workflow tests
This project follows Semantic Versioning with automated releases via GitHub Actions.
We use Conventional Commits for commit messages:
feat:- New features (triggers MINOR version bump)fix:- Bug fixes (triggers PATCH version bump)chore:,docs:,refactor:,ci:, etc. - Other changes (triggers PATCH version bump)BREAKING CHANGE:- Breaking changes (triggers MAJOR version bump)
Example:
feat(sms): add support for scheduled messages
fix(validation): correct phone number format validationReleases are automatically published when commits are pushed to the master branch:
- Tests run on Node.js 18, 20, and 22
- Commits since last tag are analyzed for version bump type
- Version is bumped in
package.json CHANGELOG.mdis updated- A git tag
vX.Y.Zis created and pushed - Package is published to npm
- GitHub release is created with release notes
We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines on:
- Development workflow
- Commit message conventions
- Pull request process
- Testing requirements
- Code standards
Quick start for contributors:
# Fork and clone the repository
git clone https://github.com/gosms-ge/gosmsge-node.git
cd gosmsge-node
# Install dependencies
npm install
# Run tests
npm test
# Build the project
npm run buildYou can check out our website https://gosms.ge