Change Profile Picture + Change Group Settings + Send Message to Oneself
This commit is contained in:
+19
-3
@@ -1,5 +1,5 @@
|
||||
import WAConnection from '../WAConnection/WAConnection'
|
||||
import { MessageStatusUpdate, PresenceUpdate, Presence, WABroadcastListInfo } from './Constants'
|
||||
import { MessageStatusUpdate, PresenceUpdate, Presence, WABroadcastListInfo, WAProfilePictureChange } from './Constants'
|
||||
import {
|
||||
WAMessage,
|
||||
WANode,
|
||||
@@ -8,6 +8,9 @@ import {
|
||||
MessageLogLevel,
|
||||
WATag,
|
||||
} from '../WAConnection/Constants'
|
||||
import { generateProfilePicture } from '../WAClient/Utils'
|
||||
import { generateMessageTag } from '../WAConnection/Utils'
|
||||
|
||||
|
||||
export default class WhatsAppWebBase extends WAConnection {
|
||||
/** 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>
|
||||
}
|
||||
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 */
|
||||
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]
|
||||
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
|
||||
jpegThumbnail?: Buffer
|
||||
}
|
||||
export interface WAProfilePictureChange {
|
||||
status: number
|
||||
tag: string
|
||||
eurl: string
|
||||
}
|
||||
export interface MessageInfo {
|
||||
reads: {jid: string, t: string}[]
|
||||
deliveries: {jid: string, t: string}[]
|
||||
@@ -94,7 +99,11 @@ export interface MessageStatusUpdate {
|
||||
/** Message IDs read/delivered */
|
||||
ids: string[]
|
||||
/** 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 {
|
||||
id: string
|
||||
|
||||
+22
-5
@@ -1,23 +1,24 @@
|
||||
import WhatsAppWebBase from './Base'
|
||||
import { WAMessage, WAMetric, WAFlag, WANode, WAGroupMetadata, WAGroupCreateResponse, WAGroupModification } from '../WAConnection/Constants'
|
||||
import { GroupSettingChange } from './Constants'
|
||||
import { generateMessageTag } from '../WAConnection/Utils'
|
||||
|
||||
export default class WhatsAppWebGroups extends WhatsAppWebBase {
|
||||
/** 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 = [
|
||||
'group',
|
||||
{
|
||||
author: this.userMetaData.id,
|
||||
id: generateMessageTag(),
|
||||
id: tag,
|
||||
type: type,
|
||||
jid: jid,
|
||||
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.queryExpecting200(q, [WAMetric.group, WAFlag.ignore])
|
||||
return this.setQuery ([json], [WAMetric.group, WAFlag.ignore], tag)
|
||||
}
|
||||
/** Get the metadata of the group */
|
||||
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[]) =>
|
||||
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 */
|
||||
async groupInviteCode(jid: string) {
|
||||
const json = ['query', 'inviteCode', jid]
|
||||
|
||||
@@ -326,7 +326,8 @@ export default class WhatsAppWebMessages extends WhatsAppWebGroups {
|
||||
status: WAMessageProto.proto.WebMessageInfo.WEB_MESSAGE_INFO_STATUS.PENDING
|
||||
}
|
||||
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 {
|
||||
status: response.status as number,
|
||||
messageID: messageJSON.key.id,
|
||||
|
||||
+21
-15
@@ -1,7 +1,8 @@
|
||||
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 assert from 'assert'
|
||||
import fetch from 'node-fetch'
|
||||
|
||||
import { decodeMediaMessage, validateJIDForSending } from './Utils'
|
||||
import { promiseTimeout, createTimeout } from '../WAConnection/Utils'
|
||||
@@ -117,6 +118,20 @@ WAClientTest('Misc', (client) => {
|
||||
it('should return the stories', async () => {
|
||||
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 () => {
|
||||
const response = await client.getProfilePicture(testJid)
|
||||
assert.ok(response)
|
||||
@@ -177,6 +192,11 @@ WAClientTest('Groups', (client) => {
|
||||
const metadata = await client.groupMetadata(gid)
|
||||
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 () => {
|
||||
await client.groupRemove(gid, [testJid])
|
||||
})
|
||||
@@ -204,18 +224,4 @@ WAClientTest('Events', (client) => {
|
||||
const response = await client.sendMessage(testJid, 'My Name Jeff', MessageType.text)
|
||||
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)
|
||||
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 */
|
||||
export async function generateThumbnail(buffer: Buffer, mediaType: MessageType, info: MessageOptions) {
|
||||
if (info.thumbnail === null || info.thumbnail) {
|
||||
|
||||
Reference in New Issue
Block a user