@juzi/whatsapp-web.js
Advanced tools
Comparing version 1.19.6 to 1.20.0
@@ -1,6 +0,10 @@ | ||
const { Client, Location, List, Buttons, LocalAuth} = require('./index'); | ||
const { Client, Location, List, Buttons, LocalAuth } = require('./index'); | ||
const client = new Client({ | ||
authStrategy: new LocalAuth(), | ||
puppeteer: { headless: false } | ||
// proxyAuthentication: { username: 'username', password: 'password' }, | ||
puppeteer: { | ||
// args: ['--proxy-server=proxy-server-that-requires-authentication.example.com'], | ||
headless: false | ||
} | ||
}); | ||
@@ -192,7 +196,7 @@ | ||
} else if (msg.body === '!buttons') { | ||
let button = new Buttons('Button body',[{body:'bt1'},{body:'bt2'},{body:'bt3'}],'title','footer'); | ||
let button = new Buttons('Button body', [{ body: 'bt1' }, { body: 'bt2' }, { body: 'bt3' }], 'title', 'footer'); | ||
client.sendMessage(msg.from, button); | ||
} else if (msg.body === '!list') { | ||
let sections = [{title:'sectionTitle',rows:[{title:'ListItem1', description: 'desc'},{title:'ListItem2'}]}]; | ||
let list = new List('List body','btnText',sections,'Title','footer'); | ||
let sections = [{ title: 'sectionTitle', rows: [{ title: 'ListItem1', description: 'desc' }, { title: 'ListItem2' }] }]; | ||
let list = new List('List body', 'btnText', sections, 'Title', 'footer'); | ||
client.sendMessage(msg.from, list); | ||
@@ -235,3 +239,3 @@ } else if (msg.body === '!reaction') { | ||
if(ack == 3) { | ||
if (ack == 3) { | ||
// The message was read | ||
@@ -259,3 +263,3 @@ } | ||
client.on('change_state', state => { | ||
console.log('CHANGE STATE', state ); | ||
console.log('CHANGE STATE', state); | ||
}); | ||
@@ -280,1 +284,49 @@ | ||
client.on('contact_changed', async (message, oldId, newId, isContact) => { | ||
/** The time the event occurred. */ | ||
const eventTime = (new Date(message.timestamp * 1000)).toLocaleString(); | ||
console.log( | ||
`The contact ${oldId.slice(0, -5)}` + | ||
`${!isContact ? ' that participates in group ' + | ||
`${(await client.getChatById(message.to ?? message.from)).name} ` : ' '}` + | ||
`changed their phone number\nat ${eventTime}.\n` + | ||
`Their new phone number is ${newId.slice(0, -5)}.\n`); | ||
/** | ||
* Information about the {@name message}: | ||
* | ||
* 1. If a notification was emitted due to a group participant changing their phone number: | ||
* {@name message.author} is a participant's id before the change. | ||
* {@name message.recipients[0]} is a participant's id after the change (a new one). | ||
* | ||
* 1.1 If the contact who changed their number WAS in the current user's contact list at the time of the change: | ||
* {@name message.to} is a group chat id the event was emitted in. | ||
* {@name message.from} is a current user's id that got an notification message in the group. | ||
* Also the {@name message.fromMe} is TRUE. | ||
* | ||
* 1.2 Otherwise: | ||
* {@name message.from} is a group chat id the event was emitted in. | ||
* {@name message.to} is @type {undefined}. | ||
* Also {@name message.fromMe} is FALSE. | ||
* | ||
* 2. If a notification was emitted due to a contact changing their phone number: | ||
* {@name message.templateParams} is an array of two user's ids: | ||
* the old (before the change) and a new one, stored in alphabetical order. | ||
* {@name message.from} is a current user's id that has a chat with a user, | ||
* whos phone number was changed. | ||
* {@name message.to} is a user's id (after the change), the current user has a chat with. | ||
*/ | ||
}); | ||
client.on('group_admin_changed', (notification) => { | ||
if (notification.type === 'promote') { | ||
/** | ||
* Emitted when a current user is promoted to an admin. | ||
* {@link notification.author} is a user who performs the action of promoting/demoting the current user. | ||
*/ | ||
console.log(`You were promoted by ${notification.author}`); | ||
} else if (notification.type === 'demote') | ||
/** Emitted when a current user is demoted to a regular user. */ | ||
console.log(`You were demoted by ${notification.author}`); | ||
}); |
@@ -157,2 +157,8 @@ | ||
/** Sets the current user's profile picture */ | ||
setProfilePicture(media: MessageMedia): Promise<boolean> | ||
/** Deletes the current user's profile picture */ | ||
deleteProfilePicture(): Promise<boolean> | ||
/** Generic event */ | ||
@@ -202,2 +208,8 @@ on(event: string, listener: (...args: any) => void): this | ||
/** Emitted when a current user is promoted to an admin or demoted to a regular user */ | ||
on(event: 'group_admin_changed', listener: ( | ||
/** GroupNotification with more information about the action */ | ||
notification: GroupNotification | ||
) => void): this | ||
/** Emitted when group settings are updated, such as subject, description or picture */ | ||
@@ -209,2 +221,14 @@ on(event: 'group_update', listener: ( | ||
/** Emitted when a contact or a group participant changed their phone number. */ | ||
on(event: 'contact_changed', listener: ( | ||
/** Message with more information about the event. */ | ||
message: Message, | ||
/** Old user's id. */ | ||
oldId : String, | ||
/** New user's id. */ | ||
newId : String, | ||
/** Indicates if a contact or a group participant changed their phone number. */ | ||
isContact : Boolean | ||
) => void): this | ||
/** Emitted when media has been uploaded for a message sent by the client */ | ||
@@ -229,2 +253,8 @@ on(event: 'media_uploaded', listener: ( | ||
) => void): this | ||
/** Emitted when a chat unread count changes */ | ||
on(event: 'unread_count', listener: ( | ||
/** The chat that was affected */ | ||
chat: Chat | ||
) => void): this | ||
@@ -260,2 +290,18 @@ /** Emitted when a new message is created, which may include the current user's own messages */ | ||
/** Emitted when a chat is removed */ | ||
on(event: 'chat_removed', listener: ( | ||
/** The chat that was removed */ | ||
chat: Chat | ||
) => void): this | ||
/** Emitted when a chat is archived/unarchived */ | ||
on(event: 'chat_archived', listener: ( | ||
/** The chat that was archived/unarchived */ | ||
chat: Chat, | ||
/** State the chat is currently in */ | ||
currState: boolean, | ||
/** State the chat was previously in */ | ||
prevState: boolean | ||
) => void): this | ||
/** Emitted when loading screen is appearing */ | ||
@@ -358,3 +404,5 @@ on(event: 'loading_screen', listener: (percent: string, message: string) => void): this | ||
* @default 'ffmpeg' */ | ||
ffmpegPath?: string | ||
ffmpegPath?: string, | ||
/** Object with proxy autentication requirements @default: undefined */ | ||
proxyAuthentication?: {username: string, password: string} | undefined | ||
} | ||
@@ -516,4 +564,6 @@ | ||
MEDIA_UPLOADED = 'media_uploaded', | ||
CONTACT_CHANGED = 'contact_changed', | ||
GROUP_JOIN = 'group_join', | ||
GROUP_LEAVE = 'group_leave', | ||
GROUP_ADMIN_CHANGED = 'group_admin_changed', | ||
GROUP_UPDATE = 'group_update', | ||
@@ -656,2 +706,3 @@ QR_RECEIVED = 'qr', | ||
* hasQuotedMsg: false, | ||
* hasReaction: false, | ||
* location: undefined, | ||
@@ -686,2 +737,4 @@ * mentionedIds: [] | ||
hasQuotedMsg: boolean, | ||
/** Indicates whether there are reactions to the message */ | ||
hasReaction: boolean, | ||
/** Indicates the duration of the message in seconds */ | ||
@@ -788,2 +841,6 @@ duration: string, | ||
getPayment: () => Promise<Payment>, | ||
/** | ||
* Gets the reactions associated with the given message | ||
*/ | ||
getReactions: () => Promise<ReactionList[]>, | ||
} | ||
@@ -1041,2 +1098,4 @@ | ||
unreadCount: number, | ||
/** Last message fo chat */ | ||
lastMessage: Message, | ||
@@ -1185,2 +1244,6 @@ /** Archives this chat */ | ||
leave: () => Promise<void>; | ||
/** Sets the group's picture.*/ | ||
setPicture: (media: MessageMedia) => Promise<boolean>; | ||
/** Deletes the group's picture */ | ||
deletePicture: () => Promise<boolean>; | ||
} | ||
@@ -1389,4 +1452,11 @@ | ||
} | ||
export type ReactionList = { | ||
id: string, | ||
aggregateEmoji: string, | ||
hasReactionByMe: boolean, | ||
senders: Array<Reaction> | ||
} | ||
} | ||
export = WAWebJS |
{ | ||
"name": "@juzi/whatsapp-web.js", | ||
"version": "1.19.6", | ||
"version": "1.20.0", | ||
"description": "Library for interacting with the WhatsApp Web API ", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -18,3 +18,3 @@ 'use strict'; | ||
const ContactFactory = require('./factories/ContactFactory'); | ||
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures'); | ||
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List, Reaction, Chat } = require('./structures'); | ||
const LegacySessionAuth = require('./authStrategies/LegacySessionAuth'); | ||
@@ -38,2 +38,3 @@ const NoAuth = require('./authStrategies/NoAuth'); | ||
* @param {boolean} options.bypassCSP - Sets bypassing of page's Content-Security-Policy. | ||
* @param {object} options.proxyAuthentication - Proxy Authentication object. | ||
* | ||
@@ -55,2 +56,4 @@ * @fires Client#qr | ||
* @fires Client#change_state | ||
* @fires Client#contact_changed | ||
* @fires Client#group_admin_changed | ||
*/ | ||
@@ -111,2 +114,6 @@ class Client extends EventEmitter { | ||
} | ||
if (this.options.proxyAuthentication !== undefined) { | ||
await page.authenticate(this.options.proxyAuthentication); | ||
} | ||
@@ -329,2 +336,9 @@ await page.setUserAgent(this.options.userAgent); | ||
this.emit(Events.GROUP_LEAVE, notification); | ||
} else if (msg.subtype === 'promote' || msg.subtype === 'demote') { | ||
/** | ||
* Emitted when a current user is promoted to an admin or demoted to a regular user. | ||
* @event Client#group_admin_changed | ||
* @param {GroupNotification} notification GroupNotification with more information about the action | ||
*/ | ||
this.emit(Events.GROUP_ADMIN_CHANGED, notification); | ||
} else { | ||
@@ -389,2 +403,32 @@ /** | ||
/** | ||
* The event notification that is received when one of | ||
* the group participants changes thier phone number. | ||
*/ | ||
const isParticipant = msg.type === 'gp2' && msg.subtype === 'modify'; | ||
/** | ||
* The event notification that is received when one of | ||
* the contacts changes thier phone number. | ||
*/ | ||
const isContact = msg.type === 'notification_template' && msg.subtype === 'change_number'; | ||
if (isParticipant || isContact) { | ||
/** {@link GroupNotification} object does not provide enough information about this event, so a {@link Message} object is used. */ | ||
const message = new Message(this, msg); | ||
const newId = isParticipant ? msg.recipients[0] : msg.to; | ||
const oldId = isParticipant ? msg.author : msg.templateParams.find(id => id !== newId); | ||
/** | ||
* Emitted when a contact or a group participant changes their phone number. | ||
* @event Client#contact_changed | ||
* @param {Message} message Message with more information about the event. | ||
* @param {String} oldId The user's id (an old one) who changed their phone number | ||
* and who triggered the notification. | ||
* @param {String} newId The user's new id after the change. | ||
* @param {Boolean} isContact Indicates if a contact or a group participant changed their phone number. | ||
*/ | ||
this.emit(Events.CONTACT_CHANGED, message, oldId, newId, isContact); | ||
} | ||
}); | ||
@@ -421,2 +465,11 @@ | ||
await page.exposeFunction('onChatUnreadCountEvent', async (data) =>{ | ||
const chat = await this.getChatById(data.id); | ||
/** | ||
* Emitted when the chat unread count changes | ||
*/ | ||
this.emit(Events.UNREAD_COUNT, chat); | ||
}); | ||
await page.exposeFunction('onMessageMediaUploadedEvent', (msg) => { | ||
@@ -527,2 +580,22 @@ | ||
await page.exposeFunction('onRemoveChatEvent', (chat) => { | ||
/** | ||
* Emitted when a chat is removed | ||
* @event Client#chat_removed | ||
* @param {Chat} chat | ||
*/ | ||
this.emit(Events.CHAT_REMOVED, new Chat(this, chat)); | ||
}); | ||
await page.exposeFunction('onArchiveChatEvent', (chat, currState, prevState) => { | ||
/** | ||
* Emitted when a chat is archived/unarchived | ||
* @event Client#chat_archived | ||
* @param {Chat} chat | ||
* @param {boolean} currState | ||
* @param {boolean} prevState | ||
*/ | ||
this.emit(Events.CHAT_ARCHIVED, new Chat(this, chat), currState, prevState); | ||
}); | ||
await page.evaluate(() => { | ||
@@ -537,2 +610,4 @@ window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); }); | ||
window.Store.Call.on('add', (call) => { window.onIncomingCall(call); }); | ||
window.Store.Chat.on('remove', async (chat) => { window.onRemoveChatEvent(await window.WWebJS.getChatModel(chat)); }); | ||
window.Store.Chat.on('change:archive', async (chat, currState, prevState) => { window.onArchiveChatEvent(await window.WWebJS.getChatModel(chat), currState, prevState); }); | ||
window.Store.Msg.on('add', (msg) => { | ||
@@ -549,2 +624,4 @@ if (msg.isNewMsg) { | ||
window.Store.Contact.on('change:name', (contact, newName, oldName) => {window.onContactNameChange(contact, newName, oldName);}); | ||
window.Store.Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);}); | ||
{ | ||
@@ -1230,4 +1307,29 @@ const module = window.Store.createOrUpdateReactionsModule; | ||
} | ||
/** | ||
* Sets the current user's profile picture. | ||
* @param {MessageMedia} media | ||
* @returns {Promise<boolean>} Returns true if the picture was properly updated. | ||
*/ | ||
async setProfilePicture(media) { | ||
const success = await this.pupPage.evaluate((chatid, media) => { | ||
return window.WWebJS.setPicture(chatid, media); | ||
}, this.info.wid._serialized, media); | ||
return success; | ||
} | ||
/** | ||
* Deletes the current user's profile picture. | ||
* @returns {Promise<boolean>} Returns true if the picture was properly deleted. | ||
*/ | ||
async deleteProfilePicture() { | ||
const success = await this.pupPage.evaluate((chatid) => { | ||
return window.WWebJS.deletePicture(chatid); | ||
}, this.info.wid._serialized); | ||
return success; | ||
} | ||
} | ||
module.exports = Client; |
@@ -78,2 +78,8 @@ 'use strict'; | ||
/** | ||
* Last message fo chat | ||
* @type {Message} | ||
*/ | ||
this.lastMessage = data.lastMessage ? new Message(super.client, data.lastMessage) : undefined; | ||
return super._patch(data); | ||
@@ -80,0 +86,0 @@ } |
@@ -217,2 +217,27 @@ 'use strict'; | ||
/** | ||
* Deletes the group's picture. | ||
* @returns {Promise<boolean>} Returns true if the picture was properly deleted. This can return false if the user does not have the necessary permissions. | ||
*/ | ||
async deletePicture() { | ||
const success = await this.client.pupPage.evaluate((chatid) => { | ||
return window.WWebJS.deletePicture(chatid); | ||
}, this.id._serialized); | ||
return success; | ||
} | ||
/** | ||
* Sets the group's picture. | ||
* @param {MessageMedia} media | ||
* @returns {Promise<boolean>} Returns true if the picture was properly updated. This can return false if the user does not have the necessary permissions. | ||
*/ | ||
async setPicture(media) { | ||
const success = await this.client.pupPage.evaluate((chatid, media) => { | ||
return window.WWebJS.setPicture(chatid, media); | ||
}, this.id._serialized, media); | ||
return success; | ||
} | ||
/** | ||
* Gets the invite code for a specific group | ||
@@ -219,0 +244,0 @@ * @returns {Promise<string>} Group's invite code |
@@ -8,3 +8,4 @@ 'use strict'; | ||
const Payment = require('./Payment'); | ||
const { MessageTypes } = require('../util/Constants'); | ||
const Reaction = require('./Reaction'); | ||
const {MessageTypes} = require('../util/Constants'); | ||
@@ -92,4 +93,3 @@ /** | ||
*/ | ||
this.deviceType = data.id.id.length > 21 ? 'android' : data.id.id.substring(0, 2) == '3A' ? 'ios' : 'web'; | ||
this.deviceType = typeof data.id.id === 'string' && data.id.id.length > 21 ? 'android' : typeof data.id.id === 'string' && data.id.id.substring(0, 2) === '3A' ? 'ios' : 'web'; | ||
/** | ||
@@ -113,3 +113,3 @@ * Indicates if the message was forwarded | ||
*/ | ||
this.isStatus = data.isStatusV3; | ||
this.isStatus = data.isStatusV3 || data.id.remote === 'status@broadcast'; | ||
@@ -141,2 +141,8 @@ /** | ||
/** | ||
* Indicates whether there are reactions to the message | ||
* @type {boolean} | ||
*/ | ||
this.hasReaction = data.hasReaction ? true : false; | ||
/** | ||
* Indicates the duration of the message in seconds | ||
@@ -443,11 +449,12 @@ * @type {string} | ||
async delete(everyone) { | ||
await this.client.pupPage.evaluate((msgId, everyone) => { | ||
await this.client.pupPage.evaluate(async (msgId, everyone) => { | ||
let msg = window.Store.Msg.get(msgId); | ||
let chat = await window.Store.Chat.find(msg.id.remote); | ||
const canRevoke = window.Store.MsgActionChecks.canSenderRevokeMsg(msg) || window.Store.MsgActionChecks.canAdminRevokeMsg(msg); | ||
if (everyone && canRevoke) { | ||
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], { type: msg.id.fromMe ? 'Sender' : 'Admin' }); | ||
return window.Store.Cmd.sendRevokeMsgs(chat, [msg], { clearMedia: true, type: msg.id.fromMe ? 'Sender' : 'Admin' }); | ||
} | ||
return window.Store.Cmd.sendDeleteMsgs(msg.chat, [msg], true); | ||
return window.Store.Cmd.sendDeleteMsgs(chat, [msg], true); | ||
}, this.id._serialized, everyone); | ||
@@ -460,7 +467,8 @@ } | ||
async star() { | ||
await this.client.pupPage.evaluate((msgId) => { | ||
await this.client.pupPage.evaluate(async (msgId) => { | ||
let msg = window.Store.Msg.get(msgId); | ||
if (window.Store.MsgActionChecks.canStarMsg(msg)) { | ||
return window.Store.Cmd.sendStarMsgs(msg.chat, [msg], false); | ||
let chat = await window.Store.Chat.find(msg.id.remote); | ||
return window.Store.Cmd.sendStarMsgs(chat, [msg], false); | ||
} | ||
@@ -474,7 +482,8 @@ }, this.id._serialized); | ||
async unstar() { | ||
await this.client.pupPage.evaluate((msgId) => { | ||
await this.client.pupPage.evaluate(async (msgId) => { | ||
let msg = window.Store.Msg.get(msgId); | ||
if (window.Store.MsgActionChecks.canStarMsg(msg)) { | ||
return window.Store.Cmd.sendUnstarMsgs(msg.chat, [msg], false); | ||
let chat = await window.Store.Chat.find(msg.id.remote); | ||
return window.Store.Cmd.sendUnstarMsgs(chat, [msg], false); | ||
} | ||
@@ -539,4 +548,42 @@ }, this.id._serialized); | ||
} | ||
/** | ||
* Reaction List | ||
* @typedef {Object} ReactionList | ||
* @property {string} id Original emoji | ||
* @property {string} aggregateEmoji aggregate emoji | ||
* @property {boolean} hasReactionByMe Flag who sent the reaction | ||
* @property {Array<Reaction>} senders Reaction senders, to this message | ||
*/ | ||
/** | ||
* Gets the reactions associated with the given message | ||
* @return {Promise<ReactionList[]>} | ||
*/ | ||
async getReactions() { | ||
if (!this.hasReaction) { | ||
return undefined; | ||
} | ||
const reactions = await this.client.pupPage.evaluate(async (msgId) => { | ||
const msgReactions = await window.Store.Reactions.find(msgId); | ||
if (!msgReactions || !msgReactions.reactions.length) return null; | ||
return msgReactions.reactions.serialize(); | ||
}, this.id._serialized); | ||
if (!reactions) { | ||
return undefined; | ||
} | ||
return reactions.map(reaction => { | ||
reaction.senders = reaction.senders.map(sender => { | ||
sender.timestamp = Math.round(sender.timestamp / 1000); | ||
return new Reaction(this.client, sender); | ||
}); | ||
return reaction; | ||
}); | ||
} | ||
} | ||
module.exports = Message; |
@@ -16,3 +16,4 @@ 'use strict'; | ||
ffmpegPath: 'ffmpeg', | ||
bypassCSP: false | ||
bypassCSP: false, | ||
proxyAuthentication: undefined | ||
}; | ||
@@ -40,2 +41,4 @@ | ||
READY: 'ready', | ||
CHAT_REMOVED: 'chat_removed', | ||
CHAT_ARCHIVED: 'chat_archived', | ||
MESSAGE_RECEIVED: 'message', | ||
@@ -46,6 +49,9 @@ MESSAGE_CREATE: 'message_create', | ||
MESSAGE_ACK: 'message_ack', | ||
UNREAD_COUNT: 'unread_count', | ||
MESSAGE_REACTION: 'message_reaction', | ||
MEDIA_UPLOADED: 'media_uploaded', | ||
CONTACT_CHANGED: 'contact_changed', | ||
GROUP_JOIN: 'group_join', | ||
GROUP_LEAVE: 'group_leave', | ||
GROUP_ADMIN_CHANGED: 'group_admin_changed', | ||
GROUP_UPDATE: 'group_update', | ||
@@ -52,0 +58,0 @@ QR_RECEIVED: 'qr', |
@@ -44,3 +44,3 @@ 'use strict'; | ||
window.Store.ChatState = window.mR.findModule('sendChatStateComposing')[0]; | ||
window.Store.GroupParticipants = window.mR.findModule('promoteParticipants')[1]; | ||
window.Store.GroupParticipants = window.mR.findModule('promoteParticipants')[0]; | ||
window.Store.JoinInviteV4 = window.mR.findModule('sendJoinGroupViaInviteV4')[0]; | ||
@@ -58,2 +58,4 @@ window.Store.findCommonGroups = window.mR.findModule('findCommonGroups')[0].findCommonGroups; | ||
window.Store.SocketWap = window.mR.findModule('wap')[0]; | ||
window.Store.SearchContext = window.mR.findModule('getSearchContext')[0].getSearchContext; | ||
window.Store.DrawerManager = window.mR.findModule('DrawerManager')[0].DrawerManager; | ||
window.Store.StickerTools = { | ||
@@ -67,3 +69,4 @@ ...window.mR.findModule('toWebpSticker')[0], | ||
...window.mR.findModule('setGroupDescription')[0], | ||
...window.mR.findModule('sendExitGroup')[0] | ||
...window.mR.findModule('sendExitGroup')[0], | ||
...window.mR.findModule('sendSetPicture')[0] | ||
}; | ||
@@ -248,7 +251,8 @@ | ||
const isMD = window.Store.MDBackend; | ||
const newId = await window.Store.MsgKey.newId(); | ||
const newMsgId = new window.Store.MsgKey({ | ||
from: meUser, | ||
to: chat.id, | ||
id: window.Store.MsgKey.newId(), | ||
id: newId, | ||
participant: isMD && chat.id.isGroup() ? meUser : undefined, | ||
@@ -278,2 +282,3 @@ selfDir: 'out', | ||
...attOptions, | ||
...(attOptions.toJSON ? attOptions.toJSON() : {}), | ||
...quotedMsgOptions, | ||
@@ -434,3 +439,11 @@ ...vcardOptions, | ||
} | ||
res.lastMessage = null; | ||
if (res.msgs && res.msgs.length) { | ||
const lastMessage = window.Store.Msg.get(chat.lastReceivedKey._serialized); | ||
if (lastMessage) { | ||
res.lastMessage = window.WWebJS.getMessageModel(lastMessage); | ||
} | ||
} | ||
delete res.msgs; | ||
@@ -634,2 +647,71 @@ delete res.msgUnsyncedButtonReplyMsgs; | ||
}; | ||
window.WWebJS.cropAndResizeImage = async (media, options = {}) => { | ||
if (!media.mimetype.includes('image')) | ||
throw new Error('Media is not an image'); | ||
if (options.mimetype && !options.mimetype.includes('image')) | ||
delete options.mimetype; | ||
options = Object.assign({ size: 640, mimetype: media.mimetype, quality: .75, asDataUrl: false }, options); | ||
const img = await new Promise ((resolve, reject) => { | ||
const img = new Image(); | ||
img.onload = () => resolve(img); | ||
img.onerror = reject; | ||
img.src = `data:${media.mimetype};base64,${media.data}`; | ||
}); | ||
const sl = Math.min(img.width, img.height); | ||
const sx = Math.floor((img.width - sl) / 2); | ||
const sy = Math.floor((img.height - sl) / 2); | ||
const canvas = document.createElement('canvas'); | ||
canvas.width = options.size; | ||
canvas.height = options.size; | ||
const ctx = canvas.getContext('2d'); | ||
ctx.drawImage(img, sx, sy, sl, sl, 0, 0, options.size, options.size); | ||
const dataUrl = canvas.toDataURL(options.mimetype, options.quality); | ||
if (options.asDataUrl) | ||
return dataUrl; | ||
return Object.assign(media, { | ||
mimetype: options.mimeType, | ||
data: dataUrl.replace(`data:${options.mimeType};base64,`, '') | ||
}); | ||
}; | ||
window.WWebJS.setPicture = async (chatid, media) => { | ||
const thumbnail = await window.WWebJS.cropAndResizeImage(media, { asDataUrl: true, mimetype: 'image/jpeg', size: 96 }); | ||
const profilePic = await window.WWebJS.cropAndResizeImage(media, { asDataUrl: true, mimetype: 'image/jpeg', size: 640 }); | ||
const chatWid = window.Store.WidFactory.createWid(chatid); | ||
try { | ||
const collection = window.Store.ProfilePicThumb.get(chatid); | ||
if (!collection.canSet()) return; | ||
const res = await window.Store.GroupUtils.sendSetPicture(chatWid, thumbnail, profilePic); | ||
return res ? res.status === 200 : false; | ||
} catch (err) { | ||
if(err.name === 'ServerStatusCodeError') return false; | ||
throw err; | ||
} | ||
}; | ||
window.WWebJS.deletePicture = async (chatid) => { | ||
const chatWid = window.Store.WidFactory.createWid(chatid); | ||
try { | ||
const collection = window.Store.ProfilePicThumb.get(chatid); | ||
if (!collection.canDelete()) return; | ||
const res = await window.Store.GroupUtils.requestDeletePicture(chatWid); | ||
return res ? res.status === 200 : false; | ||
} catch (err) { | ||
if(err.name === 'ServerStatusCodeError') return false; | ||
throw err; | ||
} | ||
}; | ||
}; |
@@ -53,3 +53,5 @@ 'use strict'; | ||
let msg = await window.Store.Msg.get(msgId); | ||
await window.Store.Cmd.openChatAt(msg.chat, msg.chat.getSearchContext(msg)); | ||
let chat = await window.Store.Chat.find(msg.id.remote); | ||
let searchContext = await window.Store.SearchContext(chat,msg); | ||
await window.Store.Cmd.openChatAt(chat, searchContext); | ||
}, msgId); | ||
@@ -74,3 +76,3 @@ } | ||
await this.pupPage.evaluate(async () => { | ||
await window.Store.Cmd.closeDrawerRight(); | ||
await window.Store.DrawerManager.closeDrawerRight(); | ||
}); | ||
@@ -77,0 +79,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
263076
6144