Skip to content

Commit

Permalink
Release v1.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
giuseppecastaldo committed Jul 7, 2023
1 parent b06ec49 commit f8225ac
Show file tree
Hide file tree
Showing 63 changed files with 35,234 additions and 4,706 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file modified whatsapp_addon/.DS_Store
Binary file not shown.
9 changes: 9 additions & 0 deletions whatsapp_addon/Baileys/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## 6.2.1 (2023-06-07)


### Bug Fixes

* updated proto/version to v2.2323.4 ([#96](https://github.com/WhiskeySockets/Baileys/issues/96)) ([63575e9](https://github.com/WhiskeySockets/Baileys/commit/63575e9b85520bd7621bd16ac0508cdd523a3a43))



124 changes: 108 additions & 16 deletions whatsapp_addon/Baileys/Example/example.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { Boom } from '@hapi/boom'
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, isJidBroadcast, makeCacheableSignalKeyStore, makeInMemoryStore, MessageRetryMap, useMultiFileAuthState } from '../src'
import parsePhoneNumber from 'libphonenumber-js'
import NodeCache from 'node-cache'
import readline from 'readline'
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, getAggregateVotesInPollMessage, makeCacheableSignalKeyStore, makeInMemoryStore, PHONENUMBER_MCC, proto, useMultiFileAuthState, WAMessageContent, WAMessageKey } from '../src'
import MAIN_LOGGER from '../src/Utils/logger'

const logger = MAIN_LOGGER.child({ })
const logger = MAIN_LOGGER.child({})
logger.level = 'trace'

const useStore = !process.argv.includes('--no-store')
const doReplies = !process.argv.includes('--no-reply')
const useMobile = process.argv.includes('--mobile')

// external map to store retry counts of messages when decryption/encryption fails
// keep this out of the socket itself, so as to prevent a message decryption/encryption loop across socket restarts
const msgRetryCounterMap: MessageRetryMap = { }
const msgRetryCounterCache = new NodeCache()

