{"id":13676798,"url":"https://github.com/danielcardeenas/sulla","last_synced_at":"2025-05-15T09:07:55.777Z","repository":{"id":37849387,"uuid":"191179628","full_name":"danielcardeenas/sulla","owner":"danielcardeenas","description":"👩🏻‍🔬 Javascript Whatsapp api library for chatbots","archived":false,"fork":false,"pushed_at":"2023-05-24T01:51:41.000Z","size":3234,"stargazers_count":1281,"open_issues_count":96,"forks_count":271,"subscribers_count":73,"default_branch":"master","last_synced_at":"2025-04-14T15:02:04.126Z","etag":null,"topics":["bot","chatbot","framework","whatsapp","whatsapp-api","whatsapp-bot"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielcardeenas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-06-10T14:04:46.000Z","updated_at":"2025-04-11T13:19:21.000Z","dependencies_parsed_at":"2024-01-14T14:31:42.008Z","dependency_job_id":"2da37317-f0e0-4fab-8c41-634acad93458","html_url":"https://github.com/danielcardeenas/sulla","commit_stats":{"total_commits":300,"total_committers":16,"mean_commits":18.75,"dds":"0.43999999999999995","last_synced_commit":"34f70f44cd87e769dd1dbac79fc19aae7553776a"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielcardeenas%2Fsulla","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielcardeenas%2Fsulla/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielcardeenas%2Fsulla/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielcardeenas%2Fsulla/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielcardeenas","download_url":"https://codeload.github.com/danielcardeenas/sulla/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254310520,"owners_count":22049470,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","chatbot","framework","whatsapp","whatsapp-api","whatsapp-bot"],"created_at":"2024-08-02T13:00:33.054Z","updated_at":"2025-05-15T09:07:50.768Z","avatar_url":"https://github.com/danielcardeenas.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/danielcardeenas/sulla\"\u003e\n    \u003cimg width=\"250px\" src=\"https://github.com/danielcardeenas/sulla/blob/master/img/logo.jpg?raw=true\" alt=\"Sulla logo\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# Sulla\n\n[![npm version](https://img.shields.io/npm/v/sulla.svg?color=%2378e08f)](https://www.npmjs.com/package/sulla)\n![npm type definitions](https://img.shields.io/npm/types/sulla)\n![GitHub last commit](https://img.shields.io/github/last-commit/danielcardeenas/sulla)\n[![GitHub license](https://img.shields.io/github/license/danielcardeenas/sulla)](https://github.com/danielcardeenas/sulla/blob/master/LICENSE)\n[![codebeat badge](https://codebeat.co/badges/7e510d47-8689-49da-abd8-a9a29d106a2b)](https://codebeat.co/projects/github-com-danielcardeenas-sulla-master)\n\n\u003e Sulla is a javascript library which provides a high-level API control to\n\u003e Whatsapp so it can be configured to automatize responses or any data that goes\n\u003e through Whatsapp effortlessly.\n\u003e\n\u003e It is built using [puppeteer](https://github.com/GoogleChrome/puppeteer)\n\n\n## Sulla state\n\nAs of version `2.3.5` it seems that sulla has reached a very rich and stable functionality and architecture.\nAs much as I would love to, I cannot dedicate a lot of time to this project so please consider checking out forked versions of sulla where other developers can dedicate more time and support to it.\n\nRecommended actively supported sulla-based projects:\n\u003e [**venom**](https://github.com/orkestral/venom)\n\u003e \n\u003e [![last commit](https://img.shields.io/github/last-commit/orkestral/venom)](https://github.com/orkestral/venom/)\n[![Downloads](https://img.shields.io/npm/dm/venom.svg)](https://www.npmjs.com/package/venom)\n[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/orkestral/venom.svg)](https://isitmaintained.com/project/orkestral/venom 'Average time to resolve an issue')\n\n\u003e [**wppconnect**](https://github.com/wppconnect-team/wppconnect/)\n\u003e \n\u003e [![last commit](https://img.shields.io/github/last-commit/wppconnect-team/wppconnect)](https://github.com/wppconnect-team/wppconnect/)\n[![Downloads](https://img.shields.io/npm/dm/@wppconnect-team/wppconnect.svg)](https://www.npmjs.com/package/@wppconnect-team/wppconnect)\n[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/wppconnect-team/wppconnect.svg)](https://isitmaintained.com/project/wppconnect-team/wppconnect 'Average time to resolve an issue')\n\n\u003e [**open-wa/wa-automate**](https://github.com/open-wa/wa-automate-nodejs)\n\u003e\n\u003e [![last commit](https://img.shields.io/github/last-commit/open-wa/wa-automate-nodejs)](https://github.com/open-wa/wa-automate-nodejs)\n[![Downloads](https://img.shields.io/npm/dm/@open-wa/wa-automate.svg)](https://www.npmjs.com/package/@open-wa/wa-automate)\n[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/open-wa/wa-automate-nodejs.svg)](http://isitmaintained.com/project/open-wa/wa-automate-nodejs \"Average time to resolve an issue\")\n\n## Installation\n\n```bash\n\u003e npm i sulla --save\n```\n\n## Getting started\n\n```javascript\n// Supports ES6\n// import { create, Whatsapp } from 'sulla';\nconst sulla = require('sulla');\n\nsulla.create().then((client) =\u003e start(client));\n\nfunction start(client) {\n  client.onMessage((message) =\u003e {\n    if (message.body === 'Hi') {\n      client.sendText(message.from, '👋 Hello from sulla!');\n    }\n  });\n}\n```\n\n\u003cimg align=\"left\" src=\"https://github.com/danielcardeenas/sulla/blob/master/img/auth.gif?raw=true\" width=\"370px\"\u003e\n\n##### After executing `create()` function, **sulla** 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!\n\n##### Sulla will remember the session so there is no need to authenticate everytime.\n\n##### Multiples sessions can be created at the same time by pasing a session name to `create()` function:\n\n```javascript\n// Init sales whatsapp bot\nsulla.create('sales').then((salesClient) =\u003e {...});\n\n// Init support whatsapp bot\nsulla.create('support').then((supportClient) =\u003e {...});\n```\n\n\u003cbr\u003e\n\n## Optional create parameters\n\nSulla `create()` method third parameter can have the following optional\nparameters:\n\n```javascript\ncreate('sessionName', qrCallback, {\n  headless: true, // Headless chrome\n  devtools: false, // Open devtools by default\n  useChrome: true, // If false will use Chromium instance\n  debug: false, // Opens a debug session\n  logQR: true // Logs QR automatically in terminal\n  browserArgs: [''] // Parameters to be added into the chrome browser instance\n  refreshQR: 15000, // Will refresh QR every 15 seconds, 0 will load QR once. Default is 30 seconds\n});\n```\n\n##### The type definition con be found in here: [CreateConfig.ts](https://github.com/danielcardeenas/sulla/blob/master/src/config/create-config.ts)\n\n## Exporting QR code\n\nBy default QR code will appear on the terminal. If you need to pass the QR\nsomewhere else heres how:\n\n```javascript\nconst fs = require('fs');\n\n// Second create() parameter is the QR callback\nsulla.create('session-marketing', (base64Qr, asciiQR) =\u003e {\n  // To log the QR in the terminal\n  console.log(asciiQR);\n\n  // To write it somewhere else in a file\n  exportQR(base64Qr, 'marketing-qr.png');\n});\n\n// Writes QR in specified path\nfunction exportQR(qrCode, path) {\n  qrCode = qrCode.replace('data:image/png;base64,', '');\n  const imageBuffer = Buffer.from(qrCode, 'base64');\n\n  // Creates 'marketing-qr.png' file\n  fs.writeFileSync(path, imageBuffer);\n}\n```\n\n## Downloading files\n\nPuppeteer takes care of the file downloading. The decryption is being done as\nfast as possible (outruns native methods). Supports big files!\n\n```javascript\nimport fs = require('fs');\nimport mime = require('mime-types');\n\nclient.onMessage(async (message) =\u003e {\n  if (message.isMedia) {\n    const buffer = await client.downloadFile(message);\n    // At this point you can do whatever you want with the buffer\n    // Most likely you want to write it into a file\n    const fileName = `some-file-name.${mime.extension(message.mimetype)}`;\n    fs.writeFile(fileName, buffer, function (err) {\n      ...\n    });\n  }\n});\n```\n\n## Basic functions (usage)\n\nNot every available function is listed, for further look, every function\navailable can be found in [here](/src/api/layers) and\n[here](/src/lib/wapi/functions)\n\n### Chatting\n\n##### Here, `chatId` could be `\u003cphoneNumber\u003e@c.us` or `\u003cphoneNumber\u003e-\u003cgroupId\u003e@c.us`\n\n```javascript\n// Send basic text\nawait client.sendText(chatId, '👋 Hello from sulla!');\n\n// Send image\nawait client.sendImage(\n  chatId,\n  'path/to/img.jpg',\n  'image-name.jpg',\n  'Caption text'\n);\n\n// Send @tagged message\nawait client.sendMentioned(chatId, 'Hello @5218113130740 and @5218243160777!', [\n  '5218113130740',\n  '5218243160777',\n]);\n\n// Reply to a message\nawait client.reply(chatId, 'This is a reply!', message.id.toString());\n\n// Send file (sulla will take care of mime types, just need the path)\nawait client.sendFile(chatId, 'path/to/file.pdf', 'cv.pdf', 'Curriculum');\n\n// Send gif\nawait client.sendVideoAsGif(\n  chatId,\n  'path/to/video.mp4',\n  'video.gif',\n  'Gif image file'\n);\n\n// Send contact\n// contactId: 52155334634@c.us\nawait client.sendContact(chatId, contactId);\n\n// Forwards messages\nawait client.forwardMessages(chatId, [message.id.toString()], true);\n\n// Send sticker\nawait client.sendImageAsSticker(chatId, 'path/to/image.jpg');\n\n// Send location\nawait client.sendLocation(\n  chatId,\n  25.6801987,\n  -100.4060626,\n  'Some address, Washington DC',\n  'Subtitle'\n);\n\n// Send seen ✔️✔️\nawait client.sendSeen(chatId);\n\n// Start typing...\nawait client.startTyping(chatId);\n\n// Stop typing\nawait client.stopTyping(chatId);\n\n// Set chat state (0: Typing, 1: Recording, 2: Paused)\nawait client.setChatState(chatId, 0 | 1 | 2);\n```\n\n### Retrieving data\n\n```javascript\n// Retrieve contacts\nconst contacts = await client.getAllContacts();\n\n// Retrieve all messages in chat\nconst allMessages = await client.loadAndGetAllMessagesInChat(chatId);\n\n// Retrieve contact status\nconst status = await client.getStatus(contactId);\n\n// Retrieve user profile\nconst user = await client.getNumberProfile(contactId);\n\n// Retrieve all unread message\nconst messages = await client.getAllUnreadMessages();\n\n// Retrieve all chats\nconst chats = await client.getAllChats();\n\n// Retrieve all groups\nconst chats = await client.getAllGroups();\n\n// Retrieve profile fic (as url)\nconst url = await client.getProfilePicFromServer(chatId);\n\n// Retrieve chat/conversation\nconst chat = await client.getChat(chatId);\n```\n\n### Group functions\n\n```javascript\n// groupId or chatId: leaveGroup 52123123-323235@g.us\n\n// Leave group\nawait client.leaveGroup(groupId);\n\n// Get group members\nawait client.getGroupMembers(groupId);\n\n// Get group members ids\nawait client.getGroupMembersIds(groupId);\n\n// Generate group invite url link\nawait client.getGroupInviteLink(groupId);\n\n// Create group (title, participants to add)\nawait client.createGroup('Group name', ['123123@c.us', '45456456@c.us']);\n\n// Remove participant\nawait client.removeParticipant(groupId, '123123@c.us');\n\n// Add participant\nawait client.addParticipant(groupId, '123123@c.us');\n\n// Promote participant (Give admin privileges)\nawait client.promoteParticipant(groupId, '123123@c.us');\n\n// Demote particiapnt (Revoke admin privileges)\nawait client.demoteParticipant(groupId, '123123@c.us');\n\n// Get group admins\nawait client.getGroupAdmins(groupId);\n```\n\n### Profile functions\n\n```javascript\n// Set client status\nawait client.setProfileStatus('On vacations! ✈️');\n\n// Set client profile name\nawait client.setProfileName('Sulla bot');\n```\n\n### Device functions\n\n```javascript\n// Get device info\nawait client.getHostDevice();\n\n// Get connection state\nawait client.getConnectionState();\n\n// Get battery level\nawait client.getBatteryLevel();\n\n// Is connected\nawait client.isConnected();\n\n// Get whatsapp web version\nawait client.getWAVersion();\n```\n\n### Events\n\n```javascript\n// Listen to messages\nclient.onMessage(message =\u003e {\n  ...\n})\n\n// Listen to state changes\nclient.onStateChange(state =\u003e {\n  ...\n});\n\n// Listen to ack's\nclient.onAck(ack =\u003e {\n  ...\n});\n\n// Listen to live location\n// chatId: 'phone@c.us'\nclient.onLiveLocation(chatId, (liveLocation) =\u003e {\n  ...\n});\n\n// chatId looks like this: '5518156745634-1516512045@g.us'\n// Event interface is in here: https://github.com/danielcardeenas/sulla/blob/master/src/api/model/participant-event.ts\nclient.onParticipantsChanged(chatId, (event) =\u003e {\n  ...\n});\n\n// Listen when client has been added to a group\nclient.onAddedToGroup(chatEvent =\u003e {\n  ...\n});\n\n```\n\n### Other\n\n```javascript\n// Delete chat\nawait client.deleteChat(chatId);\n\n// Clear chat messages\nawait client.clearChat(chatId);\n\n// Delete message (last parameter: delete only locally)\nawait client.deleteMessage(chatId, message.id.toString(), false);\n\n// Retrieve a number profile / check if contact is a valid whatsapp number\nconst profile = await client.getNumberProfile('0000000@c.us');\n```\n\n## Misc\n\nThere are some tricks for a better usage of sulla.\n\n#### Keep session alive:\n\n```javascript\n// In case of being logged out of whatsapp web\n// Force it to keep the current session\n// State change\nclient.onStateChange((state) =\u003e {\n  console.log(state);\n  const conflits = [\n    sulla.SocketState.CONFLICT,\n    sulla.SocketState.UNPAIRED,\n    sulla.SocketState.UNLAUNCHED,\n  ];\n  if (conflits.includes(state)) {\n    client.useHere();\n  }\n});\n```\n\n#### Send message to new contacts (non-added)\n\nAlso see [Whatsapp links](https://faq.whatsapp.com/en/26000030/) Be careful\nsince this can pretty much could cause a ban from Whatsapp, always keep your\ncontacts updated!\n\n```javascript\nawait client.sendMessageToId('5212234234@c.us', 'Hello from sulla! 👋');\n```\n\n#### Multiple sessions\n\nIf you need to run multiple sessions at once just pass a session name to\n`create()` method.\n\n```javascript\nasync () =\u003e {\n  const marketingClient = await sulla.create('marketing');\n  const salesClient = await sulla.create('sales');\n  const supportClient = await sulla.create('support');\n};\n```\n\n#### Closing (saving) sessions\n\nClose the session properly to ensure the session is saved for the next time you\nlog in (So it wont ask for QR scan again). So instead of CTRL+C,\n\n```javascript\n// Catch ctrl+C\nprocess.on('SIGINT', function() {\n  client.close();\n});\n\n// Try-catch close\ntry {\n   ...\n} catch (error) {\n   client.close();\n}\n```\n\n### Debugging\n\n## Development\n\nBuilding sulla is really simple altough it contians 3 main projects inside\n\n1. Wapi project\n\n```bash\n\u003e npm run build:wapi\n```\n\n2. Middleeware\n\n```bash\n\u003e npm run build:build:middleware\n\u003e npm run build:jsQR\n```\n\n3. Sulla\n\n```bash\n\u003e npm run build:sulla\n```\n\nTo build the entire project just run\n\n```bash\n\u003e npm run build\n```\n\n\n## Maintainers\n\nMaintainers are needed, I cannot keep with all the updates by myself. If you are\ninterested please open a Pull Request.\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to\ndiscuss what you would like to change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielcardeenas%2Fsulla","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielcardeenas%2Fsulla","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielcardeenas%2Fsulla/lists"}