jms-whatsapp
v2.0.1
Published
Biblioteca de funcionalidades para integração com serviço de envio e recebimento de mensagens.
Downloads
17
Readme
jms-whatsapp
jms-whatsapp is a javascript library which provides a high-level API control to Whatsapp so it can be configured to automatize resposes or any data that goes trough Whatsapp effortlessly.
It is built using puppeteer and based on this python wrapper
By deafult jms-whatsapp will try to use Google Chrome driver if installed, if not, it will use integrated Chromium instance
Changelog:
☑️ Add
openChat()
function with UI Layer☑️ Self check for updates
☑️ More parameters to
create()
☑️ Added d.ts types comments for friendlier development
☑️ Fixed video send, fixed optional
create()
parameters☑️ Bundle size now just 300 kB
☑️ Added
debug
option anduseChrome
tocreate()
Installation
> npm i jms-whatsapp
Getting started
// Supports ES6
// import { create, Whatsapp } from 'jms-whatsapp';
const jms-whatsapp = require('jms-whatsapp');
jms-whatsapp.create().then((client) => start(client));
function start(client) {
client.onMessage((message) => {
if (message.body === 'Hi') {
client.sendText(message.from, '👋 Hello from jms-whatsapp!');
}
});
}
After executing create()
function, jms-whatsapp will create an instance of whatsapp web. If you are not logged in, it will print a QR code in the terminal. Scan it with your phone and you are ready to go!
jms-whatsapp will remember the session so there is no need to authenticate everytime.
Multiples sessions can be created at the same time by pasing a session name to create()
function:
// Init sales whatsapp bot
jms-whatsapp.create('sales').then((salesClient) => {...});
// Init support whatsapp bot
jms-whatsapp.create('support').then((supportClient) => {...});
Optional create parameters
jms-whatsapp create()
method third parameter can have the following optional
parameters:
create('sessionName', qrCallback, {
headless: true, // Headless chrome
devtools: false, // Open devtools by default
useChrome: true, // If false will use Chromium instance
debug: false, // Opens a debug session
logQR: true // Logs QR automatically in terminal
browserArgs: [''] // Parameters to be added into the chrome browser instance
});
The type definition con be found in here: CreateConfig.ts
Exporting QR code
By default QR code will appear on the terminal. If you need to pass the QR somewhere else heres how:
const fs = require('fs');
// Second create() parameter is the QR callback
jms-whatsapp.create('session-marketing', (base64Qr, asciiQR) => {
// To log the QR in the terminal
console.log(asciiQR);
// To write it somewhere else in a file
exportQR(base64Qr, 'marketing-qr.png');
});
// Writes QR in specified path
function exportQR(qrCode, path) {
qrCode = qrCode.replace('data:image/png;base64,', '');
const imageBuffer = Buffer.from(qrCode, 'base64');
// Creates 'marketing-qr.png' file
fs.writeFileSync(path, imageBuffer);
}
Downloading files
Puppeteer takes care of the file downloading. The decryption is being done as fast as possible (outruns native methods). Supports big files!
import fs = require('fs');
import mime = require('mime-types');
client.onMessage(async (message) => {
if (message.isMedia) {
const buffer = await client.downloadFile(message);
// At this point you can do whatever you want with the buffer
// Most likely you want to write it into a file
const fileName = `some-file-name.${mime.extension(message.mimetype)}`;
fs.writeFile(fileName, buffer, function (err) {
...
});
}
});
Basic functions (usage)
Not every available function is listed, for further look, every function available can be found in here and here
Chatting
// Send basic text
await client.sendText(chatId, '👋 Hello from jms-whatsapp!');
// Send image
await client.sendImage(
chatId,
'path/to/img.jpg',
'image-name.jpg',
'Caption text'
);
// Send @tagged message
await client.sendMentioned(chatId, 'Hello @5218113130740 and @5218243160777!', [
'5218113130740',
'5218243160777',
]);
// Reply to a message
await client.reply(chatId, 'This is a reply!', message.id.toString());
// Send file (jms-whatsapp will take care of mime types, just need the path)
await client.sendFile(chatId, 'path/to/file.pdf', 'cv.pdf', 'Curriculum');
// Send gif
await client.sendVideoAsGif(
chatId,
'path/to/video.mp4',
'video.gif',
'Gif image file'
);
// Send contact
// contactId: [email protected]
await client.sendContact(chatId, contactId);
// Forwards messages
await client.forwardMessages(chatId, [message.id.toString()], true);
// Send sticker
await client.sendImageAsSticker(chatId, 'path/to/image.jpg');
// Send location
await client.sendLocation(
chatId,
25.6801987,
-100.4060626,
'Some address, Washington DC',
'Subtitle'
);
// Send seen ✔️✔️
await client.sendSeen(chatId);
// Start typing...
await client.startTyping(chatId);
// Stop typing
await client.stopTyping(chatId);
// Set chat state (0: Typing, 1: Recording, 2: Paused)
await client.setChatState(chatId, 0 | 1 | 2);
Retrieving data
// Retrieve contacts
const contacts = await client.getAllContacts();
// Retrieve all messages in chat
const allMessages = await client.loadAndGetAllMessagesInChat(chatId);
// Retrieve contact status
const status = await client.getStatus(contactId);
// Retrieve user profile
const user = await client.getNumberProfile(contactId);
// Retrieve all unread message
const messages = await client.getAllUnreadMessages();
// Retrieve all chats
const chats = await client.getAllChats();
// Retrieve all groups
const chats = await client.getAllGroups();
// Retrieve profile fic (as url)
const url = await client.getProfilePicFromServer(chatId);
// Retrieve chat/conversation
const chat = await client.getChat(chatId);
Group functions
// groupId or chatId: leaveGroup [email protected]
// Leave group
await client.leaveGroup(groupId);
// Get group members
await client.getGroupMembers(groupId);
// Get group members ids
await client.getGroupMembersIds(groupId);
// Generate group invite url link
await client.getGroupInviteLink(groupId);
// Create group (title, participants to add)
await client.createGroup('Group name', ['[email protected]', '[email protected]']);
// Remove participant
await client.removeParticipant(groupId, '[email protected]');
// Add participant
await client.addParticipant(groupId, '[email protected]');
// Promote participant (Give admin privileges)
await client.promoteParticipant(groupId, '[email protected]');
// Demote particiapnt (Revoke admin privileges)
await client.demoteParticipant(groupId, '[email protected]');
// Get group admins
await client.getGroupAdmins(groupId);
Profile functions
// Set client status
await client.setProfileStatus('On vacations! ✈️');
// Set client profile name
await client.setProfileName('jms-whatsapp bot');
Device functions
// Get device info
await client.getHostDevice();
// Get connection state
await client.getConnectionState();
// Get battery level
await client.getBatteryLevel();
// Is connected
await client.isConnected();
// Get whatsapp web version
await client.getWAVersion();
Events
// Listen to messages
client.onMessage(message => {
...
})
// Listen to state changes
client.onStateChange(state => {
...
});
// Listen to ack's
client.onAck(ack => {
...
});
// Listen to live location
// chatId: '[email protected]'
client.onLiveLocation(chatId, (liveLocation) => {
...
});
// chatId looks like this: '[email protected]'
// Event interface is in here: https://github.com/danielcardeenas/jms-whatsapp/blob/master/src/api/model/participant-event.ts
client.onParticipantsChanged(chatId, (event) => {
...
});
// Listen when client has been added to a group
client.onAddedToGroup(chatEvent => {
...
});
Other
// Delete chat
await client.deleteChat(chatId);
// Clear chat messages
await client.clearChat(chatId);
// Delete message (last parameter: delete only locally)
await client.deleteMessage(chatId, message.id.toString(), false);
// Retrieve a number profile / check if contact is a valid whatsapp number
const profile = await client.getNumberProfile('[email protected]');
Misc
There are some tricks for a better usage of jms-whatsapp.
Keep session alive:
// In case of being logged out of whatsapp web
// Force it to keep the current session
// State change
client.onStateChange((state) => {
console.log(state);
const conflits = [
jms-whatsapp.SocketState.CONFLICT,
jms-whatsapp.SocketState.UNPAIRED,
jms-whatsapp.SocketState.UNLAUNCHED,
];
if (conflits.includes(state)) {
client.useHere();
}
});
Send message to new contacts (non-added)
Also see Whatsapp links Be careful since this can pretty much could cause a ban from Whatsapp, always keep your contacts updated!
await client.sendMessageToId('[email protected]', 'Hello from jms-whatsapp! 👋');
Multiple sessions
If you need to run multiple sessions at once just pass a session name to
create()
method.
async () => {
const marketingClient = await jms-whatsapp.create('marketing');
const salesClient = await jms-whatsapp.create('sales');
const supportClient = await jms-whatsapp.create('support');
};
Closing (saving) sessions
Close the session properly to ensure the session is saved for the next time you log in (So it wont ask for QR scan again). So instead of CTRL+C,
// Catch ctrl+C
process.on('SIGINT', function() {
client.close();
});
// Try-catch close
try {
...
} catch (error) {
client.close();
}
Debugging
Development
Building jms-whatsapp is really simple altough it contians 3 main projects inside
- Wapi project
> npm run build:wapi
- Middleeware
> npm run build:build:middleware
> npm run build:jsQR
- jms-whatsapp
> npm run build:jms-whatsapp
To build the entire project just run
> npm run build
jms-whatsapp state
As of version 2.3.5
it seems that jms-whatsapp has reached a very rich and stable
functionality and architecture. As much as I would love to, I cannot dedicate a
lot of time to this project so please consider checking out forked versions of
jms-whatsapp where other developers can dedicate more time and support to it.
Maintainers
Maintainers are needed, I cannot keep with all the updates by myself. If you are interested please open a Pull Request.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.