// the store maintains the data of the WA connection in memory
// can be written out to a file & read from it
Expand All @@ -32,31 +36,83 @@ const startSock = async() => {
version,
logger,
printQRInTerminal: true,
mobile: useMobile,
auth: {
creds: state.creds,
/** caching makes the store faster to send/recv messages */
keys: makeCacheableSignalKeyStore(state.keys, logger),
},
msgRetryCounterMap,
msgRetryCounterCache,
generateHighQualityLinkPreview: true,
// ignore all broadcast messages -- to receive the same
// comment the line below out
shouldIgnoreJid: jid => isJidBroadcast(jid),
// implement to handle retries
getMessage: async key => {
if(store) {
const msg = await store.loadMessage(key.remoteJid!, key.id!)
return msg?.message || undefined
// shouldIgnoreJid: jid => isJidBroadcast(jid),
// implement to handle retries & poll updates
getMessage,
})

store?.bind(sock.ev)

// If mobile was chosen, ask for the code
if(useMobile && !sock.authState.creds.registered) {
const question = (text: string) => new Promise<string>((resolve) => rl.question(text, resolve))

const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
const { registration } = sock.authState.creds || { registration: {} }

if(!registration.phoneNumber) {
registration.phoneNumber = await question('Please enter your mobile phone number:\n')
}

const phoneNumber = parsePhoneNumber(registration!.phoneNumber)
if(!phoneNumber?.isValid()) {
throw new Error('Invalid phone number: ' + registration!.phoneNumber)
}

registration.phoneNumber = phoneNumber.format('E.164')
registration.phoneNumberCountryCode = phoneNumber.countryCallingCode
registration.phoneNumberNationalNumber = phoneNumber.nationalNumber
const mcc = PHONENUMBER_MCC[phoneNumber.countryCallingCode]
if(!mcc) {
throw new Error('Could not find MCC for phone number: ' + registration!.phoneNumber + '\nPlease specify the MCC manually.')
}

registration.phoneNumberMobileCountryCode = mcc

async function enterCode() {
try {
const code = await question('Please enter the one time code:\n')
const response = await sock.register(code.replace(/["']/g, '').trim().toLowerCase())
console.log('Successfully registered your phone number.')
console.log(response)
rl.close()
} catch(error) {
console.error('Failed to register your phone number. Please try again.\n', error)
await askForOTP()
}
}

async function askForOTP() {
let code = await question('How would you like to receive the one time code for registration? "sms" or "voice"\n')
code = code.replace(/["']/g, '').trim().toLowerCase()

if(code !== 'sms' && code !== 'voice') {
return await askForOTP()
}

// only if store is present
return {
conversation: 'hello'
registration.method = code

try {
await sock.requestRegistrationCode(registration)
await enterCode()
} catch(error) {
console.error('Failed to request registration code. Please try again.\n', error)
await askForOTP()
}
}
})

store?.bind(sock.ev)
askForOTP()
}

const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => {
await sock.presenceSubscribe(jid)
Expand Down Expand Up @@ -97,6 +153,15 @@ const startSock = async() => {
await saveCreds()
}

if(events['labels.association']) {
console.log(events['labels.association'])
}


if(events['labels.edit']) {
console.log(events['labels.edit'])
}

if(events.call) {
console.log('recv call event', events.call)
}
Expand Down Expand Up @@ -125,7 +190,24 @@ const startSock = async() => {

// messages updated like status delivered, message deleted etc.
if(events['messages.update']) {
console.log(events['messages.update'])
console.log(
JSON.stringify(events['messages.update'], undefined, 2)
)

for(const { key, update } of events['messages.update']) {
if(update.pollUpdates) {
const pollCreation = await getMessage(key)
if(pollCreation) {
console.log(
'got poll update, aggregation: ',
getAggregateVotesInPollMessage({
message: pollCreation,
pollUpdates: update.pollUpdates,
})
)
}
}
}
}

if(events['message-receipt.update']) {
Expand Down Expand Up @@ -164,6 +246,16 @@ const startSock = async() => {
)

return sock

async function getMessage(key: WAMessageKey): Promise<WAMessageContent | undefined> {
if(store) {
const msg = await store.loadMessage(key.remoteJid!, key.id!)
return msg?.message || undefined
}

// only if store is present
return proto.Message.fromObject({})
}
}

startSock()
100 changes: 77 additions & 23 deletions whatsapp_addon/Baileys/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
# Baileys - Typescript/Javascript WhatsApp Web API

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 :/

Baileys supports interacting with the multi-device & web versions of WhatsApp.

Thank you to [@pokearaujo](https://github.com/pokearaujo/multidevice) for writing his observations on the workings of WhatsApp Multi-Device. Also, 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.

Baileys is type-safe, extensible and simple to use. If you require more functionality than provided, it's super easy to write an extension. More on this [here](#WritingCustomFunctionality).
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 :/
Baileys supports interacting with the multi-device & web versions of WhatsApp.
Thank you to [@pokearaujo](https://github.com/pokearaujo/multidevice) for writing his observations on the workings of WhatsApp Multi-Device. Also, 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.

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).
## Please Read

**Read the docs [here](https://adiwajshing.github.io/Baileys)**
The original repository had to be removed by the original author - we now continue development in this repository here.
This is the only official repository and is maintained by the community.
**Join the Discord [here](https://discord.gg/WeJM5FP9GG)**

## Example

Do check out & run [example.ts](https://github.com/adiwajshing/Baileys/blob/master/Example/example.ts) to see an example usage of the library.
Do check out & run [example.ts](Example/example.ts) to see an example usage of the library.
The script covers most common use cases.
To run the example script, download or clone the repo and then type the following in a terminal:
1. ``` cd path/to/Baileys ```
Expand All @@ -26,27 +24,29 @@ To run the example script, download or clone the repo and then type the followin

Use the stable version:
```
yarn add @adiwajshing/baileys
yarn add @whiskeysockets/baileys
```

Use the edge version (no guarantee of stability, but latest fixes + features)
```
yarn add github:adiwajshing/baileys
yarn add github:WhiskeySockets/Baileys
```

Then import your code using:
``` ts
import makeWASocket from '@adiwajshing/baileys'
import makeWASocket from '@whiskeysockets/baileys'
```

## Unit Tests

TODO

## Connecting
## Connecting multi device (recommended)

WhatsApp provides a multi-device API that allows Baileys to be authenticated as a second WhatsApp client by scanning a QR code with WhatsApp on your phone.

``` ts
import makeWASocket, { DisconnectReason } from '@adiwajshing/baileys'
import makeWASocket, { DisconnectReason } from '@whiskeysockets/baileys'
import { Boom } from '@hapi/boom'

async function connectToWhatsApp () {
Expand Down Expand Up @@ -84,6 +84,12 @@ If the connection is successful, you will see a QR code printed on your terminal

**Note:** the code to support the legacy version of WA Web (pre multi-device) has been removed in v5. Only the standard multi-device connection is now supported. This is done as WA seems to have completely dropped support for the legacy version.

## Connecting native mobile api

Baileys also supports the native mobile API, which allows users to authenticate as a standalone WhatsApp client using their phone number.

Run the [example](Example/example.ts) file with ``--mobile`` cli flag to use the native mobile API.

## Configuring the Connection

You can configure the connection by passing a `SocketConfig` object.
Expand Down Expand Up @@ -176,7 +182,7 @@ You obviously don't want to keep scanning the QR code every time you want to con

So, you can load the credentials to log back in:
``` ts
import makeWASocket, { BufferJSON, useMultiFileAuthState } from '@adiwajshing/baileys'
import makeWASocket, { BufferJSON, useMultiFileAuthState } from '@whiskeysockets/baileys'
import * as fs from 'fs'
// utility function to help save the auth state in a single folder
Expand Down Expand Up @@ -241,6 +247,8 @@ export type BaileysEventMap = {
'chats.update': Partial<Chat>[]
/** delete chats with given ID */
'chats.delete': string[]
'labels.association': LabelAssociation
'labels.edit': Label
/** presence of contact in a chat updated */
'presence.update': { id: string, presences: { [participant: string]: PresenceData } }
Expand Down Expand Up @@ -289,7 +297,7 @@ Baileys does not come with a defacto storage for chats, contacts, or messages. H
It can be used as follows:

``` ts
import makeWASocket, { makeInMemoryStore } from '@adiwajshing/baileys'
import makeWASocket, { makeInMemoryStore } from '@whiskeysockets/baileys'
// the store maintains the data of the WA connection in memory
// can be written out to a file & read from it
const store = makeInMemoryStore({ })
Expand Down Expand Up @@ -328,7 +336,7 @@ The store also provides some simple functions such as `loadMessages` that utiliz
### Non-Media Messages

``` ts
import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys'
import { MessageType, MessageOptions, Mimetype } from '@whiskeysockets/baileys'
const id = 'abcd@s.whatsapp.net' // the WhatsApp ID
// send a simple text!
Expand Down Expand Up @@ -446,7 +454,7 @@ Sending media (video, stickers, images) is easier & more efficient than ever.
- When specifying a media url, Baileys never loads the entire buffer into memory; it even encrypts the media as a readable stream.

``` ts
import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys'
import { MessageType, MessageOptions, Mimetype } from '@whiskeysockets/baileys'
// Sending gifs
await sock.sendMessage(
id,
Expand Down Expand Up @@ -528,7 +536,7 @@ const sendMsg = await sock.sendMessage(id, templateMessage)
Do not enter this field if you want to automatically generate a thumb
*/
mimetype: Mimetype.pdf, /* (for media messages) specify the type of media (optional for all media types except documents),
import {Mimetype} from '@adiwajshing/baileys'
import {Mimetype} from '@whiskeysockets/baileys'
*/
fileName: 'somefile.pdf', // (for media messages) file name for the media
/* will send audio messages as voice notes, if set to true */
Expand Down Expand Up @@ -587,7 +595,7 @@ The presence expires after about 10 seconds.
If you want to save the media you received
``` ts
import { writeFile } from 'fs/promises'
import { downloadMediaMessage } from '@adiwajshing/baileys'
import { downloadMediaMessage } from '@whiskeysockets/baileys'
sock.ev.on('messages.upsert', async ({ messages }) => {
const m = messages[0]
Expand Down Expand Up @@ -742,6 +750,11 @@ await sock.sendMessage(
const jid = '111234567890-1594482450@g.us' // can be your own too
await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
```
- To remove your display picture or a group's
``` ts
const jid = '111234567890-1594482450@g.us' // can be your own too
await sock.removeProfilePicture(jid)
```
- To get someone's presence (if they're typing or online)
``` ts
// the presence update is fetched and called here
Expand Down Expand Up @@ -833,7 +846,48 @@ Of course, replace ``` xyz ``` with an actual ID.
console.log("joined to: " + response)
```
Of course, replace ``` xxx ``` with invitation code.


## Privacy
- To get the privacy settings
``` ts
const privacySettings = await sock.fetchPrivacySettings(true)
console.log("privacy settings: " + privacySettings)
```
- To update the LastSeen privacy
``` ts
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
await sock.updateLastSeenPrivacy(value)
```
- To update the Online privacy
``` ts
const value = 'all' // 'match_last_seen'
await sock.updateOnlinePrivacy(value)
```
- To update the Profile Picture privacy
``` ts
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
await sock.updateProfilePicturePrivacy(value)
```
- To update the Status privacy
``` ts
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
await sock.updateStatusPrivacy(value)
```
- To update the Read Receipts privacy
``` ts
const value = 'all' // 'none'
await sock.updateReadReceiptsPrivacy(value)
```
- To update the Groups Add privacy
``` ts
const value = 'all' // 'contacts' | 'contact_blacklist' | 'none'
await sock.updateGroupsAddPrivacy(value)
```
- To update the Default Disappearing Mode
``` ts
const duration = 86400 // 604800 | 7776000 | 0
await sock.updateDefaultDisappearingMode(duration)
```
## Broadcast Lists & Stories

**Note:** messages currently cannot be sent to broadcast lists from the MD version.
Expand Down
Loading

0 comments on commit f8225ac

Please sign in to comment.