[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10789":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":16,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":16,"starSnapshotCount":16,"syncStatus":32,"lastSyncTime":33,"discoverSource":34},10789,"sulla","danielcardeenas\u002Fsulla","danielcardeenas","👩🏻‍🔬 Javascript Whatsapp api library for chatbots","",null,"JavaScript",1303,273,72,68,0,55.31,"MIT License",false,"master",true,[23,24,25,26,27,28],"bot","chatbot","framework","whatsapp","whatsapp-api","whatsapp-bot","2026-06-12 04:00:52","\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fdanielcardeenas\u002Fsulla\">\n    \u003Cimg width=\"250px\" src=\"https:\u002F\u002Fgithub.com\u002Fdanielcardeenas\u002Fsulla\u002Fblob\u002Fmaster\u002Fimg\u002Flogo.jpg?raw=true\" alt=\"Sulla logo\">\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n# Sulla\n\n[![npm version](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Fsulla.svg?color=%2378e08f)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fsulla)\n![npm type definitions](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Ftypes\u002Fsulla)\n![GitHub last commit](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Fdanielcardeenas\u002Fsulla)\n[![GitHub license](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002Fdanielcardeenas\u002Fsulla)](https:\u002F\u002Fgithub.com\u002Fdanielcardeenas\u002Fsulla\u002Fblob\u002Fmaster\u002FLICENSE)\n[![codebeat badge](https:\u002F\u002Fcodebeat.co\u002Fbadges\u002F7e510d47-8689-49da-abd8-a9a29d106a2b)](https:\u002F\u002Fcodebeat.co\u002Fprojects\u002Fgithub-com-danielcardeenas-sulla-master)\n\n> Sulla is a javascript library which provides a high-level API control to\n> Whatsapp so it can be configured to automatize responses or any data that goes\n> through Whatsapp effortlessly.\n>\n> It is built using [puppeteer](https:\u002F\u002Fgithub.com\u002FGoogleChrome\u002Fpuppeteer)\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> [**venom**](https:\u002F\u002Fgithub.com\u002Forkestral\u002Fvenom)\n> \n> [![last commit](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Forkestral\u002Fvenom)](https:\u002F\u002Fgithub.com\u002Forkestral\u002Fvenom\u002F)\n[![Downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdm\u002Fvenom.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fvenom)\n[![Average time to resolve an issue](https:\u002F\u002Fisitmaintained.com\u002Fbadge\u002Fresolution\u002Forkestral\u002Fvenom.svg)](https:\u002F\u002Fisitmaintained.com\u002Fproject\u002Forkestral\u002Fvenom 'Average time to resolve an issue')\n\n> [**wppconnect**](https:\u002F\u002Fgithub.com\u002Fwppconnect-team\u002Fwppconnect\u002F)\n> \n> [![last commit](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Fwppconnect-team\u002Fwppconnect)](https:\u002F\u002Fgithub.com\u002Fwppconnect-team\u002Fwppconnect\u002F)\n[![Downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdm\u002F@wppconnect-team\u002Fwppconnect.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@wppconnect-team\u002Fwppconnect)\n[![Average time to resolve an issue](https:\u002F\u002Fisitmaintained.com\u002Fbadge\u002Fresolution\u002Fwppconnect-team\u002Fwppconnect.svg)](https:\u002F\u002Fisitmaintained.com\u002Fproject\u002Fwppconnect-team\u002Fwppconnect 'Average time to resolve an issue')\n\n> [**open-wa\u002Fwa-automate**](https:\u002F\u002Fgithub.com\u002Fopen-wa\u002Fwa-automate-nodejs)\n>\n> [![last commit](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Fopen-wa\u002Fwa-automate-nodejs)](https:\u002F\u002Fgithub.com\u002Fopen-wa\u002Fwa-automate-nodejs)\n[![Downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdm\u002F@open-wa\u002Fwa-automate.svg)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@open-wa\u002Fwa-automate)\n[![Average time to resolve an issue](http:\u002F\u002Fisitmaintained.com\u002Fbadge\u002Fresolution\u002Fopen-wa\u002Fwa-automate-nodejs.svg)](http:\u002F\u002Fisitmaintained.com\u002Fproject\u002Fopen-wa\u002Fwa-automate-nodejs \"Average time to resolve an issue\")\n\n## Installation\n\n```bash\n> npm i sulla --save\n```\n\n## Getting started\n\n```javascript\n\u002F\u002F Supports ES6\n\u002F\u002F import { create, Whatsapp } from 'sulla';\nconst sulla = require('sulla');\n\nsulla.create().then((client) => start(client));\n\nfunction start(client) {\n  client.onMessage((message) => {\n    if (message.body === 'Hi') {\n      client.sendText(message.from, '👋 Hello from sulla!');\n    }\n  });\n}\n```\n\n\u003Cimg align=\"left\" src=\"https:\u002F\u002Fgithub.com\u002Fdanielcardeenas\u002Fsulla\u002Fblob\u002Fmaster\u002Fimg\u002Fauth.gif?raw=true\" width=\"370px\">\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\u002F\u002F Init sales whatsapp bot\nsulla.create('sales').then((salesClient) => {...});\n\n\u002F\u002F Init support whatsapp bot\nsulla.create('support').then((supportClient) => {...});\n```\n\n\u003Cbr>\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, \u002F\u002F Headless chrome\n  devtools: false, \u002F\u002F Open devtools by default\n  useChrome: true, \u002F\u002F If false will use Chromium instance\n  debug: false, \u002F\u002F Opens a debug session\n  logQR: true \u002F\u002F Logs QR automatically in terminal\n  browserArgs: [''] \u002F\u002F Parameters to be added into the chrome browser instance\n  refreshQR: 15000, \u002F\u002F 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:\u002F\u002Fgithub.com\u002Fdanielcardeenas\u002Fsulla\u002Fblob\u002Fmaster\u002Fsrc\u002Fconfig\u002Fcreate-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\u002F\u002F Second create() parameter is the QR callback\nsulla.create('session-marketing', (base64Qr, asciiQR) => {\n  \u002F\u002F To log the QR in the terminal\n  console.log(asciiQR);\n\n  \u002F\u002F To write it somewhere else in a file\n  exportQR(base64Qr, 'marketing-qr.png');\n});\n\n\u002F\u002F Writes QR in specified path\nfunction exportQR(qrCode, path) {\n  qrCode = qrCode.replace('data:image\u002Fpng;base64,', '');\n  const imageBuffer = Buffer.from(qrCode, 'base64');\n\n  \u002F\u002F 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) => {\n  if (message.isMedia) {\n    const buffer = await client.downloadFile(message);\n    \u002F\u002F At this point you can do whatever you want with the buffer\n    \u002F\u002F 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](\u002Fsrc\u002Fapi\u002Flayers) and\n[here](\u002Fsrc\u002Flib\u002Fwapi\u002Ffunctions)\n\n### Chatting\n\n##### Here, `chatId` could be `\u003CphoneNumber>@c.us` or `\u003CphoneNumber>-\u003CgroupId>@c.us`\n\n```javascript\n\u002F\u002F Send basic text\nawait client.sendText(chatId, '👋 Hello from sulla!');\n\n\u002F\u002F Send image\nawait client.sendImage(\n  chatId,\n  'path\u002Fto\u002Fimg.jpg',\n  'image-name.jpg',\n  'Caption text'\n);\n\n\u002F\u002F Send @tagged message\nawait client.sendMentioned(chatId, 'Hello @5218113130740 and @5218243160777!', [\n  '5218113130740',\n  '5218243160777',\n]);\n\n\u002F\u002F Reply to a message\nawait client.reply(chatId, 'This is a reply!', message.id.toString());\n\n\u002F\u002F Send file (sulla will take care of mime types, just need the path)\nawait client.sendFile(chatId, 'path\u002Fto\u002Ffile.pdf', 'cv.pdf', 'Curriculum');\n\n\u002F\u002F Send gif\nawait client.sendVideoAsGif(\n  chatId,\n  'path\u002Fto\u002Fvideo.mp4',\n  'video.gif',\n  'Gif image file'\n);\n\n\u002F\u002F Send contact\n\u002F\u002F contactId: 52155334634@c.us\nawait client.sendContact(chatId, contactId);\n\n\u002F\u002F Forwards messages\nawait client.forwardMessages(chatId, [message.id.toString()], true);\n\n\u002F\u002F Send sticker\nawait client.sendImageAsSticker(chatId, 'path\u002Fto\u002Fimage.jpg');\n\n\u002F\u002F Send location\nawait client.sendLocation(\n  chatId,\n  25.6801987,\n  -100.4060626,\n  'Some address, Washington DC',\n  'Subtitle'\n);\n\n\u002F\u002F Send seen ✔️✔️\nawait client.sendSeen(chatId);\n\n\u002F\u002F Start typing...\nawait client.startTyping(chatId);\n\n\u002F\u002F Stop typing\nawait client.stopTyping(chatId);\n\n\u002F\u002F 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\u002F\u002F Retrieve contacts\nconst contacts = await client.getAllContacts();\n\n\u002F\u002F Retrieve all messages in chat\nconst allMessages = await client.loadAndGetAllMessagesInChat(chatId);\n\n\u002F\u002F Retrieve contact status\nconst status = await client.getStatus(contactId);\n\n\u002F\u002F Retrieve user profile\nconst user = await client.getNumberProfile(contactId);\n\n\u002F\u002F Retrieve all unread message\nconst messages = await client.getAllUnreadMessages();\n\n\u002F\u002F Retrieve all chats\nconst chats = await client.getAllChats();\n\n\u002F\u002F Retrieve all groups\nconst chats = await client.getAllGroups();\n\n\u002F\u002F Retrieve profile fic (as url)\nconst url = await client.getProfilePicFromServer(chatId);\n\n\u002F\u002F Retrieve chat\u002Fconversation\nconst chat = await client.getChat(chatId);\n```\n\n### Group functions\n\n```javascript\n\u002F\u002F groupId or chatId: leaveGroup 52123123-323235@g.us\n\n\u002F\u002F Leave group\nawait client.leaveGroup(groupId);\n\n\u002F\u002F Get group members\nawait client.getGroupMembers(groupId);\n\n\u002F\u002F Get group members ids\nawait client.getGroupMembersIds(groupId);\n\n\u002F\u002F Generate group invite url link\nawait client.getGroupInviteLink(groupId);\n\n\u002F\u002F Create group (title, participants to add)\nawait client.createGroup('Group name', ['123123@c.us', '45456456@c.us']);\n\n\u002F\u002F Remove participant\nawait client.removeParticipant(groupId, '123123@c.us');\n\n\u002F\u002F Add participant\nawait client.addParticipant(groupId, '123123@c.us');\n\n\u002F\u002F Promote participant (Give admin privileges)\nawait client.promoteParticipant(groupId, '123123@c.us');\n\n\u002F\u002F Demote particiapnt (Revoke admin privileges)\nawait client.demoteParticipant(groupId, '123123@c.us');\n\n\u002F\u002F Get group admins\nawait client.getGroupAdmins(groupId);\n```\n\n### Profile functions\n\n```javascript\n\u002F\u002F Set client status\nawait client.setProfileStatus('On vacations! ✈️');\n\n\u002F\u002F Set client profile name\nawait client.setProfileName('Sulla bot');\n```\n\n### Device functions\n\n```javascript\n\u002F\u002F Get device info\nawait client.getHostDevice();\n\n\u002F\u002F Get connection state\nawait client.getConnectionState();\n\n\u002F\u002F Get battery level\nawait client.getBatteryLevel();\n\n\u002F\u002F Is connected\nawait client.isConnected();\n\n\u002F\u002F Get whatsapp web version\nawait client.getWAVersion();\n```\n\n### Events\n\n```javascript\n\u002F\u002F Listen to messages\nclient.onMessage(message => {\n  ...\n})\n\n\u002F\u002F Listen to state changes\nclient.onStateChange(state => {\n  ...\n});\n\n\u002F\u002F Listen to ack's\nclient.onAck(ack => {\n  ...\n});\n\n\u002F\u002F Listen to live location\n\u002F\u002F chatId: 'phone@c.us'\nclient.onLiveLocation(chatId, (liveLocation) => {\n  ...\n});\n\n\u002F\u002F chatId looks like this: '5518156745634-1516512045@g.us'\n\u002F\u002F Event interface is in here: https:\u002F\u002Fgithub.com\u002Fdanielcardeenas\u002Fsulla\u002Fblob\u002Fmaster\u002Fsrc\u002Fapi\u002Fmodel\u002Fparticipant-event.ts\nclient.onParticipantsChanged(chatId, (event) => {\n  ...\n});\n\n\u002F\u002F Listen when client has been added to a group\nclient.onAddedToGroup(chatEvent => {\n  ...\n});\n\n```\n\n### Other\n\n```javascript\n\u002F\u002F Delete chat\nawait client.deleteChat(chatId);\n\n\u002F\u002F Clear chat messages\nawait client.clearChat(chatId);\n\n\u002F\u002F Delete message (last parameter: delete only locally)\nawait client.deleteMessage(chatId, message.id.toString(), false);\n\n\u002F\u002F Retrieve a number profile \u002F 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\u002F\u002F In case of being logged out of whatsapp web\n\u002F\u002F Force it to keep the current session\n\u002F\u002F State change\nclient.onStateChange((state) => {\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:\u002F\u002Ffaq.whatsapp.com\u002Fen\u002F26000030\u002F) 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 () => {\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\u002F\u002F Catch ctrl+C\nprocess.on('SIGINT', function() {\n  client.close();\n});\n\n\u002F\u002F 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> npm run build:wapi\n```\n\n2. Middleeware\n\n```bash\n> npm run build:build:middleware\n> npm run build:jsQR\n```\n\n3. Sulla\n\n```bash\n> npm run build:sulla\n```\n\nTo build the entire project just run\n\n```bash\n> 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","Sulla 是一个用于创建 WhatsApp 聊天机器人的 JavaScript 库。它基于 Puppeteer 构建，提供了一套高层级的 API 来控制 WhatsApp，使得自动化响应或处理通过 WhatsApp 传递的数据变得简单高效。Sulla 的主要功能包括消息发送、接收及管理联系人等，支持多种消息类型如文本、图片和视频等。尽管 Sulla 本身已经相当成熟稳定，但目前维护者建议用户考虑使用一些活跃维护的分支项目，例如 venom、wppconnect 和 open-wa\u002Fwa-automate，这些项目提供了更多的功能更新和技术支持。此工具非常适合需要在 WhatsApp 上实现客户服务自动化、市场推广或是任何希望通过 WhatsApp 进行自动通信的应用场景。",2,"2026-06-11 03:30:11","top_topic"]