mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Change Profile Picture + Change Group Settings + Send Message to Oneself
This commit is contained in:
BIN
Media/cat.jpeg
Normal file
BIN
Media/cat.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
31
README.md
31
README.md
@@ -161,13 +161,6 @@ Implement the following callbacks in your code:
|
|||||||
``` ts
|
``` ts
|
||||||
client.setOnUnexpectedDisconnect (reason => console.log ("disconnected unexpectedly: " + reason) )
|
client.setOnUnexpectedDisconnect (reason => console.log ("disconnected unexpectedly: " + reason) )
|
||||||
```
|
```
|
||||||
- Called when you log into WhatsApp Web somewhere else
|
|
||||||
``` ts
|
|
||||||
client.setOnTakenOver (async () => {
|
|
||||||
// reconnect to gain connection back here
|
|
||||||
await client.connect ()
|
|
||||||
})
|
|
||||||
```
|
|
||||||
## Sending Messages
|
## Sending Messages
|
||||||
|
|
||||||
Send like, all types of messages with a single function:
|
Send like, all types of messages with a single function:
|
||||||
@@ -296,7 +289,8 @@ await client.deleteChat (jid) // will delete the chat (can be a group or broadca
|
|||||||
|
|
||||||
**Note:** to unmute or unpin a chat, one must pass the timestamp of the pinning or muting. This is returned by the pin & mute functions. This is also available in the `WAChat` objects of the respective chats, as a `mute` or `pin` property.
|
**Note:** to unmute or unpin a chat, one must pass the timestamp of the pinning or muting. This is returned by the pin & mute functions. This is also available in the `WAChat` objects of the respective chats, as a `mute` or `pin` property.
|
||||||
|
|
||||||
## Querying
|
## Misc
|
||||||
|
|
||||||
- To check if a given ID is on WhatsApp
|
- To check if a given ID is on WhatsApp
|
||||||
``` ts
|
``` ts
|
||||||
const id = 'xyz@s.whatsapp.net'
|
const id = 'xyz@s.whatsapp.net'
|
||||||
@@ -324,6 +318,12 @@ await client.deleteChat (jid) // will delete the chat (can be a group or broadca
|
|||||||
const ppUrl = await client.getProfilePicture ("xyz@g.us") // leave empty to get your own
|
const ppUrl = await client.getProfilePicture ("xyz@g.us") // leave empty to get your own
|
||||||
console.log("download profile picture from: " + ppUrl)
|
console.log("download profile picture from: " + ppUrl)
|
||||||
```
|
```
|
||||||
|
- To change your display picture or a group's
|
||||||
|
``` ts
|
||||||
|
const jid = '111234567890-1594482450@g.us' // can be your own too
|
||||||
|
const img = fs.readFileSync ('new-profile-picture.jpeg') // can be PNG also
|
||||||
|
await client.updateProfilePicture (jid, newPP)
|
||||||
|
```
|
||||||
- To get someone's presence (if they're typing, online)
|
- To get someone's presence (if they're typing, online)
|
||||||
``` ts
|
``` ts
|
||||||
// the presence update is fetched and called here
|
// the presence update is fetched and called here
|
||||||
@@ -353,10 +353,21 @@ Append ``` @s.whatsapp.net ``` for individuals & ``` @g.us ``` for groups.
|
|||||||
// id & people to add to the group (will throw error if it fails)
|
// id & people to add to the group (will throw error if it fails)
|
||||||
const response = await client.groupAdd ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"])
|
const response = await client.groupAdd ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"])
|
||||||
```
|
```
|
||||||
- To make someone admin on a group
|
- To make/demote admins on a group
|
||||||
``` ts
|
``` ts
|
||||||
// id & people to make admin (will throw error if it fails)
|
// id & people to make admin (will throw error if it fails)
|
||||||
await client.groupMakeAdmin ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"])
|
await client.groupMakeAdmin ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"])
|
||||||
|
await client.groupDemoteAdmin ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"]) // demote admins
|
||||||
|
```
|
||||||
|
- To change group settings
|
||||||
|
``` ts
|
||||||
|
import { GroupSettingChange } from '@adiwajshing/baileys'
|
||||||
|
// only allow admins to send messages
|
||||||
|
await client.groupSettingChange ("abcd-xyz@g.us", GroupSettingChange.messageSend, true)
|
||||||
|
// allow everyone to modify the group's settings -- like display picture etc.
|
||||||
|
await client.groupSettingChange ("abcd-xyz@g.us", GroupSettingChange.settingChange, false)
|
||||||
|
// only allow admins to modify the group's settings
|
||||||
|
await client.groupSettingChange ("abcd-xyz@g.us", GroupSettingChange.settingChange, true)
|
||||||
```
|
```
|
||||||
- To leave a group
|
- To leave a group
|
||||||
``` ts
|
``` ts
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@adiwajshing/baileys",
|
"name": "@adiwajshing/baileys",
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"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",
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { WA } from './Constants'
|
|||||||
import { proto } from '../../WAMessage/WAMessage'
|
import { proto } from '../../WAMessage/WAMessage'
|
||||||
|
|
||||||
export default class Encoder {
|
export default class Encoder {
|
||||||
data: Array<number> = []
|
data: number[] = []
|
||||||
|
|
||||||
pushByte(value: number) {
|
pushByte(value: number) {
|
||||||
this.data.push(value & 0xff)
|
this.data.push(value & 0xff)
|
||||||
}
|
}
|
||||||
pushInt(value: number, n: number, littleEndian = false) {
|
pushInt(value: number, n: number, littleEndian=false) {
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < n; i++) {
|
||||||
const curShift = littleEndian ? i : n - 1 - i
|
const curShift = littleEndian ? i : n - 1 - i
|
||||||
this.data.push((value >> (curShift * 8)) & 0xff)
|
this.data.push((value >> (curShift * 8)) & 0xff)
|
||||||
@@ -16,17 +16,17 @@ export default class Encoder {
|
|||||||
pushInt20(value: number) {
|
pushInt20(value: number) {
|
||||||
this.pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff])
|
this.pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff])
|
||||||
}
|
}
|
||||||
pushBytes(bytes: Uint8Array | Array<number>) {
|
pushBytes(bytes: Uint8Array | Buffer | number[]) {
|
||||||
this.data.push.apply(this.data, bytes)
|
bytes.forEach (b => this.data.push(b))
|
||||||
|
//this.data.push.apply(this.data, bytes)
|
||||||
}
|
}
|
||||||
pushString(str: string) {
|
pushString(str: string) {
|
||||||
const bytes = Buffer.from (str, 'utf-8')
|
const bytes = Buffer.from (str, 'utf-8')
|
||||||
this.pushBytes(bytes)
|
this.pushBytes(bytes)
|
||||||
}
|
}
|
||||||
writeByteLength(length: number) {
|
writeByteLength(length: number) {
|
||||||
if (length >= 4294967296) {
|
if (length >= 4294967296) throw new Error('string too large to encode: ' + length)
|
||||||
throw new Error('string too large to encode: ' + length)
|
|
||||||
}
|
|
||||||
if (length >= 1 << 20) {
|
if (length >= 1 << 20) {
|
||||||
this.pushByte(WA.Tags.BINARY_32)
|
this.pushByte(WA.Tags.BINARY_32)
|
||||||
this.pushInt(length, 4) // 32 bit integer
|
this.pushInt(length, 4) // 32 bit integer
|
||||||
@@ -101,19 +101,18 @@ export default class Encoder {
|
|||||||
this.pushBytes([WA.Tags.LIST_16, listSize])
|
this.pushBytes([WA.Tags.LIST_16, listSize])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeChildren(children: string | Array<WA.Node> | Object) {
|
writeChildren(children: string | Array<WA.Node> | Buffer | Object) {
|
||||||
if (!children) {
|
if (!children) return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof children === 'string') {
|
if (typeof children === 'string') {
|
||||||
this.writeString(children, true)
|
this.writeString(children, true)
|
||||||
|
} else if (Buffer.isBuffer(children)) {
|
||||||
|
this.writeByteLength (children.length)
|
||||||
|
this.pushBytes(children)
|
||||||
} else if (Array.isArray(children)) {
|
} else if (Array.isArray(children)) {
|
||||||
this.writeListStart(children.length)
|
this.writeListStart(children.length)
|
||||||
children.forEach((c) => {
|
children.forEach(c => c && this.writeNode(c))
|
||||||
if (c) this.writeNode(c)
|
} else if (typeof children === 'object') {
|
||||||
})
|
|
||||||
} else if (typeof children === 'object') {
|
|
||||||
const buffer = WA.Message.encode(children as proto.WebMessageInfo).finish()
|
const buffer = WA.Message.encode(children as proto.WebMessageInfo).finish()
|
||||||
this.writeByteLength(buffer.length)
|
this.writeByteLength(buffer.length)
|
||||||
this.pushBytes(buffer)
|
this.pushBytes(buffer)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Encoder from './Encoder'
|
|||||||
import Decoder from './Decoder'
|
import Decoder from './Decoder'
|
||||||
|
|
||||||
describe('Binary Coding Tests', () => {
|
describe('Binary Coding Tests', () => {
|
||||||
const testVectors: [[string, Object]] = [
|
const testVectors: [string, Object][] = [
|
||||||
[
|
[
|
||||||
'f806092f5a0a10f804f80234fc6c0a350a1b39313735323938373131313740732e77686174736170702e6e657410011a143345423030393637354537454433374141424632122b0a292a7069616e6f20726f6f6d2074696d696e6773206172653a2a0a20363a3030414d2d31323a3030414d18b3faa7f3052003f80234fc4c0a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20304643454335333330463634393239433645394132434646443242433845414418bdfaa7f305c00101f80234fc930a350a1b39313735323938373131313740732e77686174736170702e6e657410011a14334542303033433742353339414644303937353312520a50536f727279206672656e2c204920636f756c646e277420756e6465727374616e6420274c69627261272e2054797065202768656c702720746f206b6e6f77207768617420616c6c20492063616e20646f18c1faa7f3052003f80234fc540a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20413132333042384436423041314437393345433241453245413043313638443812090a076c69627261727918c2faa7f305',
|
'f806092f5a0a10f804f80234fc6c0a350a1b39313735323938373131313740732e77686174736170702e6e657410011a143345423030393637354537454433374141424632122b0a292a7069616e6f20726f6f6d2074696d696e6773206172653a2a0a20363a3030414d2d31323a3030414d18b3faa7f3052003f80234fc4c0a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20304643454335333330463634393239433645394132434646443242433845414418bdfaa7f305c00101f80234fc930a350a1b39313735323938373131313740732e77686174736170702e6e657410011a14334542303033433742353339414644303937353312520a50536f727279206672656e2c204920636f756c646e277420756e6465727374616e6420274c69627261272e2054797065202768656c702720746f206b6e6f77207768617420616c6c20492063616e20646f18c1faa7f3052003f80234fc540a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20413132333042384436423041314437393345433241453245413043313638443812090a076c69627261727918c2faa7f305',
|
||||||
[
|
[
|
||||||
@@ -62,12 +62,20 @@ describe('Binary Coding Tests', () => {
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'f8063f2dfafc0831323334353637385027fc0431323334f801f80228fc0701020304050607',
|
||||||
|
[
|
||||||
|
'picture',
|
||||||
|
{jid: '12345678@c.us', id: '1234'},
|
||||||
|
[['image', null, Buffer.from([1,2,3,4,5,6,7])]]
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
const encoder = new Encoder()
|
const encoder = new Encoder()
|
||||||
const decoder = new Decoder()
|
const decoder = new Decoder()
|
||||||
|
|
||||||
it('should decode strings', () => {
|
it('should decode strings', () => {
|
||||||
testVectors.forEach((pair) => {
|
testVectors.forEach(pair => {
|
||||||
const buff = Buffer.from(pair[0], 'hex')
|
const buff = Buffer.from(pair[0], 'hex')
|
||||||
const decoded = decoder.read(buff)
|
const decoded = decoder.read(buff)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import WAConnection from '../WAConnection/WAConnection'
|
import WAConnection from '../WAConnection/WAConnection'
|
||||||
import { MessageStatusUpdate, PresenceUpdate, Presence, WABroadcastListInfo } from './Constants'
|
import { MessageStatusUpdate, PresenceUpdate, Presence, WABroadcastListInfo, WAProfilePictureChange } from './Constants'
|
||||||
import {
|
import {
|
||||||
WAMessage,
|
WAMessage,
|
||||||
WANode,
|
WANode,
|
||||||
@@ -8,6 +8,9 @@ import {
|
|||||||
MessageLogLevel,
|
MessageLogLevel,
|
||||||
WATag,
|
WATag,
|
||||||
} from '../WAConnection/Constants'
|
} from '../WAConnection/Constants'
|
||||||
|
import { generateProfilePicture } from '../WAClient/Utils'
|
||||||
|
import { generateMessageTag } from '../WAConnection/Utils'
|
||||||
|
|
||||||
|
|
||||||
export default class WhatsAppWebBase extends WAConnection {
|
export default class WhatsAppWebBase extends WAConnection {
|
||||||
/** Set the callback for message status updates (when a message is delivered, read etc.) */
|
/** Set the callback for message status updates (when a message is delivered, read etc.) */
|
||||||
@@ -185,9 +188,22 @@ export default class WhatsAppWebBase extends WAConnection {
|
|||||||
}
|
}
|
||||||
return loadMessage() as Promise<void>
|
return loadMessage() as Promise<void>
|
||||||
}
|
}
|
||||||
|
async updateProfilePicture (jid: string, img: Buffer) {
|
||||||
|
const data = await generateProfilePicture (img)
|
||||||
|
const tag = generateMessageTag (this.msgCount)
|
||||||
|
const query: WANode = [
|
||||||
|
'picture',
|
||||||
|
{ jid: jid, id: tag, type: 'set' },
|
||||||
|
[
|
||||||
|
['image', null, data.img],
|
||||||
|
['preview', null, data.preview]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
return this.setQuery ([query], [14, 136], tag) as Promise<WAProfilePictureChange>
|
||||||
|
}
|
||||||
/** Generic function for action, set queries */
|
/** Generic function for action, set queries */
|
||||||
async setQuery (nodes: WANode[], binaryTags: WATag = [WAMetric.group, WAFlag.ignore]) {
|
async setQuery (nodes: WANode[], binaryTags: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) {
|
||||||
const json = ['action', {epoch: this.msgCount.toString(), type: 'set'}, nodes]
|
const json = ['action', {epoch: this.msgCount.toString(), type: 'set'}, nodes]
|
||||||
return this.queryExpecting200(json, binaryTags) as Promise<{status: number}>
|
return this.queryExpecting200(json, binaryTags, null, tag) as Promise<{status: number}>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ export interface WAUrlInfo {
|
|||||||
description: string
|
description: string
|
||||||
jpegThumbnail?: Buffer
|
jpegThumbnail?: Buffer
|
||||||
}
|
}
|
||||||
|
export interface WAProfilePictureChange {
|
||||||
|
status: number
|
||||||
|
tag: string
|
||||||
|
eurl: string
|
||||||
|
}
|
||||||
export interface MessageInfo {
|
export interface MessageInfo {
|
||||||
reads: {jid: string, t: string}[]
|
reads: {jid: string, t: string}[]
|
||||||
deliveries: {jid: string, t: string}[]
|
deliveries: {jid: string, t: string}[]
|
||||||
@@ -94,7 +99,11 @@ export interface MessageStatusUpdate {
|
|||||||
/** Message IDs read/delivered */
|
/** Message IDs read/delivered */
|
||||||
ids: string[]
|
ids: string[]
|
||||||
/** Status of the Message IDs */
|
/** Status of the Message IDs */
|
||||||
type: proto.WebMessageInfo.WEB_MESSAGE_INFO_STUBTYPE
|
type: proto.WebMessageInfo.WEB_MESSAGE_INFO_STATUS
|
||||||
|
}
|
||||||
|
export enum GroupSettingChange {
|
||||||
|
messageSend = 'announcement',
|
||||||
|
settingsChange = 'locked',
|
||||||
}
|
}
|
||||||
export interface PresenceUpdate {
|
export interface PresenceUpdate {
|
||||||
id: string
|
id: string
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
import WhatsAppWebBase from './Base'
|
import WhatsAppWebBase from './Base'
|
||||||
import { WAMessage, WAMetric, WAFlag, WANode, WAGroupMetadata, WAGroupCreateResponse, WAGroupModification } from '../WAConnection/Constants'
|
import { WAMessage, WAMetric, WAFlag, WANode, WAGroupMetadata, WAGroupCreateResponse, WAGroupModification } from '../WAConnection/Constants'
|
||||||
|
import { GroupSettingChange } from './Constants'
|
||||||
import { generateMessageTag } from '../WAConnection/Utils'
|
import { generateMessageTag } from '../WAConnection/Utils'
|
||||||
|
|
||||||
export default class WhatsAppWebGroups extends WhatsAppWebBase {
|
export default class WhatsAppWebGroups extends WhatsAppWebBase {
|
||||||
/** Generic function for group queries */
|
/** Generic function for group queries */
|
||||||
async groupQuery(type: string, jid?: string, subject?: string, participants?: string[]) {
|
async groupQuery(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: WANode[]) {
|
||||||
|
const tag = generateMessageTag(this.msgCount)
|
||||||
const json: WANode = [
|
const json: WANode = [
|
||||||
'group',
|
'group',
|
||||||
{
|
{
|
||||||
author: this.userMetaData.id,
|
author: this.userMetaData.id,
|
||||||
id: generateMessageTag(),
|
id: tag,
|
||||||
type: type,
|
type: type,
|
||||||
jid: jid,
|
jid: jid,
|
||||||
subject: subject,
|
subject: subject,
|
||||||
},
|
},
|
||||||
participants ? participants.map((str) => ['participant', { jid: str }, null]) : [],
|
participants ? participants.map(str => ['participant', { jid: str }, null]) : additionalNodes,
|
||||||
]
|
]
|
||||||
const q = ['action', { type: 'set', epoch: this.msgCount.toString() }, [json]]
|
return this.setQuery ([json], [WAMetric.group, WAFlag.ignore], tag)
|
||||||
return this.queryExpecting200(q, [WAMetric.group, WAFlag.ignore])
|
|
||||||
}
|
}
|
||||||
/** Get the metadata of the group */
|
/** Get the metadata of the group */
|
||||||
groupMetadata = (jid: string) => this.queryExpecting200(['query', 'GroupMetadata', jid]) as Promise<WAGroupMetadata>
|
groupMetadata = (jid: string) => this.queryExpecting200(['query', 'GroupMetadata', jid]) as Promise<WAGroupMetadata>
|
||||||
@@ -79,6 +80,22 @@ export default class WhatsAppWebGroups extends WhatsAppWebBase {
|
|||||||
*/
|
*/
|
||||||
groupMakeAdmin = (jid: string, participants: string[]) =>
|
groupMakeAdmin = (jid: string, participants: string[]) =>
|
||||||
this.groupQuery('promote', jid, null, participants) as Promise<WAGroupModification>
|
this.groupQuery('promote', jid, null, participants) as Promise<WAGroupModification>
|
||||||
|
/**
|
||||||
|
* Make demote an admin on the group
|
||||||
|
* @param jid the ID of the group
|
||||||
|
* @param participants the people to make admin
|
||||||
|
*/
|
||||||
|
groupDemoteAdmin = (jid: string, participants: string[]) =>
|
||||||
|
this.groupQuery('demote', jid, null, participants) as Promise<WAGroupModification>
|
||||||
|
/**
|
||||||
|
* Make demote an admin on the group
|
||||||
|
* @param jid the ID of the group
|
||||||
|
* @param participants the people to make admin
|
||||||
|
*/
|
||||||
|
groupSettingChange = (jid: string, setting: GroupSettingChange, onlyAdmins: boolean) => {
|
||||||
|
const node: WANode = [ setting, {value: onlyAdmins ? 'true' : 'false'}, null ]
|
||||||
|
return this.groupQuery('prop', jid, null, null, [node]) as Promise<{status: number}>
|
||||||
|
}
|
||||||
/** Get the invite link of the given group */
|
/** Get the invite link of the given group */
|
||||||
async groupInviteCode(jid: string) {
|
async groupInviteCode(jid: string) {
|
||||||
const json = ['query', 'inviteCode', jid]
|
const json = ['query', 'inviteCode', jid]
|
||||||
|
|||||||
@@ -326,7 +326,8 @@ export default class WhatsAppWebMessages extends WhatsAppWebGroups {
|
|||||||
status: WAMessageProto.proto.WebMessageInfo.WEB_MESSAGE_INFO_STATUS.PENDING
|
status: WAMessageProto.proto.WebMessageInfo.WEB_MESSAGE_INFO_STATUS.PENDING
|
||||||
}
|
}
|
||||||
const json = ['action', {epoch: this.msgCount.toString(), type: 'relay'}, [['message', null, messageJSON]]]
|
const json = ['action', {epoch: this.msgCount.toString(), type: 'relay'}, [['message', null, messageJSON]]]
|
||||||
const response = await this.queryExpecting200(json, [WAMetric.message, WAFlag.ignore], null, messageJSON.key.id)
|
const flag = id === this.userMetaData.id ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself
|
||||||
|
const response = await this.queryExpecting200(json, [WAMetric.message, flag], null, messageJSON.key.id)
|
||||||
return {
|
return {
|
||||||
status: response.status as number,
|
status: response.status as number,
|
||||||
messageID: messageJSON.key.id,
|
messageID: messageJSON.key.id,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { WAClient } from './WAClient'
|
import { WAClient } from './WAClient'
|
||||||
import { MessageType, MessageOptions, Mimetype, Presence, ChatModification } from './Constants'
|
import { MessageType, MessageOptions, Mimetype, Presence, ChatModification, GroupSettingChange } from './Constants'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as assert from 'assert'
|
import * as assert from 'assert'
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
|
||||||
import { decodeMediaMessage, validateJIDForSending } from './Utils'
|
import { decodeMediaMessage, validateJIDForSending } from './Utils'
|
||||||
import { promiseTimeout, createTimeout } from '../WAConnection/Utils'
|
import { promiseTimeout, createTimeout } from '../WAConnection/Utils'
|
||||||
@@ -117,6 +118,20 @@ WAClientTest('Misc', (client) => {
|
|||||||
it('should return the stories', async () => {
|
it('should return the stories', async () => {
|
||||||
await client.getStories()
|
await client.getStories()
|
||||||
})
|
})
|
||||||
|
it('should change the profile picture', async () => {
|
||||||
|
await createTimeout (5000)
|
||||||
|
|
||||||
|
const ppUrl = await client.getProfilePicture(client.userMetadata.id)
|
||||||
|
const fetched = await fetch(ppUrl, { headers: { Origin: 'https://web.whatsapp.com' } })
|
||||||
|
const buff = await fetched.buffer ()
|
||||||
|
|
||||||
|
const newPP = fs.readFileSync ('./Media/cat.jpeg')
|
||||||
|
const response = await client.updateProfilePicture (client.userMetadata.id, newPP)
|
||||||
|
|
||||||
|
await createTimeout (10000)
|
||||||
|
|
||||||
|
await client.updateProfilePicture (client.userMetaData.id, buff) // revert back
|
||||||
|
})
|
||||||
it('should return the profile picture', async () => {
|
it('should return the profile picture', async () => {
|
||||||
const response = await client.getProfilePicture(testJid)
|
const response = await client.getProfilePicture(testJid)
|
||||||
assert.ok(response)
|
assert.ok(response)
|
||||||
@@ -177,6 +192,11 @@ WAClientTest('Groups', (client) => {
|
|||||||
const metadata = await client.groupMetadata(gid)
|
const metadata = await client.groupMetadata(gid)
|
||||||
assert.strictEqual(metadata.subject, subject)
|
assert.strictEqual(metadata.subject, subject)
|
||||||
})
|
})
|
||||||
|
it('should update the group settings', async () => {
|
||||||
|
await client.groupSettingChange (gid, GroupSettingChange.messageSend, true)
|
||||||
|
await createTimeout (5000)
|
||||||
|
await client.groupSettingChange (gid, GroupSettingChange.settingsChange, true)
|
||||||
|
})
|
||||||
it('should remove someone from a group', async () => {
|
it('should remove someone from a group', async () => {
|
||||||
await client.groupRemove(gid, [testJid])
|
await client.groupRemove(gid, [testJid])
|
||||||
})
|
})
|
||||||
@@ -204,18 +224,4 @@ WAClientTest('Events', (client) => {
|
|||||||
const response = await client.sendMessage(testJid, 'My Name Jeff', MessageType.text)
|
const response = await client.sendMessage(testJid, 'My Name Jeff', MessageType.text)
|
||||||
await promiseTimeout(10000, waitForUpdate())
|
await promiseTimeout(10000, waitForUpdate())
|
||||||
})
|
})
|
||||||
/*it ('should update me on presence', async () => {
|
|
||||||
//client.logUnhandledMessages = true
|
|
||||||
client.setOnPresenceUpdate (presence => {
|
|
||||||
console.log (presence)
|
|
||||||
})
|
|
||||||
const response = await client.requestPresenceUpdate (client.userMetaData)
|
|
||||||
assert.strictEqual (response.status, 200)
|
|
||||||
await createTimeout (25000)
|
|
||||||
})*/
|
|
||||||
})
|
})
|
||||||
/*WAClientTest ('Testz', client => {
|
|
||||||
it ('should work', async () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
})*/
|
|
||||||
@@ -67,6 +67,15 @@ export const compressImage = async (buffer: Buffer) => {
|
|||||||
const jimp = await Jimp.read (buffer)
|
const jimp = await Jimp.read (buffer)
|
||||||
return jimp.resize(48, 48).getBufferAsync (Jimp.MIME_JPEG)
|
return jimp.resize(48, 48).getBufferAsync (Jimp.MIME_JPEG)
|
||||||
}
|
}
|
||||||
|
export const generateProfilePicture = async (buffer: Buffer) => {
|
||||||
|
const jimp = await Jimp.read (buffer)
|
||||||
|
const min = Math.min(jimp.getWidth (), jimp.getHeight ())
|
||||||
|
const cropped = jimp.crop (0, 0, min, min)
|
||||||
|
return {
|
||||||
|
img: await cropped.resize(640, 640).getBufferAsync (Jimp.MIME_JPEG),
|
||||||
|
preview: await cropped.resize(96, 96).getBufferAsync (Jimp.MIME_JPEG)
|
||||||
|
}
|
||||||
|
}
|
||||||
/** generates a thumbnail for a given media, if required */
|
/** generates a thumbnail for a given media, if required */
|
||||||
export async function generateThumbnail(buffer: Buffer, mediaType: MessageType, info: MessageOptions) {
|
export async function generateThumbnail(buffer: Buffer, mediaType: MessageType, info: MessageOptions) {
|
||||||
if (info.thumbnail === null || info.thumbnail) {
|
if (info.thumbnail === null || info.thumbnail) {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export function promiseTimeout<T>(ms: number, promise: Promise<T>) {
|
|||||||
// whatsapp requires a message tag for every message, we just use the timestamp as one
|
// whatsapp requires a message tag for every message, we just use the timestamp as one
|
||||||
export function generateMessageTag(epoch?: number) {
|
export function generateMessageTag(epoch?: number) {
|
||||||
let tag = new Date().getTime().toString()
|
let tag = new Date().getTime().toString()
|
||||||
if (epoch) tag += '-' + epoch // attach epoch if provided
|
if (epoch) tag += '.--' + epoch // attach epoch if provided
|
||||||
return tag
|
return tag
|
||||||
}
|
}
|
||||||
// generate a random 16 byte client ID
|
// generate a random 16 byte client ID
|
||||||
|
|||||||
Reference in New Issue
Block a user