Skip to content

Commit

Permalink
Merge pull request sorke#2 from SamuelScheit/master
Browse files Browse the repository at this point in the history
  • Loading branch information
edgardmessias authored Jun 5, 2023
2 parents 58ffd33 + d570da1 commit ccb2b79
Show file tree
Hide file tree
Showing 22 changed files with 902 additions and 140 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
67 changes: 66 additions & 1 deletion Example/example.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Boom } from '@hapi/boom'
import parsePhoneNumber from 'libphonenumber-js'
import NodeCache from 'node-cache'
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, getAggregateVotesInPollMessage, makeCacheableSignalKeyStore, makeInMemoryStore, proto, useMultiFileAuthState, WAMessageContent, WAMessageKey } from '../src'
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({})
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
Expand All @@ -33,6 +36,7 @@ const startSock = async() => {
version,
logger,
printQRInTerminal: true,
mobile: useMobile,
auth: {
creds: state.creds,
/** caching makes the store faster to send/recv messages */
Expand All @@ -49,6 +53,67 @@ const startSock = async() => {

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()
}

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()
}
}

askForOTP()
}

const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => {
await sock.presenceSubscribe(jid)
await delay(500)
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ import makeWASocket from '@whiskeysockets/baileys'

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 '@whiskeysockets/baileys'
Expand Down Expand Up @@ -82,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
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@
"@hapi/boom": "^9.1.3",
"axios": "^1.3.3",
"futoin-hkdf": "^1.5.1",
"libphonenumber-js": "^1.10.20",
"libsignal": "https://github.com/adiwajshing/libsignal-node.git",
"music-metadata": "^7.12.3",
"node-cache": "^5.1.2",
"pino": "^7.0.0",
"protobufjs": "^6.11.3",
"uuid": "^9.0.0",
"ws": "^8.0.0"
},
"devDependencies": {
Expand Down
17 changes: 16 additions & 1 deletion src/Defaults/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,36 @@ import type { AuthenticationState, MediaType, SocketConfig, WAVersion } from '..
import { Browsers } from '../Utils'
import logger from '../Utils/logger'
import { version } from './baileys-version.json'
import phoneNumberMCC from './phonenumber-mcc.json'

export const UNAUTHORIZED_CODES = [401, 403, 419]

export const PHONENUMBER_MCC = phoneNumberMCC

export const DEFAULT_ORIGIN = 'https://web.whatsapp.com'
export const MOBILE_ENDPOINT = 'g.whatsapp.net'
export const MOBILE_PORT = 443
export const DEF_CALLBACK_PREFIX = 'CB:'
export const DEF_TAG_PREFIX = 'TAG:'
export const PHONE_CONNECTION_CB = 'CB:Pong'

export const WA_DEFAULT_EPHEMERAL = 7 * 24 * 60 * 60

export const MOBILE_TOKEN = Buffer.from('0a1mLfGUIBVrMKF1RdvLI5lkRBvof6vn0fD2QRSM4174c0243f5277a5d7720ce842cc4ae6')
export const MOBILE_REGISTRATION_ENDPOINT = 'https://v.whatsapp.net/v2'
export const MOBILE_USERAGENT = 'WhatsApp/2.22.24.81 iOS/15.3.1 Device/Apple-iPhone_7'
export const REGISTRATION_PUBLIC_KEY = Buffer.from([
5, 142, 140, 15, 116, 195, 235, 197, 215, 166, 134, 92, 108, 60, 132, 56, 86, 176, 97, 33, 204, 232, 234, 119, 77,
34, 251, 111, 18, 37, 18, 48, 45,
])
export const NOISE_MODE = 'Noise_XX_25519_AESGCM_SHA256\0\0\0\0'
export const DICT_VERSION = 2
export const KEY_BUNDLE_TYPE = Buffer.from([5])
export const NOISE_WA_HEADER = Buffer.from(
[ 87, 65, 6, DICT_VERSION ]
) // last is "DICT_VERSION"
export const PROTOCOL_VERSION = [5, 2]
export const MOBILE_NOISE_HEADER = Buffer.concat([Buffer.from('WA'), Buffer.from(PROTOCOL_VERSION)])
/** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */
export const URL_REGEX = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/
export const URL_EXCLUDE_REGEX = /.*@.*/
Expand Down Expand Up @@ -74,7 +88,8 @@ export const MEDIA_PATH_MAP: { [T in MediaType]?: string } = {
sticker: '/mms/image',
'thumbnail-link': '/mms/image',
'product-catalog-image': '/product/image',
'md-app-state': ''
'md-app-state': '',
'md-msg-hist': '/mms/md-app-state',
}

export const MEDIA_HKDF_KEY_MAPPING = {
Expand Down
Loading

0 comments on commit ccb2b79

Please sign in to comment.