@notibuzz/noti-sdk-js
v1.0.1
Published
Lightweight JavaScript SDK for sending WhatsApp messages and bulk messaging campaigns via the Notibuzz Cloud REST API.
Maintainers
Readme
@notibuzz/noti-sdk-js
@notibuzz/noti-sdk-js is a lightweight JavaScript and TypeScript SDK that provides seamless access to the Notibuzz Cloud REST API. It allows developers to send, manage, and automate WhatsApp messages, including high-volume bulk messaging, using a clean and modern API. Designed for scalability, reliability, and ease of use in Node.js and modern web applications.
Features
- ✅ Full TypeScript - Strong typing and autocompletion
- ✅ Bulk messaging - Support for campaigns with anti-ban control
- ✅ Async queue - Background message sending
- ✅ All endpoints - Sessions, Profile, Chatting, Status, Chats, Contacts
- ✅ Campaign control - Stop, resume and check availability
- ✅ Native ESM - Compatible with modern modules
Installation
npm install @notibuzz/noti-sdk-jsQuick Setup
Option 1: Environment Variables
export NOTI_URL="your_base_url"
export NOTI_KEY="your_api_key_here"Option 2: Code Configuration
Recommended syntax (object):
import { configureClient } from '@notibuzz/noti-sdk-js'
configureClient({
notiUrl: 'your_base_url',
notiApiKey: 'your_api_key'
})Traditional syntax (also supported):
configureClient('your_base_url', 'your_api_key')Basic Usage
Send a text message
import { configureClient, sendMessage } from '@notibuzz/noti-sdk-js'
configureClient({
notiUrl: process.env.NOTI_URL!,
notiApiKey: process.env.NOTI_KEY!
})
const result = await sendMessage({
body: {
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Hello from the SDK!'
}
}
})
console.log('Message sent:', result)List sessions
import { listSessions } from '@notibuzz/noti-sdk-js'
const sessions = await listSessions({
query: { all: true } // Include STOPPED sessions
})
console.log('Available sessions:', sessions)Bulk Messaging
The SDK supports bulk messaging with interval control and anti-ban features:
import { sendMessage } from '@notibuzz/noti-sdk-js'
// Bulk sending with multiple messages
const result = await sendMessage({
body: {
intervalMs: 20000, // 20 seconds between messages
messages: [
{
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Message 1'
}
},
{
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Message 2'
}
},
{
type: 'image',
payload: {
session: 'default',
chatId: '[email protected]',
file: {
mimetype: 'image/jpeg',
filename: 'photo.jpg',
url: 'https://example.com/image.jpg'
},
caption: 'Check out this image'
}
}
],
meta: {
campaignId: 'campaign-123',
requester: 'my-app',
origin: 'web'
}
}
})
console.log('Campaign enqueued:', result)
// { enqueued: true, jobId: 'send-bulk-...', count: 3, intervalMs: 20000 }Individual sending using sendMessage
import { sendMessage } from '@notibuzz/noti-sdk-js'
// You can also send a single message
const result = await sendMessage({
body: {
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Single message'
}
}
})Async Sending
You can send messages asynchronously (enqueued) using the async parameter:
import { sendMessage } from '@notibuzz/noti-sdk-js'
// The message will be enqueued and processed in the background
await sendMessage({
body: {
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Async message'
}
},
async: true // Enqueue the message
})
// Also works with other message types
await sendMessage({
body: {
type: 'image',
payload: {
session: 'default',
chatId: '[email protected]',
file: {
mimetype: 'image/jpeg',
url: 'https://example.com/image.jpg'
}
}
},
async: true
})Bulk Campaign Control
Check availability
import { bulkAvailability } from '@notibuzz/noti-sdk-js'
const availability = await bulkAvailability({
query: { requester: 'my-app' }
})
console.log('Availability:', availability)
// { available: true, current: 1, max: 2, origin: 'noti-sender-bridge' }Stop a campaign
import { bulkStopCampaign } from '@notibuzz/noti-sdk-js'
await bulkStopCampaign({
pathParams: { id: 'campaign-123' },
body: {
sessions: ['default'] // Optional: stop only in these sessions
}
})Resume a campaign
import { bulkResumeCampaign } from '@notibuzz/noti-sdk-js'
await bulkResumeCampaign({
pathParams: { id: 'campaign-123' },
body: {
sessions: ['default'] // Optional: resume only in these sessions
}
})Examples by Category
Sessions
import { listSessions, getSession, getSessionMe } from '@notibuzz/noti-sdk-js'
// List all sessions
const sessions = await listSessions({ query: { all: true } })
// Get session information
const session = await getSession({
pathParams: { session: 'default' }
})
// Get authenticated account information
const me = await getSessionMe({
pathParams: { session: 'default' }
})Profile
import { getMyProfile, setProfileStatus, setProfilePicture } from '@notibuzz/noti-sdk-js'
// Get profile
const profile = await getMyProfile({
pathParams: { session: 'default' }
})
// Update status (About)
await setProfileStatus({
pathParams: { session: 'default' },
body: { status: '🎉 Using Noti Sender!' }
})
// Update profile picture
await setProfilePicture({
pathParams: { session: 'default' },
body: {
file: {
mimetype: 'image/jpeg',
filename: 'avatar.jpg',
url: 'https://example.com/avatar.jpg'
}
}
})Chatting
Important: All messages are sent through the generic sendMessage endpoint. Supported types: text, image, file, voice, video, link-custom-preview, seen, poll, location, contact-vcard, forward, list.
Direct endpoints (don't go through sendMessage): reaction, startTyping, stopTyping.
import { sendMessage, reaction, startTyping, stopTyping } from '@notibuzz/noti-sdk-js'
// Send text
await sendMessage({
body: {
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Hello!'
}
}
})
// Send image
await sendMessage({
body: {
type: 'image',
payload: {
session: 'default',
chatId: '[email protected]',
file: {
mimetype: 'image/jpeg',
filename: 'photo.jpg',
url: 'https://example.com/image.jpg'
},
caption: 'Check this out'
}
}
})
// Send file
await sendMessage({
body: {
type: 'file',
payload: {
session: 'default',
chatId: '[email protected]',
file: {
mimetype: 'application/pdf',
filename: 'document.pdf',
url: 'https://example.com/document.pdf'
},
caption: 'Important document'
}
}
})
// Send voice note
await sendMessage({
body: {
type: 'voice',
payload: {
session: 'default',
chatId: '[email protected]',
file: {
mimetype: 'audio/ogg; codecs=opus',
url: 'https://example.com/voice.opus'
},
convert: false // true if you need format conversion
}
}
})
// Send video
await sendMessage({
body: {
type: 'video',
payload: {
session: 'default',
chatId: '[email protected]',
file: {
mimetype: 'video/mp4',
filename: 'video.mp4',
url: 'https://example.com/video.mp4'
},
caption: 'Watch this video',
asNote: false, // true for round video
convert: false
}
}
})
// Send poll
await sendMessage({
body: {
type: 'poll',
payload: {
session: 'default',
chatId: '[email protected]',
poll: {
name: 'What is your favorite color?',
options: ['Red', 'Blue', 'Green'],
selectableOptionsCount: 1
}
}
}
})
// Send location
await sendMessage({
body: {
type: 'location',
payload: {
session: 'default',
chatId: '[email protected]',
latitude: 38.8937255,
longitude: -77.0969763,
title: 'Our office',
reply_to: null
}
}
})
// Send contact (vCard)
await sendMessage({
body: {
type: 'contact-vcard',
payload: {
session: 'default',
chatId: '[email protected]',
contacts: [
{
vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:Jane Doe\nORG:Company Name;\nTEL;type=CELL;type=VOICE;waid=911111111111:+91 11111 11111\nEND:VCARD'
},
{
fullName: 'John Doe',
organization: 'Company Name',
phoneNumber: '+91 11111 11111',
whatsappId: '911111111111',
vcard: null
}
],
reply_to: null
}
}
})
// Forward message
await sendMessage({
body: {
type: 'forward',
payload: {
session: 'default',
chatId: '[email protected]',
forward: {
keyId: '[email protected]_AAAAAAAAAAAAAAAAAAAA'
}
}
}
})
// Send list (interactive list)
await sendMessage({
body: {
type: 'list',
payload: {
session: 'default',
chatId: '[email protected]',
message: {
title: 'Simple Menu',
description: 'Please choose an option',
footer: 'Thank you!',
button: 'Choose',
sections: [
{
title: 'Main',
rows: [
{
title: 'Option 1',
rowId: 'option1',
description: 'Option 1 description'
},
{
title: 'Option 2',
rowId: 'option2',
description: 'Option 2 description'
}
]
}
]
},
reply_to: null
}
}
})
// Indicate you're typing (direct endpoint)
await startTyping({
body: {
session: 'default',
chatId: '[email protected]'
}
})
// Stop typing (direct endpoint)
await stopTyping({
body: {
session: 'default',
chatId: '[email protected]'
}
})
// Mark as seen using sendMessage with type 'seen'
await sendMessage({
body: {
type: 'seen',
payload: {
session: 'default',
chatId: '[email protected]',
messages: ['[email protected]_AAAAAAAAAAAAAAAAAAAA']
}
}
})
// React to a message (direct endpoint, doesn't go through sendMessage)
await reaction({
body: {
session: 'default',
messageId: '[email protected]_3EB0EB3DF63D6AF1112A85',
reaction: '👍'
}
})Status (Stories)
import { statusText, statusImage, statusVoice, statusVideo, statusDelete } from '@notibuzz/noti-sdk-js'
// Create text Story
await statusText({
pathParams: { session: 'default' },
body: {
contacts: [], // [] to send to everyone
text: 'Check this out! https://github.com/',
backgroundColor: '#38b42f',
font: 0,
linkPreview: true
}
})
// Create image Story
await statusImage({
pathParams: { session: 'default' },
body: {
contacts: ['[email protected]'],
caption: 'My Story',
file: {
mimetype: 'image/jpeg',
filename: 'status.jpg',
url: 'https://example.com/image.jpg'
}
}
})
// Delete Story
await statusDelete({
pathParams: { session: 'default' },
body: {
id: '3EB0B4B74FB349EEC971A6'
}
})Chats
import {
chatsGet,
chatsOverviewGet,
chatsOverviewPost,
chatsGetMessages,
chatsReadMessages,
chatsEditMessage,
chatsPinMessage,
chatsUnpinMessage
} from '@notibuzz/noti-sdk-js'
// List chats
const chats = await chatsGet({
pathParams: { session: 'default' }
})
// Get chat overview
const overview = await chatsOverviewGet({
pathParams: { session: 'default' },
query: { limit: 20, offset: 0 }
})
// Get chat messages
const messages = await chatsGetMessages({
pathParams: {
session: 'default',
chatId: '[email protected]'
},
query: {
limit: 50,
offset: 0,
downloadMedia: true
}
})
// Mark messages as read
await chatsReadMessages({
pathParams: {
session: 'default',
chatId: '[email protected]'
},
query: {
messages: 30, // Number of messages
days: 7 // Days back
}
})
// Edit message
await chatsEditMessage({
pathParams: {
session: 'default',
chatId: '[email protected]',
messageId: '[email protected]_AAAAAAAAAAAAAAAAAAAA'
},
body: {
text: 'Edited message',
linkPreview: true
}
})
// Pin message
await chatsPinMessage({
pathParams: {
session: 'default',
chatId: '[email protected]',
messageId: '[email protected]_AAAAAAAAAAAAAAAAAAAA'
},
body: {
duration: 86400 // 24 hours
}
})Contacts
import {
contactsGetAll,
contactsGetBasic,
contactsCheckExists,
contactsProfilePicture,
contactsGetAbout,
contactsBlock,
contactsUnblock,
contactsUpsert
} from '@notibuzz/noti-sdk-js'
// List all contacts
const allContacts = await contactsGetAll({
query: { session: 'default' }
})
// Get basic information
const contact = await contactsGetBasic({
query: {
session: 'default',
contactId: '[email protected]'
}
})
// Check if a number exists on WhatsApp
const exists = await contactsCheckExists({
query: {
session: 'default',
phone: '51987654321'
}
})
// Get profile picture
const picture = await contactsProfilePicture({
query: {
session: 'default',
contactId: '[email protected]',
refresh: false
}
})
// Block contact
await contactsBlock({
body: {
session: 'default',
contactId: '[email protected]'
}
})
// Create or update contact
await contactsUpsert({
pathParams: {
session: 'default',
chatId: '[email protected]'
},
body: {
firstName: 'John',
lastName: 'Doe'
}
})Error Handling
import { sendMessage } from '@notibuzz/noti-sdk-js'
try {
const result = await sendMessage({
body: {
type: 'text',
payload: {
session: 'default',
chatId: '[email protected]',
text: 'Hello'
}
}
})
console.log('Success:', result)
} catch (error) {
if (error instanceof Error) {
console.error('Error:', error.message)
// Error message includes HTTP code and details
// Example: "HTTP 401 Unauthorized - { error: 'invalid X-Api-Key' }"
}
}Requirements
- Node.js >= 18.0.0
- TypeScript >= 5.0 (optional, but recommended)
API Reference
All endpoints are documented with TypeScript types. For the complete list of endpoints and their parameters, see the Bridge documentation.
Main Endpoints
- Sessions:
listSessions,getSession,getSessionMe - Profile:
getMyProfile,setProfileName,setProfileStatus,setProfilePicture,deleteProfilePicture - Chatting:
sendMessage(generic endpoint for all types: text, image, file, voice, video, poll, location, contact-vcard, forward, list, seen),reaction,startTyping,stopTyping - Status:
statusText,statusImage,statusVoice,statusVideo,statusDelete - Chats:
chatsGet,chatsOverviewGet,chatsOverviewPost,chatsGetMessages,chatsReadMessages,chatsGetMessage,chatsDeleteMessage,chatsEditMessage,chatsPinMessage,chatsUnpinMessage - Contacts:
contactsGetAll,contactsGetBasic,contactsCheckExists,contactsProfilePicture,contactsGetAbout,contactsBlock,contactsUnblock,contactsUpsert - Bulk:
bulkStopCampaign,bulkResumeCampaign,bulkAvailability
Contributing
Contributions are welcome. Please:
- Fork the repository
- Create a branch for your feature (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT License - see LICENSE for more details.
Support
- Issues: GitHub Issues
- Documentation: README
Changelog
1.0.1
- Initial release
- Full support for all Bridge endpoints
- Bulk messaging with anti-ban control
- Async queue
- Campaign control
