{"id":16968679,"url":"https://github.com/alien-alfa/baileys","last_synced_at":"2026-05-10T02:09:52.660Z","repository":{"id":103094564,"uuid":"466534137","full_name":"Alien-Alfa/baileys","owner":"Alien-Alfa","description":null,"archived":false,"fork":false,"pushed_at":"2022-03-05T18:22:23.000Z","size":307,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T18:21:19.371Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/Alien-Alfa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-05T18:20:07.000Z","updated_at":"2023-10-02T23:59:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"2520fb68-3ae3-4ca1-a06c-e2731f7e3cf0","html_url":"https://github.com/Alien-Alfa/baileys","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Alien-Alfa/baileys","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alien-Alfa%2Fbaileys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alien-Alfa%2Fbaileys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alien-Alfa%2Fbaileys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alien-Alfa%2Fbaileys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alien-Alfa","download_url":"https://codeload.github.com/Alien-Alfa/baileys/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alien-Alfa%2Fbaileys/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261917439,"owners_count":23229918,"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":[],"created_at":"2024-10-14T00:12:58.731Z","updated_at":"2026-05-10T02:09:52.585Z","avatar_url":"https://github.com/Alien-Alfa.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Baileys - Typescript/Javascript WhatsApp Web API\n \n Baileys does not require Selenium or any other browser to be interface with WhatsApp Web, it does so directly using a **WebSocket**. Not running Selenium or Chromimum saves you like **half a gig** of ram :/ \n\n Thank you to [@Sigalor](https://github.com/sigalor/whatsapp-web-reveng) for writing his observations on the workings of WhatsApp Web and thanks to [@Rhymen](https://github.com/Rhymen/go-whatsapp/) for the __go__ implementation.\n\n Baileys is type-safe, extensible and simple to use. If you require more functionality than provided, it'll super easy for you to write an extension. More on this [here](#writing-custom-functionality).\n \n If you're interested in building a WhatsApp bot, you may wanna check out [WhatsAppInfoBot](https://github.com/adiwajshing/WhatsappInfoBot) and an actual bot built with it, [Messcat](https://github.com/ashokatechmin/Messcat).\n \n **Read the docs [here](https://adiwajshing.github.io/Baileys)**\n **Join the Discord [here](https://discord.gg/7FYURJyqng)**\n\n## Example\nDo check out \u0026 run [example.ts](Example/example.ts) to see example usage of the library.\nThe script covers most common use cases.\nTo run the example script, download or clone the repo and then type the following in terminal:\n1. ``` cd path/to/Baileys ```\n2. ``` npm install ```\n3. ``` npm run example ```\n\n## Install\nCreate and cd to your NPM project directory and then in terminal, write: \n1. stable: `npm install @adiwajshing/baileys`\n2. stabl-ish w quicker fixes \u0026 latest features: `npm install github:adiwajshing/baileys` \n\nDo note, the library will likely vary if you're using the NPM package, read that [here](https://www.npmjs.com/package/@adiwajshing/baileys)\n\nThen import in your code using:\n``` ts \nimport { WAConnection } from '@adiwajshing/baileys'\n```\n\n## Unit Tests\nBaileys also comes with a unit test suite. Simply cd into the Baileys directory \u0026 run `npm test`.\n\nYou will require a phone with WhatsApp to test, and a second WhatsApp number to send messages to.\nSet the phone number you can randomly send messages to in a `.env` file with `TEST_JID=1234@s.whatsapp.net` \n\n## Connecting\n``` ts\nimport { WAConnection } from '@adiwajshing/baileys'\n\nasync function connectToWhatsApp () {\n    const conn = new WAConnection() \n    // called when WA sends chats\n    // this can take up to a few minutes if you have thousands of chats!\n    conn.on('chats-received', async ({ hasNewChats }) =\u003e {\n        console.log(`you have ${conn.chats.length} chats, new chats available: ${hasNewChats}`)\n\n        const unread = await conn.loadAllUnreadMessages ()\n        console.log (\"you have \" + unread.length + \" unread messages\")\n    })\n    // called when WA sends chats\n    // this can take up to a few minutes if you have thousands of contacts!\n    conn.on('contacts-received', () =\u003e {\n        console.log('you have ' + Object.keys(conn.contacts).length + ' contacts')\n    })\n\n    await conn.connect ()\n    conn.on('chat-update', chatUpdate =\u003e {\n        // `chatUpdate` is a partial object, containing the updated properties of the chat\n        // received a new message\n        if (chatUpdate.messages \u0026\u0026 chatUpdate.count) {\n            const message = chatUpdate.messages.all()[0]\n            console.log (message)\n        } else console.log (chatUpdate) // see updates (can be archived, pinned etc.)\n    })\n}\n// run in main file\nconnectToWhatsApp ()\n.catch (err =\u003e console.log(\"unexpected error: \" + err) ) // catch any errors\n``` \n\nIf the connection is successful, you will see a QR code printed on your terminal screen, scan it with WhatsApp on your phone and you'll be logged in!\n\nDo note, the `conn.chats` object is a [KeyedDB](https://github.com/adiwajshing/keyed-db). This is done for the following reasons:\n- Most applications require chats to be ordered in descending order of time. (`KeyedDB` does this in `log(N)` time)\n- Most applications require pagination of chats (Use `chats.paginated()`)\n- Most applications require **O(1)** access to chats via the chat ID. (Use `chats.get(jid)` with `KeyedDB`)\n\n## Configuring the Connection\n\nYou can configure the connection via the `connectOptions` property. You can even specify an HTTPS proxy. For example:\n\n``` ts\nimport { WAConnection, ProxyAgent } from '@adiwajshing/baileys'\n\nconst conn = new WAConnecion ()\nconn.connectOptions.agent = ProxyAgent ('http://some-host:1234')\n\nawait conn.connect ()\nconsole.log (\"oh hello \" + conn.user.name + \"! You connected via a proxy\")\n```\n\nThe entire `WAConnectOptions` struct is mentioned here with default values:\n``` ts\nconn.connectOptions = {\n    /** fails the connection if no data is received for X seconds */\n    maxIdleTimeMs?: 60_000,\n    /** maximum attempts to connect */\n    maxRetries?: 10,\n    /** max time for the phone to respond to a connectivity test */\n    phoneResponseTime?: 15_000,\n    /** minimum time between new connections */\n    connectCooldownMs?: 4000,\n    /** agent used for WS connections (could be a proxy agent) */\n    agent?: Agent = undefined,\n    /** agent used for fetch requests -- uploading/downloading media */\n    fetchAgent?: Agent = undefined,\n    /** always uses takeover for connecting */\n    alwaysUseTakeover: true\n\t/** log QR to terminal */\n    logQR: true\n} as WAConnectOptions\n```\n\n## Saving \u0026 Restoring Sessions\n\nYou obviously don't want to keep scanning the QR code every time you want to connect. \n\nSo, you can save the credentials to log back in via:\n``` ts\nimport * as fs from 'fs'\n\nconst conn = new WAConnection() \n// this will be called as soon as the credentials are updated\nconn.on ('open', () =\u003e {\n    // save credentials whenever updated\n    console.log (`credentials updated!`)\n    const authInfo = conn.base64EncodedAuthInfo() // get all the auth info we need to restore this session\n    fs.writeFileSync('./auth_info.json', JSON.stringify(authInfo, null, '\\t')) // save this info to a file\n})\nawait conn.connect() // connect\n```\n\nThen, to restore a session:\n``` ts\nconst conn = new WAConnection() \nconn.loadAuthInfo ('./auth_info.json') // will load JSON credentials from file\nawait conn.connect() \n// yay connected without scanning QR\n/*\n    Optionally, you can load the credentials yourself from somewhere \n    \u0026 pass in the JSON object to loadAuthInfo () as well.\n*/\n```\n\nIf you're considering switching from a Chromium/Puppeteer based library, you can use WhatsApp Web's Browser credentials to restore sessions too:\n``` ts\nconn.loadAuthInfo ('./auth_info_browser.json')\nawait conn.connect() // works the same\n```\nSee the browser credentials type in the docs.\n\n**Note**: Upon every successive connection, WA can update part of the stored credentials. Whenever that happens, the credentials are uploaded, and you should probably update your saved credentials upon receiving the `open` event. Not doing so *may* lead WA to log you out after a few weeks with a 419 error code.\n\n## QR Callback\n\nIf you want to do some custom processing with the QR code used to authenticate, you can register for the following event:\n``` ts\nconn.on('qr', qr =\u003e {\n    // Now, use the 'qr' string to display in QR UI or send somewhere\n}\nawait conn.connect ()\n```\n\n## Handling Events\n\nBaileys now uses the EventEmitter syntax for events. \nThey're all nicely typed up, so you shouldn't have any issues with an Intellisense editor like VS Code.\n\nAlso, these events are fired regardless of whether they are initiated by the Baileys client or are relayed from your phone.\n\n``` ts\n/** when the connection has opened successfully */\non (event: 'open', listener: (result: WAOpenResult) =\u003e void): this\n/** when the connection is opening */\non (event: 'connecting', listener: () =\u003e void): this\n/** when the connection has closed */\non (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) =\u003e void): this\n/** when the socket is closed */\non (event: 'ws-close', listener: (err: {reason?: DisconnectReason | string}) =\u003e void): this\n/** when a new QR is generated, ready for scanning */\non (event: 'qr', listener: (qr: string) =\u003e void): this\n/** when the connection to the phone changes */\non (event: 'connection-phone-change', listener: (state: {connected: boolean}) =\u003e void): this\n/** when a contact is updated */\non (event: 'contact-update', listener: (update: WAContactUpdate) =\u003e void): this\n/** when a new chat is added */\non (event: 'chat-new', listener: (chat: WAChat) =\u003e void): this\n/** when contacts are sent by WA */\non (event: 'contacts-received', listener: (u: { updatedContacts: Partial\u003cWAContact\u003e[] }) =\u003e void): this\n/** when chats are sent by WA, and when all messages are received */\non (event: 'chats-received', listener: (update: {hasNewChats?: boolean}) =\u003e void): this\n/** when all initial messages are received from WA */\non (event: 'initial-data-received', listener: (update: {chatsWithMissingMessages: { jid: string, count: number }[] }) =\u003e void): this\n/** when multiple chats are updated (new message, updated message, deleted, pinned, etc) */\non (event: 'chats-update', listener: (chats: WAChatUpdate[]) =\u003e void): this\n/** when a chat is updated (new message, updated message, read message, deleted, pinned, presence updated etc) */\non (event: 'chat-update', listener: (chat: WAChatUpdate) =\u003e void): this\n/** when participants are added to a group */\non (event: 'group-participants-update', listener: (update: {jid: string, participants: string[], actor?: string, action: WAParticipantAction}) =\u003e void): this\n/** when the group is updated */\non (event: 'group-update', listener: (update: Partial\u003cWAGroupMetadata\u003e \u0026 {jid: string, actor?: string}) =\u003e void): this\n/** when WA sends back a pong */\non (event: 'received-pong', listener: () =\u003e void): this\n/** when a user is blocked or unblockd */\non (event: 'blocklist-update', listener: (update: BlocklistUpdate) =\u003e void): this\n```\n\n## Sending Messages\n\nSend like, all types of messages with a single function:\n``` ts\nimport { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys'\n\nconst id = 'abcd@s.whatsapp.net' // the WhatsApp ID \n// send a simple text!\nconn.sendMessage (id, 'oh hello there', MessageType.text)\n// send a location!\nconn.sendMessage(id, {degreesLatitude: 24.121231, degreesLongitude: 55.1121221}, MessageType.location)\n// send a contact!\nconst vcard = 'BEGIN:VCARD\\n' // metadata of the contact card\n            + 'VERSION:3.0\\n' \n            + 'FN:Jeff Singh\\n' // full name\n            + 'ORG:Ashoka Uni;\\n' // the organization of the contact\n            + 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\\n' // WhatsApp ID + phone number\n            + 'END:VCARD'\nconn.sendMessage(id, {displayname: \"Jeff\", vcard: vcard}, MessageType.contact)\n// send a gif\nconst buffer = fs.readFileSync(\"Media/ma_gif.mp4\") // load some gif\nconst options: MessageOptions = {mimetype: Mimetype.gif, caption: \"hello!\"} // some metadata \u0026 caption\nconn.sendMessage(id, buffer, MessageType.video, options)\nconst sentMsg  = await conn.sendMessage(id, {displayname: \"Jeff\", vcard: vcard}, MessageType.contact)\n// send a list message!\nconst rows = [\n {title: 'Row 1', description: \"Hello it's description 1\", rowId:\"rowid1\"},\n {title: 'Row 2', description: \"Hello it's description 2\", rowId:\"rowid2\"}\n]\n\nconst sections = [{title: \"Section 1\", rows: rows}]\n\nconst button = {\n buttonText: 'Click Me!',\n description: \"Hello it's list message\",\n sections: sections,\n listType: 1\n}\n\nconst sendMsg = await conn.sendMessage(id, button, MessageType.listMessage)\n\n// send a buttons message!\nconst buttons = [\n  {buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1},\n  {buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1}\n]\n\nconst buttonMessage = {\n    contentText: \"Hi it's button message\",\n    footerText: 'Hello World',\n    buttons: buttons,\n    headerType: 1\n}\n\nconst sendMsg = await conn.sendMessage(id, buttonMessage, MessageType.buttonsMessage)\n```\n\n### Media Messages\n\nSending media (video, stickers, images) is easier \u0026 more efficient than ever. \n- You can specify a buffer, a local url or even a remote url.\n- When specifying a media url, Baileys never loads the entire buffer into memory, it even encrypts the media as a readable stream.\n\n``` ts\nimport { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys'\n// Sending gifs\nawait conn.sendMessage(\n    id, \n    fs.readFileSync(\"Media/ma_gif.mp4\"), // load a gif and send it\n    MessageType.video, \n    { mimetype: Mimetype.gif, caption: \"hello!\" }\n)\nawait conn.sendMessage(\n    id, \n    { url: 'Media/ma_gif.mp4' }, // send directly from local file\n    MessageType.video, \n    { mimetype: Mimetype.gif, caption: \"hello!\" }\n)\n\nawait conn.sendMessage(\n    id, \n    { url: 'https://giphy.com/gifs/11JTxkrmq4bGE0/html5' }, // send directly from remote url!\n    MessageType.video, \n    { mimetype: Mimetype.gif, caption: \"hello!\" }\n)\n\n// send an audio file\nconst buffer = fs.readFileSync(\"Media/audio.mp3\") // can send mp3, mp4, \u0026 ogg\nconst options: MessageOptions = {mimetype: Mimetype.mp4Audio} // some metadata (can't have caption in audio)\nconn.sendMessage(id, buffer, MessageType.audio, options)\n```\n\nTo note:\n- `id` is the WhatsApp ID of the person or group you're sending the message to. \n    - It must be in the format ```[country code without +][phone number]@s.whatsapp.net```, for example ```19999999999@s.whatsapp.net``` for people. For groups, it must be in the format ``` 123456789-123345@g.us ```. \n    - For broadcast lists it's `[timestamp of creation]@broadcast`.\n    - For stories, the ID is `status@broadcast`.\n- For media messages, the thumbnail can be generated automatically for images \u0026 stickers. Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system.\n- **MessageOptions**: some extra info about the message. It can have the following __optional__ values:\n    ``` ts\n    const info: MessageOptions = {\n        quoted: quotedMessage, // the message you want to quote\n        contextInfo: { forwardingScore: 2, isForwarded: true }, // some random context info (can show a forwarded message with this too)\n        timestamp: Date(), // optional, if you want to manually set the timestamp of the message\n        caption: \"hello there!\", // (for media messages) the caption to send with the media (cannot be sent with stickers though)\n        thumbnail: \"23GD#4/==\", /*  (for location \u0026 media messages) has to be a base 64 encoded JPEG if you want to send a custom thumb, \n                                    or set to null if you don't want to send a thumbnail.\n                                    Do not enter this field if you want to automatically generate a thumb\n                                */\n        mimetype: Mimetype.pdf, /* (for media messages) specify the type of media (optional for all media types except documents),\n                                    import {Mimetype} from '@adiwajshing/baileys'\n                                */\n        filename: 'somefile.pdf', // (for media messages) file name for the media\n        /* will send audio messages as voice notes, if set to true */\n        ptt: true,\n        // will detect links \u0026 generate a link preview automatically (default true)\n        detectLinks: true,\n        /** Should it send as a disappearing messages. \n         * By default 'chat' -- which follows the setting of the chat */\n        sendEphemeral: 'chat'\n    }\n    ```\n## Forwarding Messages\n\n``` ts\nconst messages = await conn.loadConversation ('1234@s.whatsapp.net', 1)\nconst message = messages[0] // get the last message from this conversation\nawait conn.forwardMessage ('455@s.whatsapp.net', message) // WA forward the message!\n```\n\n## Reading Messages\n\n``` ts \nconst id = '1234-123@g.us'\nconst messageID = 'AHASHH123123AHGA' // id of the message you want to read\n\nawait conn.chatRead (id) // mark all messages in chat as read (equivalent of opening a chat in WA)\nawait conn.chatRead (id, 'unread') // mark the chat as unread\n```\n\nThe message ID is the unique identifier of the message that you are marking as read. On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```.\n\n## Update Presence\n\n``` ts\nimport { Presence } from '@adiwajshing/baileys'\nawait conn.updatePresence(id, Presence.available) \n\n```\nThis lets the person/group with ``` id ``` know whether you're online, offline, typing etc. where ``` presence ``` can be one of the following:\n``` ts\nexport enum Presence {\n    available = 'available', // \"online\"\n    composing = 'composing', // \"typing...\"\n    recording = 'recording', // \"recording...\"\n    paused = 'paused' // stopped typing, back to \"online\"\n}\n```\n\nThe presence expires after about 10 seconds.\n\n## Downloading Media Messages\n\nIf you want to save the media you received\n``` ts\nimport { MessageType } from '@adiwajshing/baileys'\nconn.on ('message-new', async m =\u003e {\n    if (!m.message) return // if there is no text or media message\n    const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video\n    // if the message is not a text message\n    if (messageType !== MessageType.text \u0026\u0026 messageType !== MessageType.extendedText) {\n        const buffer = await conn.downloadMediaMessage(m) // to decrypt \u0026 use as a buffer\n        \n        const savedFilename = await conn.downloadAndSaveMediaMessage (m) // to decrypt \u0026 save to file\n        console.log(m.key.remoteJid + \" sent media, saved at: \" + savedFilename)\n    }\n}\n```\n\n## Deleting Messages\n\n``` ts\nconst jid = '1234@s.whatsapp.net' // can also be a group\nconst response = await conn.sendMessage (jid, 'hello!', MessageType.text) // send a message\n\nawait conn.deleteMessage (jid, {id: response.messageID, remoteJid: jid, fromMe: true}) // will delete the sent message for everyone!\nawait conn.clearMessage (jid, {id: response.messageID, remoteJid: jid, fromMe: true}) // will delete the sent message for only you!\n```\n\n## Modifying Chats\n\n``` ts\nconst jid = '1234@s.whatsapp.net' // can also be a group\nawait conn.modifyChat (jid, ChatModification.archive) // archive chat\nawait conn.modifyChat (jid, ChatModification.unarchive) // unarchive chat\n\nconst response = await conn.modifyChat (jid, ChatModification.pin) // pin the chat\nawait conn.modifyChat (jid, ChatModification.unpin) // unpin it\n\nawait conn.modifyChat (jid, ChatModification.mute, 8*60*60*1000) // mute for 8 hours\nsetTimeout (() =\u003e {\n    conn.modifyChat (jid, ChatModification.unmute)\n}, 5000) // unmute after 5 seconds\n\nawait conn.modifyChat (jid, ChatModification.delete) // will delete the chat (can be a group or broadcast list as well)\n```\n\n**Note:** to unmute or unpin a chat, one must pass the timestamp of the pinning or muting. This is returned by the pin \u0026 mute functions. This is also available in the `WAChat` objects of the respective chats, as a `mute` or `pin` property.\n\n## Disappearing Messages\n\n``` ts\nconst jid = '1234@s.whatsapp.net' // can also be a group\n// turn on disappearing messages\nawait conn.toggleDisappearingMessages(\n    jid, \n    WA_DEFAULT_EPHEMERAL // this is 1 week in seconds -- how long you want messages to appear for\n) \n// will automatically send as a disappearing message\nawait conn.sendMessage(jid, 'Hello poof!', MessageType.text)\n// turn off disappearing messages\nawait conn.toggleDisappearingMessages(jid, 0)\n\n```\n\n## Misc\n\n- To load chats in a paginated manner\n    ``` ts\n    const {chats, cursor} = await conn.loadChats (25)\n    if (cursor) {\n        const moreChats = await conn.loadChats (25, cursor) // load the next 25 chats\n    }\n    ```\n- To check if a given ID is on WhatsApp\n    Note: this method falls back to using `https://wa.me` to determine whether a number is on WhatsApp in case the WebSocket connection is not open yet.\n    ``` ts\n    const id = '123456'\n    const exists = await conn.isOnWhatsApp (id)\n    if (exists) console.log (`${id} exists on WhatsApp, as jid: ${exists.jid}`)\n    ```\n- To query chat history on a group or with someone\n    ``` ts\n    // query the last 25 messages (replace 25 with the number of messages you want to query)\n    const messages = await conn.loadMessages (\"xyz-abc@g.us\", 25)\n    console.log(\"got back \" + messages.length + \" messages\")\n    ```\n    You can also load the entire conversation history if you want\n    ``` ts\n    await conn.loadAllMessages (\"xyz@c.us\", message =\u003e console.log(\"Loaded message with ID: \" + message.key.id))\n    console.log(\"queried all messages\") // promise resolves once all messages are retrieved\n    ```\n- To get the status of some person\n    ``` ts\n    const status = await conn.getStatus (\"xyz@c.us\") // leave empty to get your own status\n    console.log(\"status: \" + status)\n    ```\n- To get the display picture of some person/group\n    ``` ts\n    const ppUrl = await conn.getProfilePicture (\"xyz@g.us\") // leave empty to get your own\n    console.log(\"download profile picture from: \" + ppUrl)\n    ```\n- To change your display picture or a group's\n    ``` ts\n    const jid = '111234567890-1594482450@g.us' // can be your own too\n    const img = fs.readFileSync ('new-profile-picture.jpeg') // can be PNG also\n    await conn.updateProfilePicture (jid, img)\n    ```\n- To get someone's presence (if they're typing, online)\n    ``` ts\n    // the presence update is fetched and called here\n    conn.on ('CB:Presence', json =\u003e console.log(json.id + \" presence is \" + json.type))\n    await conn.requestPresenceUpdate (\"xyz@c.us\") // request the update\n    ```\n- To search through messages\n    ``` ts\n    const response = await conn.searchMessages ('so cool', null, 25, 1) // search in all chats\n    console.log (`got ${response.messages.length} messages in search`)\n\n    const response2 = await conn.searchMessages ('so cool', '1234@c.us', 25, 1) // search in given chat\n    ```\n- To block or unblock user\n    ``` ts\n    await conn.blockUser (\"xyz@c.us\", \"add\") // Block user\n    await conn.blockUser (\"xyz@c.us\", \"remove\") // Unblock user\n    ```\nOf course, replace ``` xyz ``` with an actual ID. \n\n## Groups\n- To create a group\n    ``` ts\n    // title \u0026 participants\n    const group = await conn.groupCreate (\"My Fab Group\", [\"abcd@s.whatsapp.net\", \"efgh@s.whatsapp.net\"])\n    console.log (\"created group with id: \" + group.gid)\n    conn.sendMessage(group.gid, \"hello everyone\", MessageType.extendedText) // say hello to everyone on the group\n    ```\n- To add people to a group\n    ``` ts\n    // id \u0026 people to add to the group (will throw error if it fails)\n    const response = await conn.groupAdd (\"abcd-xyz@g.us\", [\"abcd@s.whatsapp.net\", \"efgh@s.whatsapp.net\"])\n    ```\n- To make/demote admins on a group\n    ``` ts\n    // id \u0026 people to make admin (will throw error if it fails)\n    await conn.groupMakeAdmin (\"abcd-xyz@g.us\", [\"abcd@s.whatsapp.net\", \"efgh@s.whatsapp.net\"])\n    await conn.groupDemoteAdmin (\"abcd-xyz@g.us\", [\"abcd@s.whatsapp.net\", \"efgh@s.whatsapp.net\"]) // demote admins\n    ```\n- To change the group's subject\n    ``` ts\n    await conn.groupUpdateSubject(\"abcd-xyz@g.us\", \"New Subject!\")\n    ```\n- To change the group's description\n    ``` ts\n    await conn.groupUpdateDescription(\"abcd-xyz@g.us\", \"This group has a new description\")\n    ```\n- To change group settings\n    ``` ts\n    import { GroupSettingChange } from '@adiwajshing/baileys'\n    // only allow admins to send messages\n    await conn.groupSettingChange (\"abcd-xyz@g.us\", GroupSettingChange.messageSend, true)\n    // allow everyone to modify the group's settings -- like display picture etc.\n    await conn.groupSettingChange (\"abcd-xyz@g.us\", GroupSettingChange.settingsChange, false)\n    // only allow admins to modify the group's settings\n    await conn.groupSettingChange (\"abcd-xyz@g.us\", GroupSettingChange.settingsChange, true)\n    ```\n- To leave a group\n    ``` ts\n    await conn.groupLeave (\"abcd-xyz@g.us\") // (will throw error if it fails)\n    ```\n- To get the invite code for a group\n    ``` ts\n    const code = await conn.groupInviteCode (\"abcd-xyz@g.us\")\n    console.log(\"group code: \" + code)\n    ```\n- To query the metadata of a group\n    ``` ts\n    const metadata = await conn.groupMetadata (\"abcd-xyz@g.us\") \n    console.log(json.id + \", title: \" + json.subject + \", description: \" + json.desc)\n\n    // Or if you've left the group -- call this\n    const metadata2 = await conn.groupMetadataMinimal (\"abcd-xyz@g.us\") \n    ```\n- To join the group using the invitation code\n    ``` ts\n    const response = await conn.acceptInvite (\"xxx\")\n    console.log(\"joined to: \" + response.gid)\n    ```\n    Of course, replace ``` xxx ``` with invitation code.\n- To revokes the current invite link of a group\n    ``` ts\n    const response = await conn.revokeInvite (\"abcd-xyz@g.us\")\n    console.log(\"new group code: \" + response.code)\n    ```\n\n## Broadcast Lists \u0026 Stories\n\n- You can send messages to broadcast lists the same way you send messages to groups \u0026 individual chats.\n- Unfortunately, WA Web does not support creating broadcast lists right now but you can still delete them.\n- Broadcast IDs are in the format `12345678@broadcast`\n- To query a broadcast list's recipients \u0026 name:\n    ``` ts\n    const bList = await conn.getBroadcastListInfo (\"1234@broadcast\")\n    console.log (`list name: ${bList.name}, recps: ${bList.recipients}`)\n    ```\n\n## Writing Custom Functionality\nBaileys is written, keeping in mind, that you may require other custom functionality. Hence, instead of having to fork the project \u0026 re-write the internals, you can simply write extensions in your own code.\n\nFirst, enable the logging of unhandled messages from WhatsApp by setting\n``` ts\nconn.logger.level = 'debug'\n```\nThis will enable you to see all sorts of messages WhatsApp sends in the console. Some examples:\n\n1. Functionality to track of the battery percentage of your phone.\n    You enable logging and you'll see a message about your battery pop up in the console: \n    ```s22, [\"action\",null,[[\"battery\",{\"live\":\"false\",\"value\":\"52\"},null]]] ``` \n    \n    You now know what a battery update looks like. It'll have the following characteristics.\n    - Given ```const bMessage = [\"action\",null,[[\"battery\",{\"live\":\"false\",\"value\":\"52\"},null]]]```\n    - ```bMessage[0]``` is always ``` \"action\" ```\n    - ```bMessage[1]``` is always ``` null ```\n    - ```bMessage[2][0][0]``` is always ``` \"battery\" ```\n\n    Hence, you can register a callback for an event using the following:\n    ``` ts\n    conn.on (`CB:action,,battery`, json =\u003e {\n        const batteryLevelStr = json[2][0][1].value\n        const batterylevel = parseInt (batteryLevelStr)\n        console.log (\"battery level: \" + batterylevel + \"%\")\n    })\n    ```\n    This callback will be fired any time a message is received matching the following criteria:\n    ``` message [0] === \"action\" \u0026\u0026 message [1] === null \u0026\u0026 message[2][0][0] === \"battery\" ```\n2. Functionality to keep track of the pushname changes on your phone.\n    You enable logging and you'll see an unhandled message about your pushanme pop up like this: \n    ```s24, [\"Conn\",{\"pushname\":\"adiwajshing\"}]``` \n    \n    You now know what a pushname update looks like. It'll have the following characteristics.\n    - Given ```const pMessage = [\"Conn\",{\"pushname\":\"adiwajshing\"}] ```\n    - ```pMessage[0]``` is always ``` \"Conn\" ```\n    - ```pMessage[1]``` always has the key ``` \"pushname\" ```\n    - ```pMessage[2]``` is always ``` undefined ```\n\n    Following this, one can implement the following callback:\n    ``` ts\n    conn.on ('CB:Conn,pushname', json =\u003e {\n        const pushname = json[1].pushname\n        conn.user.name = pushname // update on client too\n        console.log (\"Name updated: \" + pushname)\n    })\n    ```\n    This callback will be fired any time a message is received matching the following criteria:\n    ``` message [0] === \"Conn\" \u0026\u0026 message [1].pushname ```\n\nA little more testing will reveal that almost all WhatsApp messages are in the format illustrated above. \nNote: except for the first parameter (in the above cases, ```\"action\"``` or ```\"Conn\"```), all the other parameters are optional.\n\n### Note\n This library was originally a project for **CS-2362 at Ashoka University** and is in no way affiliated with WhatsApp. Use at your own discretion. Do not spam people with this.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falien-alfa%2Fbaileys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falien-alfa%2Fbaileys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falien-alfa%2Fbaileys/lists"}