mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
ID Validation + Full Stub Types
This commit is contained in:
@@ -151,12 +151,14 @@ To note:
|
|||||||
- `id` is the WhatsApp ID of the person or group you're sending the message to.
|
- `id` is the WhatsApp ID of the person or group you're sending the message to.
|
||||||
- It must be in the format ```[country code][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 ```.
|
- It must be in the format ```[country code][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 ```.
|
||||||
- **Do not attach** `@c.us` for individual people IDs, It won't work.
|
- **Do not attach** `@c.us` for individual people IDs, It won't work.
|
||||||
|
- Please do not explicitly disable ID validation (in `MessageOptions`) because then your messages may fail for no apparent reason.
|
||||||
- For media messages, the thumbnail can be generated automatically for images & stickers. Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system.
|
- For media messages, the thumbnail can be generated automatically for images & stickers. Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system.
|
||||||
- **MessageOptions**: some extra info about the message. It can have the following __optional__ values:
|
- **MessageOptions**: some extra info about the message. It can have the following __optional__ values:
|
||||||
``` ts
|
``` ts
|
||||||
const info: MessageOptions = {
|
const info: MessageOptions = {
|
||||||
quoted: quotedMessage, // the message you want to quote
|
quoted: quotedMessage, // the message you want to quote
|
||||||
timestamp: Date() // optional, if you want to manually set the timestamp of the message
|
timestamp: Date(), // optional, if you want to manually set the timestamp of the message
|
||||||
|
validateID: true, // if you want to validate the ID before sending the message, true by default
|
||||||
caption: "hello there!", // (for media messages) the caption to send with the media (cannot be sent with stickers though)
|
caption: "hello there!", // (for media messages) the caption to send with the media (cannot be sent with stickers though)
|
||||||
thumbnail: "23GD#4/==", /* (for location & media messages) has to be a base 64 encoded JPEG if you want to send a custom thumb,
|
thumbnail: "23GD#4/==", /* (for location & media messages) has to be a base 64 encoded JPEG if you want to send a custom thumb,
|
||||||
or set to null if you don't want to send a thumbnail.
|
or set to null if you don't want to send a thumbnail.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@adiwajshing/baileys",
|
"name": "@adiwajshing/baileys",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "WhatsApp Web API",
|
"description": "WhatsApp Web API",
|
||||||
"homepage": "https://github.com/adiwajshing/Baileys",
|
"homepage": "https://github.com/adiwajshing/Baileys",
|
||||||
"main": "lib/WAClient/WAClient.js",
|
"main": "lib/WAClient/WAClient.js",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"test": "mocha --timeout 30000 -r ts-node/register */Tests.ts",
|
"test": "mocha --timeout 30000 -r ts-node/register src/*/Tests.ts",
|
||||||
"lint": "eslint '*/*.ts' --quiet --fix",
|
"lint": "eslint '*/*.ts' --quiet --fix",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"example": "npx ts-node Example/example.ts"
|
"example": "npx ts-node Example/example.ts"
|
||||||
|
|||||||
@@ -34,15 +34,14 @@ export enum MessageType {
|
|||||||
document = 'documentMessage',
|
document = 'documentMessage',
|
||||||
audio = 'audioMessage',
|
audio = 'audioMessage',
|
||||||
}
|
}
|
||||||
/**
|
export const WAMessageType = function () {
|
||||||
* Tells us what kind of message it is
|
const types = proto.WebMessageInfo.WEB_MESSAGE_INFO_STUBTYPE
|
||||||
*/
|
const dict: Record<number, string> = {}
|
||||||
export const MessageStubTypes = {
|
Object.keys(types).forEach(element => dict[ types[element] ] = element)
|
||||||
20: 'addedToGroup',
|
return dict
|
||||||
32: 'leftGroup',
|
}()
|
||||||
39: 'createdGroup',
|
|
||||||
}
|
|
||||||
export const HKDFInfoKeys = (function () {
|
export const HKDFInfoKeys = (function () {
|
||||||
|
|
||||||
const dict: Record<string, string> = {}
|
const dict: Record<string, string> = {}
|
||||||
dict[MessageType.image] = 'WhatsApp Image Keys'
|
dict[MessageType.image] = 'WhatsApp Image Keys'
|
||||||
dict[MessageType.video] = 'WhatsApp Audio Keys'
|
dict[MessageType.video] = 'WhatsApp Audio Keys'
|
||||||
@@ -65,10 +64,12 @@ export interface MessageOptions {
|
|||||||
caption?: string
|
caption?: string
|
||||||
thumbnail?: string
|
thumbnail?: string
|
||||||
mimetype?: Mimetype
|
mimetype?: Mimetype
|
||||||
|
validateID?: boolean
|
||||||
}
|
}
|
||||||
export interface MessageStatusUpdate {
|
export interface MessageStatusUpdate {
|
||||||
from: string
|
from: string
|
||||||
to: string
|
to: string
|
||||||
|
/** Which participant caused the update (only for groups) */
|
||||||
participant?: string
|
participant?: string
|
||||||
timestamp: Date
|
timestamp: Date
|
||||||
/** Message IDs read/delivered */
|
/** Message IDs read/delivered */
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from './Constants'
|
} from './Constants'
|
||||||
import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes } from '../WAConnection/Utils'
|
import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes } from '../WAConnection/Utils'
|
||||||
import { WAMessageContent, WAMetric, WAFlag } from '../WAConnection/Constants'
|
import { WAMessageContent, WAMetric, WAFlag } from '../WAConnection/Constants'
|
||||||
import { generateThumbnail, getMediaKeys } from './Utils'
|
import { validateJIDForSending, generateThumbnail, getMediaKeys } from './Utils'
|
||||||
|
|
||||||
export default class WhatsAppWebMessages extends WhatsAppWebBase {
|
export default class WhatsAppWebMessages extends WhatsAppWebBase {
|
||||||
/**
|
/**
|
||||||
@@ -48,6 +48,9 @@ export default class WhatsAppWebMessages extends WhatsAppWebBase {
|
|||||||
type: MessageType,
|
type: MessageType,
|
||||||
options: MessageOptions = {},
|
options: MessageOptions = {},
|
||||||
) {
|
) {
|
||||||
|
if (options.validateID === true || !('validateID' in options)) {
|
||||||
|
validateJIDForSending (id)
|
||||||
|
}
|
||||||
let m: any = {}
|
let m: any = {}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MessageType.text:
|
case MessageType.text:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { MessageType, MessageOptions, Mimetype, Presence } from './Constants'
|
|||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as assert from 'assert'
|
import * as assert from 'assert'
|
||||||
|
|
||||||
import { decodeMediaMessage } from './Utils'
|
import { decodeMediaMessage, validateJIDForSending } from './Utils'
|
||||||
import { promiseTimeout } from '../WAConnection/Utils'
|
import { promiseTimeout } from '../WAConnection/Utils'
|
||||||
|
|
||||||
require ('dotenv').config () // dotenv to load test jid
|
require ('dotenv').config () // dotenv to load test jid
|
||||||
@@ -61,6 +61,18 @@ WAClientTest('Messages', (client) => {
|
|||||||
assert.strictEqual(message.message.imageMessage.contextInfo.stanzaId, messages[0].key.id)
|
assert.strictEqual(message.message.imageMessage.contextInfo.stanzaId, messages[0].key.id)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe('Validate WhatsApp IDs', () => {
|
||||||
|
it ('should correctly validate', () => {
|
||||||
|
assert.doesNotThrow (() => validateJIDForSending ('12345@s.whatsapp.net'))
|
||||||
|
assert.doesNotThrow (() => validateJIDForSending ('919999999999@s.whatsapp.net'))
|
||||||
|
assert.doesNotThrow (() => validateJIDForSending ('10203040506@s.whatsapp.net'))
|
||||||
|
assert.doesNotThrow (() => validateJIDForSending ('12345-3478@g.us'))
|
||||||
|
assert.doesNotThrow (() => validateJIDForSending ('1234567890-34712121238@g.us'))
|
||||||
|
assert.throws (() => validateJIDForSending ('123454677@c.us'))
|
||||||
|
assert.throws (() => validateJIDForSending ('+123454677@s.whatsapp.net'))
|
||||||
|
assert.throws (() => validateJIDForSending ('+12345-3478@g.us'))
|
||||||
|
})
|
||||||
|
})
|
||||||
WAClientTest('Presence', (client) => {
|
WAClientTest('Presence', (client) => {
|
||||||
it('should update presence', async () => {
|
it('should update presence', async () => {
|
||||||
const presences = Object.values(Presence)
|
const presences = Object.values(Presence)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MessageType, HKDFInfoKeys, MessageOptions, MessageStubTypes } from './Constants'
|
import { MessageType, HKDFInfoKeys, MessageOptions, WAMessageType } from './Constants'
|
||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
@@ -8,18 +8,28 @@ import { proto } from '../../WAMessage/WAMessage'
|
|||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'crypto'
|
||||||
import { exec } from 'child_process'
|
import { exec } from 'child_process'
|
||||||
|
|
||||||
|
export function validateJIDForSending (jid: string) {
|
||||||
|
const regexp = /^[0-9]{1,20}(-[0-9]{1,20}@g.us|@s.whatsapp.net)$/
|
||||||
|
if (!regexp.test (jid)) {
|
||||||
|
throw new Error (
|
||||||
|
`Invalid WhatsApp id: ${jid}
|
||||||
|
1. Please ensure you suffix '@s.whatsapp.net' for individual numbers & '@g.us' for groups
|
||||||
|
2. Please do not put any alphabets or special characters like a '+' in the number. A '-' symbol in groups is fine`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Type of notification */
|
/** Type of notification */
|
||||||
export function getNotificationType(message: WAMessage) {
|
export function getNotificationType(message: WAMessage): [string, string] {
|
||||||
if (message.message) {
|
if (message.message) {
|
||||||
return ['message', Object.keys(message.message)[0]]
|
return ['message', Object.keys(message.message)[0]]
|
||||||
} else if (message.messageStubType) {
|
} else if (message.messageStubType) {
|
||||||
return [MessageStubTypes[message.messageStubType], null]
|
return [WAMessageType[message.messageStubType], null]
|
||||||
} else {
|
} else {
|
||||||
return ['unknown', null]
|
return ['unknown', null]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
||||||
|
|
||||||
export function getMediaKeys(buffer, mediaType: MessageType) {
|
export function getMediaKeys(buffer, mediaType: MessageType) {
|
||||||
// expand using HKDF to 112 bytes, also pass in the relevant app info
|
// expand using HKDF to 112 bytes, also pass in the relevant app info
|
||||||
const expandedMediaKey = hkdf(buffer, 112, HKDFInfoKeys[mediaType])
|
const expandedMediaKey = hkdf(buffer, 112, HKDFInfoKeys[mediaType])
|
||||||
|
|||||||
Reference in New Issue
Block a user