feat: Channel (#2620)
* window.injectToFunction clarifications * added createChannel method * initial Channel class structure * added getChannelById and getChannels methods * added 4 methods to change channel metadata * added deleteChannel method * added subscribe to/unsubscribe from channel methods * ecmaVersion updated to 2022 * added searchChannels method * refactoring of: getChat, getChannel, getChatModel, getChannelModel * removed Channel.canSend * sendMessage updated to support channels [p1] * createChannel: returns string if an error occupied * added getSubscribers * added mute/unmute methods * searchChannels: minor update * sendMessage updated to support channels [p2] - added support to send image, sticker, gif and video * [REFAC] refactored chat retrieving in getChatOrChannel * [FEAT] added getChannelByInviteCode method * [CHG] added check if channel creation enabled * [FEAT] added sendChannelAdminInvitation method * [WIP] preparations for sending polls [p1] * [BUG] fixed some internal functions * [BUG] fixed poll creation * [COPY] renamed some internal functions - window.WWebJS.getChatOrChannel renamed back to window.WWebJS.getChat -window.WWebJS.getChatOrChannelModel renamed back to window.WWebJS.getChatModel * fix: typo * fix: send docs without caption * fix: fixed some internal function * fix: channel retrieving * fix: fixed internal getChannelMetadata function * fix: fixed channel admin can unsubscribe from channel * feat: channel admin functionality * feat: added fetchMessages method Co-authored-by: tuke307 <58882912+tuke307@users.noreply.github.com> * refactor: revert removing support for Buttons and Lists Note: buttons and lists are deprecated * refactor: revert parameter name from 'chatOrChannel' to 'chat' * fix: support Node v12 * refactor: return 'undefined' in a case of falsy value * refactor: use already created variable * docs: fix 'countryCodes' property type * fix: 'searchChannels' method fixed * fix: add check in 'setReactionSetting' method * sendNewsletterMessageJob requires a proper Msg Object in 2.24xx (#10) Co-authored-by: Sven Neumann <s.neumann@websix.de> * style: fix broken link in readme file * fix: only directPath determines whether hasMedia or not fixes #2952 * fix: get rid of unnecessary 'await' * feat: add option to send polls in channels * refactor: get channel instances with 'getChatById' * chore: fix eslint * fix: fatal error * refactor: delete local models by default when unsubscribing * fix: prevent TypeError if no channel models are returned * fix: update 'searchChannels' function for WWeb > 2.3000.0 * fix: fix for 'getChannelByInviteCode' function * fix: fix for 'sendChannelAdminInvite' function * fix: update 'fetchMessages' for channels * refactor: update 'setReactionSetting' function * fix: update 'sendMessage' for channels * feat: add 'transferChannelOwnership' function * refactor: add 'deleteChannel' function to 'Client' * style: fix project code style * chore: eslint fix * feat: add 'sendSeen' function * fix: fix the function restoration after injection * refactor: remove duplicate module * fix: get isNewsletter properly * fix: fix channels media - add mediaHandle Co-authored-by: devlikepro <155617407+devlikepro@users.noreply.github.com> --------- Co-authored-by: tuke307 <58882912+tuke307@users.noreply.github.com> Co-authored-by: Sven <sven2neumann@gmail.com> Co-authored-by: Sven Neumann <s.neumann@websix.de> Co-authored-by: devlikepro <155617407+devlikepro@users.noreply.github.com>
This commit is contained in:
parent
dd257b2039
commit
d0642b761c
3 changed files with 1241 additions and 234 deletions
|
|
@ -65,7 +65,6 @@ exports.ExposeStore = () => {
|
|||
window.Store.SendSeen = window.require('WAWebUpdateUnreadChatAction');
|
||||
window.Store.User = window.require('WAWebUserPrefsMeUser');
|
||||
window.Store.ContactMethods = window.require('WAWebContactGetters');
|
||||
window.Store.UploadUtils = window.require('WAWebUploadManager');
|
||||
window.Store.UserConstructor = window.require('WAWebWid');
|
||||
window.Store.Validators = window.require('WALinkify');
|
||||
window.Store.VCard = window.require('WAWebFrontendVcardUtils');
|
||||
|
|
@ -95,22 +94,21 @@ exports.ExposeStore = () => {
|
|||
window.Store.ReplyUtils = window.require('WAWebMsgReply');
|
||||
window.Store.BotSecret = window.require('WAWebBotMessageSecret');
|
||||
window.Store.BotProfiles = window.require('WAWebBotProfileCollection');
|
||||
window.Store.ContactCollection = window.require('WAWebContactCollection').ContactCollection;
|
||||
window.Store.DeviceList = window.require('WAWebApiDeviceList');
|
||||
window.Store.HistorySync = window.require('WAWebSendNonMessageDataRequest');
|
||||
if (window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.1014111620'))
|
||||
window.Store.AddonReactionTable = window.require('WAWebAddonReactionTableMode').reactionTableMode;
|
||||
window.Store.AddonReactionTable = window.require('WAWebAddonReactionTableMode').reactionTableMode;
|
||||
window.Store.ChatGetters = window.require('WAWebChatGetters');
|
||||
|
||||
window.Store.Settings = {
|
||||
...window.require('WAWebUserPrefsGeneral'),
|
||||
...window.require('WAWebUserPrefsNotifications'),
|
||||
setPushname: window.require('WAWebSetPushnameConnAction').setPushname
|
||||
};
|
||||
|
||||
window.Store.NumberInfo = {
|
||||
...window.require('WAPhoneUtils'),
|
||||
...window.require('WAPhoneFindCC')
|
||||
};
|
||||
|
||||
window.Store.ForwardUtils = {
|
||||
...window.require('WAWebForwardMessagesToChat')
|
||||
};
|
||||
|
|
@ -141,6 +139,37 @@ exports.ExposeStore = () => {
|
|||
...window.require('WAWebApiMembershipApprovalRequestStore'),
|
||||
...window.require('WASmaxGroupsMembershipRequestsActionRPC')
|
||||
};
|
||||
window.Store.ChannelUtils = {
|
||||
...window.require('WAWebLoadNewsletterPreviewChatAction'),
|
||||
...window.require('WAWebNewsletterMetadataQueryJob'),
|
||||
...window.require('WAWebNewsletterCreateQueryJob'),
|
||||
...window.require('WAWebEditNewsletterMetadataAction'),
|
||||
...window.require('WAWebNewsletterDeleteAction'),
|
||||
...window.require('WAWebNewsletterSubscribeAction'),
|
||||
...window.require('WAWebNewsletterUnsubscribeAction'),
|
||||
...window.require('WAWebNewsletterDirectorySearchAction'),
|
||||
...window.require('WAWebNewsletterToggleMuteStateJob'),
|
||||
...window.require('WAWebNewsletterGatingUtils'),
|
||||
...window.require('WAWebNewsletterModelUtils'),
|
||||
...window.require('WAWebMexAcceptNewsletterAdminInviteJob'),
|
||||
...window.require('WAWebMexRevokeNewsletterAdminInviteJob'),
|
||||
...window.require('WAWebChangeNewsletterOwnerAction'),
|
||||
...window.require('WAWebDemoteNewsletterAdminAction'),
|
||||
...window.require('WAWebNewsletterDemoteAdminJob'),
|
||||
countryCodesIso: window.require('WAWebCountriesNativeCountryNames'),
|
||||
currentRegion: window.require('WAWebL10N').getRegion(),
|
||||
};
|
||||
window.Store.SendChannelMessage = {
|
||||
...window.require('WAWebNewsletterUpdateMsgsRecordsJob'),
|
||||
...window.require('WAWebMsgDataFromModel'),
|
||||
...window.require('WAWebNewsletterSendMessageJob'),
|
||||
...window.require('WAWebNewsletterSendMsgAction'),
|
||||
...window.require('WAMediaCalculateFilehash')
|
||||
};
|
||||
window.Store.ChannelSubscribers = {
|
||||
...window.require('WAWebMexFetchNewsletterSubscribersJob'),
|
||||
...window.require('WAWebNewsletterSubscriberListAction')
|
||||
};
|
||||
window.Store.AddressbookContactUtils = {
|
||||
...window.require('WAWebSaveContactAction'),
|
||||
...window.require('WAWebDeleteContactAction')
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ exports.LoadUtils = () => {
|
|||
|
||||
window.WWebJS.forwardMessage = async (chatId, msgId) => {
|
||||
const msg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
|
||||
let chat = window.Store.Chat.get(chatId);
|
||||
const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
|
||||
if (window.compareWwebVersions(window.Debug.VERSION, '>', '2.3000.0')) {
|
||||
return window.Store.ForwardUtils.forwardMessagesToChats([msg], [chat], true);
|
||||
|
|
@ -15,50 +15,51 @@ exports.LoadUtils = () => {
|
|||
};
|
||||
|
||||
window.WWebJS.sendSeen = async (chatId) => {
|
||||
let chat = window.Store.Chat.get(chatId);
|
||||
if (chat !== undefined) {
|
||||
await window.Store.SendSeen.sendSeen(chat, false);
|
||||
const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
if (chat) {
|
||||
await window.Store.SendSeen.sendSeen(chat);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
window.WWebJS.sendMessage = async (chat, content, options = {}) => {
|
||||
let attOptions = {};
|
||||
if (options.attachment) {
|
||||
attOptions = options.sendMediaAsSticker
|
||||
? await window.WWebJS.processStickerData(options.attachment)
|
||||
: await window.WWebJS.processMediaData(options.attachment, {
|
||||
const isChannel = window.Store.ChatGetters.getIsNewsletter(chat);
|
||||
|
||||
let mediaOptions = {};
|
||||
if (options.media) {
|
||||
mediaOptions = await window.WWebJS.processMediaData(
|
||||
options.media, {
|
||||
forceSticker: options.sendMediaAsSticker,
|
||||
forceGif: options.sendVideoAsGif,
|
||||
forceVoice: options.sendAudioAsVoice,
|
||||
forceDocument: options.sendMediaAsDocument,
|
||||
forceGif: options.sendVideoAsGif
|
||||
sendToChannel: isChannel
|
||||
});
|
||||
|
||||
attOptions.caption = options.caption;
|
||||
content = options.sendMediaAsSticker ? undefined : attOptions.preview;
|
||||
attOptions.isViewOnce = options.isViewOnce;
|
||||
|
||||
delete options.attachment;
|
||||
mediaOptions.caption = options.caption;
|
||||
content = options.sendMediaAsSticker ? undefined : mediaOptions.preview;
|
||||
mediaOptions.isViewOnce = options.isViewOnce;
|
||||
delete options.media;
|
||||
delete options.sendMediaAsSticker;
|
||||
}
|
||||
|
||||
let quotedMsgOptions = {};
|
||||
if (options.quotedMessageId) {
|
||||
let quotedMessage = await window.Store.Msg.getMessagesById([options.quotedMessageId]);
|
||||
let quotedMessage = window.Store.Msg.get(options.quotedMessageId);
|
||||
!quotedMessage && (quotedMessage = (await window.Store.Msg.getMessagesById([options.quotedMessageId]))?.messages?.[0]);
|
||||
|
||||
if (quotedMessage['messages'].length == 1) {
|
||||
quotedMessage = quotedMessage['messages'][0];
|
||||
|
||||
// TODO remove .canReply() once all clients are updated to >= v2.2241.6
|
||||
const canReply = window.Store.ReplyUtils ?
|
||||
window.Store.ReplyUtils.canReplyMsg(quotedMessage.unsafe()) :
|
||||
quotedMessage.canReply();
|
||||
const canReply = window.Store.ReplyUtils
|
||||
? window.Store.ReplyUtils.canReplyMsg(quotedMessage.unsafe())
|
||||
: quotedMessage.canReply();
|
||||
|
||||
if (canReply) {
|
||||
quotedMsgOptions = quotedMessage.msgContextInfo(chat);
|
||||
}
|
||||
}else{
|
||||
if(!options.ignoreQuoteErrors) {
|
||||
} else {
|
||||
if (!options.ignoreQuoteErrors) {
|
||||
throw new Error('Could not get the quoted message.');
|
||||
}
|
||||
}
|
||||
|
|
@ -106,14 +107,15 @@ exports.LoadUtils = () => {
|
|||
const { pollName, pollOptions } = options.poll;
|
||||
const { allowMultipleAnswers, messageSecret } = options.poll.options;
|
||||
_pollOptions = {
|
||||
kind: 'pollCreation',
|
||||
type: 'poll_creation',
|
||||
pollName: pollName,
|
||||
pollOptions: pollOptions,
|
||||
pollSelectableOptionsCount: allowMultipleAnswers ? 0 : 1,
|
||||
messageSecret:
|
||||
Array.isArray(messageSecret) && messageSecret.length === 32
|
||||
? new Uint8Array(messageSecret)
|
||||
: window.crypto.getRandomValues(new Uint8Array(32))
|
||||
Array.isArray(messageSecret) && messageSecret.length === 32
|
||||
? new Uint8Array(messageSecret)
|
||||
: window.crypto.getRandomValues(new Uint8Array(32))
|
||||
};
|
||||
delete options.poll;
|
||||
}
|
||||
|
|
@ -164,9 +166,9 @@ exports.LoadUtils = () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let buttonOptions = {};
|
||||
if(options.buttons){
|
||||
if (options.buttons) {
|
||||
let caption;
|
||||
if (options.buttons.type === 'chat') {
|
||||
content = options.buttons.body;
|
||||
|
|
@ -214,18 +216,22 @@ exports.LoadUtils = () => {
|
|||
delete options.invokedBotWid;
|
||||
}
|
||||
|
||||
let meUser = window.Store.User.getMaybeMeUser();
|
||||
const lidUser = window.Store.User.getMaybeMeLidUser();
|
||||
const meUser = window.Store.User.getMaybeMeUser();
|
||||
const newId = await window.Store.MsgKey.newId();
|
||||
let from = chat.id.isLid() ? lidUser : meUser;
|
||||
let participant;
|
||||
|
||||
if (chat.id.isGroup() && chat.groupMetadata.isLidAddressingMode) {
|
||||
meUser = window.Store.User.getMaybeMeLidUser();
|
||||
if (chat.isGroup) {
|
||||
from = chat.groupMetadata && chat.groupMetadata.isLidAddressingMode ? lidUser : meUser;
|
||||
participant = window.Store.WidFactory.toUserWid(from);
|
||||
}
|
||||
|
||||
const newMsgId = new window.Store.MsgKey({
|
||||
from: meUser,
|
||||
|
||||
const newMsgKey = new window.Store.MsgKey({
|
||||
from: from,
|
||||
to: chat.id,
|
||||
id: newId,
|
||||
participant: chat.id.isGroup() ? meUser : undefined,
|
||||
participant: participant,
|
||||
selfDir: 'out',
|
||||
});
|
||||
|
||||
|
|
@ -236,7 +242,7 @@ exports.LoadUtils = () => {
|
|||
|
||||
const message = {
|
||||
...options,
|
||||
id: newMsgId,
|
||||
id: newMsgKey,
|
||||
ack: 0,
|
||||
body: content,
|
||||
from: meUser,
|
||||
|
|
@ -247,11 +253,11 @@ exports.LoadUtils = () => {
|
|||
isNewMsg: true,
|
||||
type: 'chat',
|
||||
...ephemeralFields,
|
||||
...mediaOptions,
|
||||
...(mediaOptions.toJSON ? mediaOptions.toJSON() : {}),
|
||||
...quotedMsgOptions,
|
||||
...locationOptions,
|
||||
..._pollOptions,
|
||||
...attOptions,
|
||||
...(attOptions.toJSON ? attOptions.toJSON() : {}),
|
||||
...quotedMsgOptions,
|
||||
...vcardOptions,
|
||||
...buttonOptions,
|
||||
...listOptions,
|
||||
|
|
@ -264,12 +270,41 @@ exports.LoadUtils = () => {
|
|||
delete message.canonicalUrl;
|
||||
}
|
||||
|
||||
if (isChannel) {
|
||||
const msg = new window.Store.Msg.modelClass(message);
|
||||
const msgDataFromMsgModel = window.Store.SendChannelMessage.msgDataFromMsgModel(msg);
|
||||
const isMedia = Object.keys(mediaOptions).length > 0;
|
||||
await window.Store.SendChannelMessage.addNewsletterMsgsRecords([msgDataFromMsgModel]);
|
||||
chat.msgs.add(msg);
|
||||
chat.t = msg.t;
|
||||
|
||||
const sendChannelMsgResponse = await window.Store.SendChannelMessage.sendNewsletterMessageJob({
|
||||
msg: msg,
|
||||
type: message.type === 'chat' ? 'text' : isMedia ? 'media' : 'pollCreation',
|
||||
newsletterJid: chat.id.toJid(),
|
||||
...(isMedia
|
||||
? {
|
||||
mediaMetadata: msg.avParams(),
|
||||
mediaHandle: isMedia ? mediaOptions.mediaHandle : null,
|
||||
}
|
||||
: {}
|
||||
)
|
||||
});
|
||||
|
||||
if (sendChannelMsgResponse.success) {
|
||||
msg.t = sendChannelMsgResponse.ack.t;
|
||||
msg.serverId = sendChannelMsgResponse.serverId;
|
||||
}
|
||||
msg.updateAck(1, true);
|
||||
await window.Store.SendChannelMessage.updateNewsletterMsgRecord(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
|
||||
return window.Store.Msg.get(newMsgId._serialized);
|
||||
return window.Store.Msg.get(newMsgKey._serialized);
|
||||
};
|
||||
|
||||
window.WWebJS.editMessage = async (msg, content, options = {}) => {
|
||||
|
||||
const extraOptions = options.extraOptions || {};
|
||||
delete options.extraOptions;
|
||||
|
||||
|
|
@ -327,74 +362,51 @@ exports.LoadUtils = () => {
|
|||
};
|
||||
};
|
||||
|
||||
window.WWebJS.processStickerData = async (mediaInfo) => {
|
||||
if (mediaInfo.mimetype !== 'image/webp') throw new Error('Invalid media type');
|
||||
|
||||
window.WWebJS.processMediaData = async (mediaInfo, { forceSticker, forceGif, forceVoice, forceDocument, sendToChannel }) => {
|
||||
const file = window.WWebJS.mediaInfoToFile(mediaInfo);
|
||||
let filehash = await window.WWebJS.getFileHash(file);
|
||||
let mediaKey = await window.WWebJS.generateHash(32);
|
||||
|
||||
const controller = new AbortController();
|
||||
const uploadedInfo = await window.Store.UploadUtils.encryptAndUpload({
|
||||
blob: file,
|
||||
type: 'sticker',
|
||||
signal: controller.signal,
|
||||
mediaKey
|
||||
});
|
||||
|
||||
const stickerInfo = {
|
||||
...uploadedInfo,
|
||||
clientUrl: uploadedInfo.url,
|
||||
deprecatedMms3Url: uploadedInfo.url,
|
||||
uploadhash: uploadedInfo.encFilehash,
|
||||
size: file.size,
|
||||
type: 'sticker',
|
||||
filehash
|
||||
};
|
||||
|
||||
return stickerInfo;
|
||||
};
|
||||
|
||||
window.WWebJS.processMediaData = async (mediaInfo, { forceVoice, forceDocument, forceGif }) => {
|
||||
const file = window.WWebJS.mediaInfoToFile(mediaInfo);
|
||||
const mData = await window.Store.OpaqueData.createFromData(file, file.type);
|
||||
const mediaPrep = window.Store.MediaPrep.prepRawMedia(mData, { asDocument: forceDocument });
|
||||
const opaqueData = await window.Store.OpaqueData.createFromData(file, file.type);
|
||||
const mediaPrep = window.Store.MediaPrep.prepRawMedia(
|
||||
opaqueData, {
|
||||
asSticker: forceSticker,
|
||||
asGif: forceGif,
|
||||
isPtt: forceVoice,
|
||||
asDocument: forceDocument
|
||||
});
|
||||
const mediaData = await mediaPrep.waitForPrep();
|
||||
const mediaObject = window.Store.MediaObject.getOrCreateMediaObject(mediaData.filehash);
|
||||
|
||||
const mediaType = window.Store.MediaTypes.msgToMediaType({
|
||||
type: mediaData.type,
|
||||
isGif: mediaData.isGif
|
||||
isGif: mediaData.isGif,
|
||||
isNewsletter: sendToChannel,
|
||||
});
|
||||
|
||||
if (forceVoice && mediaData.type === 'audio') {
|
||||
mediaData.type = 'ptt';
|
||||
if (forceVoice && mediaData.type === 'ptt') {
|
||||
const waveform = mediaObject.contentInfo.waveform;
|
||||
mediaData.waveform =
|
||||
waveform ?? await window.WWebJS.generateWaveform(file);
|
||||
}
|
||||
|
||||
if (forceGif && mediaData.type === 'video') {
|
||||
mediaData.isGif = true;
|
||||
}
|
||||
|
||||
if (forceDocument) {
|
||||
mediaData.type = 'document';
|
||||
waveform || await window.WWebJS.generateWaveform(file);
|
||||
}
|
||||
|
||||
if (!(mediaData.mediaBlob instanceof window.Store.OpaqueData)) {
|
||||
mediaData.mediaBlob = await window.Store.OpaqueData.createFromData(mediaData.mediaBlob, mediaData.mediaBlob.type);
|
||||
mediaData.mediaBlob = await window.Store.OpaqueData.createFromData(
|
||||
mediaData.mediaBlob,
|
||||
mediaData.mediaBlob.type
|
||||
);
|
||||
}
|
||||
|
||||
mediaData.renderableUrl = mediaData.mediaBlob.url();
|
||||
mediaObject.consolidate(mediaData.toJSON());
|
||||
mediaData.mediaBlob.autorelease();
|
||||
|
||||
const uploadedMedia = await window.Store.MediaUpload.uploadMedia({
|
||||
const dataToUpload = {
|
||||
mimetype: mediaData.mimetype,
|
||||
mediaObject,
|
||||
mediaType
|
||||
});
|
||||
mediaType,
|
||||
...(sendToChannel ? { calculateToken: window.Store.SendChannelMessage.getRandomFilehash } : {})
|
||||
};
|
||||
|
||||
const uploadedMedia = !sendToChannel
|
||||
? await window.Store.MediaUpload.uploadMedia(dataToUpload)
|
||||
: await window.Store.MediaUpload.uploadUnencryptedMedia(dataToUpload);
|
||||
|
||||
const mediaEntry = uploadedMedia.mediaEntry;
|
||||
if (!mediaEntry) {
|
||||
|
|
@ -412,13 +424,14 @@ exports.LoadUtils = () => {
|
|||
uploadhash: mediaEntry.uploadHash,
|
||||
size: mediaObject.size,
|
||||
streamingSidecar: mediaEntry.sidecar,
|
||||
firstFrameSidecar: mediaEntry.firstFrameSidecar
|
||||
firstFrameSidecar: mediaEntry.firstFrameSidecar,
|
||||
mediaHandle: sendToChannel ? mediaEntry.handle : null,
|
||||
});
|
||||
|
||||
return mediaData;
|
||||
};
|
||||
|
||||
window.WWebJS.getMessageModel = message => {
|
||||
window.WWebJS.getMessageModel = (message) => {
|
||||
const msg = message.serialize();
|
||||
|
||||
msg.isEphemeral = message.isEphemeral;
|
||||
|
|
@ -456,54 +469,115 @@ exports.LoadUtils = () => {
|
|||
return _vote;
|
||||
};
|
||||
|
||||
window.WWebJS.getChatModel = async chat => {
|
||||
window.WWebJS.getChat = async (chatId, { getAsModel = true } = {}) => {
|
||||
const isChannel = /@\w*newsletter\b/.test(chatId);
|
||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
||||
let chat;
|
||||
|
||||
let res = chat.serialize();
|
||||
res.isGroup = false;
|
||||
res.formattedTitle = chat.formattedTitle;
|
||||
res.isMuted = chat.mute?.expiration !== 0;
|
||||
|
||||
if (chat.groupMetadata) {
|
||||
res.isGroup = true;
|
||||
const chatWid = window.Store.WidFactory.createWid((chat.id._serialized));
|
||||
await window.Store.GroupMetadata.update(chatWid);
|
||||
chat.groupMetadata.participants._models
|
||||
.filter(x => x.id._serialized.endsWith('@lid'))
|
||||
.forEach(x => { x.id = x.contact.phoneNumber; });
|
||||
res.groupMetadata = chat.groupMetadata.serialize();
|
||||
res.isReadOnly = chat.groupMetadata.announce;
|
||||
}
|
||||
|
||||
res.lastMessage = null;
|
||||
if (res.msgs && res.msgs.length) {
|
||||
const lastMessage = chat.lastReceivedKey
|
||||
? window.Store.Msg.get(chat.lastReceivedKey._serialized) || (await window.Store.Msg.getMessagesById([chat.lastReceivedKey._serialized]))?.messages?.[0]
|
||||
: null;
|
||||
if (lastMessage) {
|
||||
res.lastMessage = window.WWebJS.getMessageModel(lastMessage);
|
||||
if (isChannel) {
|
||||
try {
|
||||
chat = window.Store.NewsletterCollection.get(chatId);
|
||||
if (!chat) {
|
||||
await window.Store.ChannelUtils.loadNewsletterPreviewChat(chatId);
|
||||
chat = await window.Store.NewsletterCollection.find(chatWid);
|
||||
}
|
||||
} catch (err) {
|
||||
chat = null;
|
||||
}
|
||||
} else {
|
||||
chat = window.Store.Chat.get(chatWid) || (await window.Store.Chat.find(chatWid));
|
||||
}
|
||||
|
||||
delete res.msgs;
|
||||
delete res.msgUnsyncedButtonReplyMsgs;
|
||||
delete res.unsyncedButtonReplies;
|
||||
|
||||
return res;
|
||||
return getAsModel && chat
|
||||
? await window.WWebJS.getChatModel(chat, { isChannel: isChannel })
|
||||
: chat;
|
||||
};
|
||||
|
||||
window.WWebJS.getChat = async chatId => {
|
||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
||||
const chat = await window.Store.Chat.find(chatWid);
|
||||
return await window.WWebJS.getChatModel(chat);
|
||||
window.WWebJS.getChannelMetadata = async (inviteCode) => {
|
||||
const response =
|
||||
await window.Store.ChannelUtils.queryNewsletterMetadataByInviteCode(
|
||||
inviteCode,
|
||||
window.Store.ChannelUtils.getRoleByIdentifier(inviteCode)
|
||||
);
|
||||
|
||||
const picUrl = response.newsletterPictureMetadataMixin?.picture[0]?.queryPictureDirectPathOrEmptyResponseMixinGroup.value.directPath;
|
||||
|
||||
return {
|
||||
id: response.idJid,
|
||||
createdAtTs: response.newsletterCreationTimeMetadataMixin.creationTimeValue,
|
||||
titleMetadata: {
|
||||
title: response.newsletterNameMetadataMixin.nameElementValue,
|
||||
updatedAtTs: response.newsletterNameMetadataMixin.nameUpdateTime
|
||||
},
|
||||
descriptionMetadata: {
|
||||
description: response.newsletterDescriptionMetadataMixin.descriptionQueryDescriptionResponseMixin.elementValue,
|
||||
updatedAtTs: response.newsletterDescriptionMetadataMixin.descriptionQueryDescriptionResponseMixin.updateTime
|
||||
},
|
||||
inviteLink: `https://whatsapp.com/channel/${response.newsletterInviteLinkMetadataMixin.inviteCode}`,
|
||||
membershipType: window.Store.ChannelUtils.getRoleByIdentifier(inviteCode),
|
||||
stateType: response.newsletterStateMetadataMixin.stateType,
|
||||
pictureUrl: picUrl ? `https://pps.whatsapp.net${picUrl}` : null,
|
||||
subscribersCount: response.newsletterSubscribersMetadataMixin.subscribersCount,
|
||||
isVerified: response.newsletterVerificationMetadataMixin.verificationState === 'verified'
|
||||
};
|
||||
};
|
||||
|
||||
window.WWebJS.getChats = async () => {
|
||||
const chats = window.Store.Chat.getModelsArray();
|
||||
|
||||
const chatPromises = chats.map(chat => window.WWebJS.getChatModel(chat));
|
||||
return await Promise.all(chatPromises);
|
||||
};
|
||||
|
||||
window.WWebJS.getChannels = async () => {
|
||||
const channels = window.Store.NewsletterCollection.getModelsArray();
|
||||
const channelPromises = channels?.map((channel) => window.WWebJS.getChatModel(channel, { isChannel: true }));
|
||||
return await Promise.all(channelPromises);
|
||||
};
|
||||
|
||||
window.WWebJS.getChatModel = async (chat, { isChannel = false } = {}) => {
|
||||
if (!chat) return null;
|
||||
|
||||
const model = chat.serialize();
|
||||
model.isGroup = false;
|
||||
model.isMuted = chat.mute?.expiration !== 0;
|
||||
if (isChannel) {
|
||||
model.isChannel = window.Store.ChatGetters.getIsNewsletter(chat);
|
||||
} else {
|
||||
model.formattedTitle = chat.formattedTitle;
|
||||
}
|
||||
|
||||
if (chat.groupMetadata) {
|
||||
model.isGroup = true;
|
||||
const chatWid = window.Store.WidFactory.createWid(chat.id._serialized);
|
||||
await window.Store.GroupMetadata.update(chatWid);
|
||||
model.groupMetadata.participants._models
|
||||
.filter(x => x.id._serialized.endsWith('@lid'))
|
||||
.forEach(x => { x.id = x.contact.phoneNumber; });
|
||||
model.groupMetadata = chat.groupMetadata.serialize();
|
||||
model.isReadOnly = chat.groupMetadata.announce;
|
||||
}
|
||||
|
||||
if (chat.newsletterMetadata) {
|
||||
await window.Store.NewsletterMetadataCollection.update(chat.id);
|
||||
model.channelMetadata = chat.newsletterMetadata.serialize();
|
||||
model.channelMetadata.createdAtTs = chat.newsletterMetadata.creationTime;
|
||||
}
|
||||
|
||||
model.lastMessage = null;
|
||||
if (model.msgs && model.msgs.length) {
|
||||
const lastMessage = chat.lastReceivedKey
|
||||
? window.Store.Msg.get(chat.lastReceivedKey._serialized) || (await window.Store.Msg.getMessagesById([chat.lastReceivedKey._serialized]))?.messages?.[0]
|
||||
: null;
|
||||
lastMessage && (model.lastMessage = window.WWebJS.getMessageModel(lastMessage));
|
||||
}
|
||||
|
||||
delete model.msgs;
|
||||
delete model.msgUnsyncedButtonReplyMsgs;
|
||||
delete model.unsyncedButtonReplies;
|
||||
|
||||
return model;
|
||||
};
|
||||
|
||||
window.WWebJS.getContactModel = contact => {
|
||||
let res = contact.serialize();
|
||||
res.isBusiness = contact.isBusiness === undefined ? false : contact.isBusiness;
|
||||
|
|
@ -512,50 +586,20 @@ exports.LoadUtils = () => {
|
|||
res.businessProfile = contact.businessProfile.serialize();
|
||||
}
|
||||
|
||||
// TODO: remove useOldImplementation and its checks once all clients are updated to >= v2.2327.4
|
||||
const useOldImplementation
|
||||
= window.compareWwebVersions(window.Debug.VERSION, '<', '2.2327.4');
|
||||
|
||||
res.isMe = useOldImplementation
|
||||
? contact.isMe
|
||||
: window.Store.ContactMethods.getIsMe(contact);
|
||||
res.isUser = useOldImplementation
|
||||
? contact.isUser
|
||||
: window.Store.ContactMethods.getIsUser(contact);
|
||||
res.isGroup = useOldImplementation
|
||||
? contact.isGroup
|
||||
: window.Store.ContactMethods.getIsGroup(contact);
|
||||
res.isWAContact = useOldImplementation
|
||||
? contact.isWAContact
|
||||
: window.Store.ContactMethods.getIsWAContact(contact);
|
||||
res.isMyContact = useOldImplementation
|
||||
? contact.isMyContact
|
||||
: window.Store.ContactMethods.getIsMyContact(contact);
|
||||
res.isMe = window.Store.ContactMethods.getIsMe(contact);
|
||||
res.isUser = window.Store.ContactMethods.getIsUser(contact);
|
||||
res.isGroup = window.Store.ContactMethods.getIsGroup(contact);
|
||||
res.isWAContact = window.Store.ContactMethods.getIsWAContact(contact);
|
||||
res.isMyContact = window.Store.ContactMethods.getIsMyContact(contact);
|
||||
res.isBlocked = contact.isContactBlocked;
|
||||
res.userid = useOldImplementation
|
||||
? contact.userid
|
||||
: window.Store.ContactMethods.getUserid(contact);
|
||||
res.isEnterprise = useOldImplementation
|
||||
? contact.isEnterprise
|
||||
: window.Store.ContactMethods.getIsEnterprise(contact);
|
||||
res.verifiedName = useOldImplementation
|
||||
? contact.verifiedName
|
||||
: window.Store.ContactMethods.getVerifiedName(contact);
|
||||
res.verifiedLevel = useOldImplementation
|
||||
? contact.verifiedLevel
|
||||
: window.Store.ContactMethods.getVerifiedLevel(contact);
|
||||
res.statusMute = useOldImplementation
|
||||
? contact.statusMute
|
||||
: window.Store.ContactMethods.getStatusMute(contact);
|
||||
res.name = useOldImplementation
|
||||
? contact.name
|
||||
: window.Store.ContactMethods.getName(contact);
|
||||
res.shortName = useOldImplementation
|
||||
? contact.shortName
|
||||
: window.Store.ContactMethods.getShortName(contact);
|
||||
res.pushname = useOldImplementation
|
||||
? contact.pushname
|
||||
: window.Store.ContactMethods.getPushname(contact);
|
||||
res.userid = window.Store.ContactMethods.getUserid(contact);
|
||||
res.isEnterprise = window.Store.ContactMethods.getIsEnterprise(contact);
|
||||
res.verifiedName = window.Store.ContactMethods.getVerifiedName(contact);
|
||||
res.verifiedLevel = window.Store.ContactMethods.getVerifiedLevel(contact);
|
||||
res.statusMute = window.Store.ContactMethods.getStatusMute(contact);
|
||||
res.name = window.Store.ContactMethods.getName(contact);
|
||||
res.shortName = window.Store.ContactMethods.getShortName(contact);
|
||||
res.pushname = window.Store.ContactMethods.getPushname(contact);
|
||||
|
||||
return res;
|
||||
};
|
||||
|
|
@ -632,10 +676,6 @@ exports.LoadUtils = () => {
|
|||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Referenced from and modified:
|
||||
* @see https://github.com/wppconnect-team/wa-js/commit/290ebfefe6021b3d17f7fdfdda5545bb0473b26f
|
||||
*/
|
||||
window.WWebJS.generateWaveform = async (audioFile) => {
|
||||
try {
|
||||
const audioData = await audioFile.arrayBuffer();
|
||||
|
|
@ -669,7 +709,7 @@ exports.LoadUtils = () => {
|
|||
};
|
||||
|
||||
window.WWebJS.sendClearChat = async (chatId) => {
|
||||
let chat = window.Store.Chat.get(chatId);
|
||||
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
if (chat !== undefined) {
|
||||
await window.Store.SendClear.sendClear(chat, false);
|
||||
return true;
|
||||
|
|
@ -678,7 +718,7 @@ exports.LoadUtils = () => {
|
|||
};
|
||||
|
||||
window.WWebJS.sendDeleteChat = async (chatId) => {
|
||||
let chat = window.Store.Chat.get(chatId);
|
||||
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
if (chat !== undefined) {
|
||||
await window.Store.SendDelete.sendDelete(chat);
|
||||
return true;
|
||||
|
|
@ -908,7 +948,7 @@ exports.LoadUtils = () => {
|
|||
}
|
||||
|
||||
if (rpcResult.name === 'AddParticipantsResponseSuccess') {
|
||||
const code = resultArgs?.value.error ?? '200';
|
||||
const code = resultArgs?.value.error || '200';
|
||||
data.name = resultArgs?.name;
|
||||
data.code = +code;
|
||||
data.inviteV4Code = resultArgs?.value.addRequestCode;
|
||||
|
|
@ -1023,6 +1063,25 @@ exports.LoadUtils = () => {
|
|||
}
|
||||
};
|
||||
|
||||
window.WWebJS.subscribeToUnsubscribeFromChannel = async (channelId, action, options = {}) => {
|
||||
const channel = await window.WWebJS.getChat(channelId, { getAsModel: false });
|
||||
|
||||
if (!channel || channel.newsletterMetadata.membershipType === 'owner') return false;
|
||||
options = { eventSurface: 3, deleteLocalModels: options.deleteLocalModels ?? true };
|
||||
|
||||
try {
|
||||
if (action === 'Subscribe') {
|
||||
await window.Store.ChannelUtils.subscribeToNewsletterAction(channel, options);
|
||||
} else if (action === 'Unsubscribe') {
|
||||
await window.Store.ChannelUtils.unsubscribeFromNewsletterAction(channel, options);
|
||||
} else return false;
|
||||
return true;
|
||||
} catch (err) {
|
||||
if (err.name === 'ServerStatusCodeError') return false;
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
window.WWebJS.pinUnpinMsgAction = async (msgId, action, duration) => {
|
||||
const message = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
|
||||
if (!message) return false;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,8 @@ class InterfaceController {
|
|||
* @param {string} chatId ID of the chat window that will be opened
|
||||
*/
|
||||
async openChatWindow(chatId) {
|
||||
await this.pupPage.evaluate(async chatId => {
|
||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
||||
const chat = window.Store.Chat.get(chatWid) || await window.Store.Chat.find(chatWid);
|
||||
await this.pupPage.evaluate(async (chatId) => {
|
||||
const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
await window.Store.Cmd.openChatBottom(chat);
|
||||
}, chatId);
|
||||
}
|
||||
|
|
@ -27,7 +26,7 @@ class InterfaceController {
|
|||
*/
|
||||
async openChatDrawer(chatId) {
|
||||
await this.pupPage.evaluate(async chatId => {
|
||||
let chat = await window.Store.Chat.get(chatId);
|
||||
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
await window.Store.Cmd.openDrawerMid(chat);
|
||||
}, chatId);
|
||||
}
|
||||
|
|
@ -38,7 +37,7 @@ class InterfaceController {
|
|||
*/
|
||||
async openChatSearch(chatId) {
|
||||
await this.pupPage.evaluate(async chatId => {
|
||||
let chat = await window.Store.Chat.get(chatId);
|
||||
let chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
await window.Store.Cmd.chatSearch(chat);
|
||||
}, chatId);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue