Skip to content

Commit

Permalink
Fix: Fixed send status functions (#2074)
Browse files Browse the repository at this point in the history
  • Loading branch information
icleitoncosta authored Jul 8, 2024
1 parent fa01117 commit 740d1b5
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 87 deletions.
118 changes: 93 additions & 25 deletions src/chat/functions/sendFileMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,29 @@
import Debug from 'debug';

import { assertFindChat, assertGetChat } from '../../assert';
import { blobToArrayBuffer, getVideoInfoFromBuffer } from '../../util';
import {
blobToArrayBuffer,
createWid,
getVideoInfoFromBuffer,
WPPError,
} from '../../util';
import { convertToFile } from '../../util/convertToFile';
import * as webpack from '../../webpack';
import { MediaPrep, MsgModel, OpaqueData } from '../../whatsapp';
import {
ChatModel,
MediaPrep,
MsgKey,
MsgModel,
OpaqueData,
StatusV3Store,
} from '../../whatsapp';
import { SendMsgResult } from '../../whatsapp/enums';
import { wrapModuleFunction } from '../../whatsapp/exportModule';
import {
generateVideoThumbsAndDuration,
isAnimatedWebp,
processRawSticker,
STATUS_JID,
uploadMedia,
} from '../../whatsapp/functions';
import {
Expand All @@ -35,6 +49,7 @@ import {
SendMessageReturn,
} from '..';
import {
getMessageById,
markIsRead,
MessageButtonsOptions,
prepareMessageButtons,
Expand Down Expand Up @@ -242,9 +257,14 @@ export async function sendFileMessage(
...options,
};

const chat = options.createChat
let chat = options.createChat
? await assertFindChat(chatId)
: assertGetChat(chatId);
if (chatId?.toString() == 'status@broadcast') {
chat = new ChatModel({
id: createWid(STATUS_JID),
});
}

const file = await convertToFile(content, options.mimetype, options.filename);

Expand Down Expand Up @@ -319,45 +339,93 @@ export async function sendFileMessage(
caption: options.caption,
footer: options.footer,
isViewOnce,
productMsgOptions: rawMessage,
productMsgOptions: chatId === 'status@broadcast' ? undefined : rawMessage,
addEvenWhilePreparing: false,
type: rawMessage.type,
} as any);

// Wait for message register
const message = await new Promise<MsgModel>((resolve) => {
chat.msgs.on('add', function fn(msg: MsgModel) {
if (msg.id === rawMessage.id) {
chat.msgs.off('add', fn);
resolve(msg);
}
let message: any = null;

if (rawMessage.to?.toString() == 'status@broadcast') {
message = await new Promise<MsgModel>((resolve) => {
StatusV3Store.on(
'change:lastReceivedKey',
async function fn(chat: ChatModel, msgKey: MsgKey) {
if (chat.id.toString() == rawMessage.from?.toString()) {
StatusV3Store.off('change:lastReceivedKey', fn);
const message = await getMessageById(msgKey);
resolve(message);
}
}
);
});
});
} else {
message = await new Promise<MsgModel>((resolve) => {
chat.msgs.on('add', function fn(msg: MsgModel) {
if (msg.id === rawMessage.id) {
chat.msgs.off('add', fn);
resolve(msg);
}
});
});
}

debug(`message file ${message.id} queued`);

function uploadStage(mediaData: any, stage: string) {
debug(`message file ${message.id} is ${stage}`);
}

message.on('change:mediaData.mediaStage', uploadStage);

sendMsgResult.finally(() => {
message.off('change:mediaData.mediaStage', uploadStage);
});

if (options.waitForAck) {
debug(`waiting ack for ${message.id}`);
if (chatId !== 'status@broadcast') {
if (options.waitForAck) {
debug(`waiting ack for ${message.id}`);

const sendResult = await sendMsgResult;
const sendResult = await sendMsgResult;

debug(
`ack received for ${message.id} (ACK: ${message.ack}, SendResult: ${sendResult})`
);
}
debug(
`ack received for ${message.id} (ACK: ${message.ack}, SendResult: ${sendResult})`
);
}

return {
id: message.id.toString(),
ack: message.ack!,
sendMsgResult,
};
return {
id: message.id?.toString(),
ack: message.ack!,
sendMsgResult,
};
} else {
// Forced a mode to return the ID since sendMediaResult was giving an error when sending with certain parameters.
const msg = await new Promise<MsgModel>((resolve, reject) => {
const timeout = setTimeout(() => {
reject(
new WPPError(
'timeout_on_send_status',
'Timeout for wait response of send media status'
)
);
}, 30000);

const interval = setInterval(async () => {
const get = await getMessageById(message.id);
if (get.ack! > 0) {
clearInterval(interval);
clearTimeout(timeout);
resolve(get);
}
}, 1500);
});
return {
id: msg.id?.toString(),
ack: msg.ack!,
sendMsgResult: {
messageSendResult: SendMsgResult.OK,
} as any,
};
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/status/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

export { get } from './get';
export { getMyStatus } from './getMyStatus';
export { remove } from './remove';
export { ImageStatusOptions, sendImageStatus } from './sendImageStatus';
export { sendRawStatus, SendStatusOptions } from './sendRawStatus';
export { sendReadStatus } from './sendReadStatus';
Expand Down
4 changes: 2 additions & 2 deletions src/status/functions/postSendStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ import { SendMessageReturn } from '../../chat';
import { MsgStore, StatusV3Store } from '../../whatsapp';

export function postSendStatus(result: SendMessageReturn): void {
result.sendMsgResult.then(() => {
result.sendMsgResult.then(async () => {
const msg = MsgStore.get(result.id);

if (!msg) {
return;
}
StatusV3Store.addStatusMessages(msg.author as any, [msg]);

// Trigger screen update
StatusV3Store.handleUpdate(msg.attributes, null, false);

const myStatus = StatusV3Store.getMyStatus();

if (myStatus) {
Expand Down
33 changes: 33 additions & 0 deletions src/status/functions/remove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*!
* Copyright 2021 WPPConnect Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { getMessageById } from '../../chat';
import { WPPError } from '../../util';
import { MsgKey, StatusV3Store, UserPrefs } from '../../whatsapp';
import { revokeStatus } from '../../whatsapp/functions';

export async function remove(msgId: string | MsgKey): Promise<boolean> {
const msg = await getMessageById(msgId);
try {
await revokeStatus(StatusV3Store.get(UserPrefs.getMeUser()) as any, msg);
return true;
} catch (error) {
throw new WPPError(
'error_on_remove_status',
`Error on remove status with id ${msgId.toString()}`
);
}
}
2 changes: 0 additions & 2 deletions src/status/functions/sendImageStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { sendFileMessage } from '../../chat';
import { MsgKey, UserPrefs } from '../../whatsapp';
import { randomHex } from '../../whatsapp/functions';
import { defaultSendStatusOptions } from '..';
import { postSendStatus } from './postSendStatus';
import { SendStatusOptions } from './sendRawStatus';

export type ImageStatusOptions = SendStatusOptions;
Expand Down Expand Up @@ -54,7 +53,6 @@ export async function sendImageStatus(
createChat: true,
type: 'image',
});
postSendStatus(result);

return result;
}
91 changes: 43 additions & 48 deletions src/status/functions/sendRawStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@
import { assertWid } from '../../assert';
import * as Chat from '../../chat';
import * as webpack from '../../webpack';
import { functions, MsgKey, UserPrefs } from '../../whatsapp';
import { MsgKey, UserPrefs } from '../../whatsapp';
import { wrapModuleFunction } from '../../whatsapp/exportModule';
import {
CHAT_JID,
createMsgProtobuf,
encryptAndSendMsg,
encryptAndSendSenderKeyMsg,
GROUP_JID,
encryptAndSendStatusMsg,
getABPropConfigValue,
primaryFeatureEnabled,
randomHex,
} from '../../whatsapp/functions';
import { defaultSendStatusOptions, updateParticipants } from '..';
import { defaultSendStatusOptions } from '..';
import { postSendStatus } from './postSendStatus';

export interface SendStatusOptions {
waitForAck?: boolean;
// Only for text status
messageId?: string | MsgKey;
// Only image and video status
caption?: string;
}

export async function sendRawStatus(
Expand All @@ -52,7 +55,6 @@ export async function sendRawStatus(
...options,
};

message.ctwaContext = message.ctwaContext || {};
message.author = UserPrefs.getMaybeMeUser();

const result = await Chat.sendRawMessage('status@broadcast', message, {
Expand Down Expand Up @@ -92,54 +94,47 @@ webpack.onInjected(() => {

// Force to send as group for broadcast list
wrapModuleFunction(encryptAndSendMsg, async (func, ...args) => {
const [, data] = args;

try {
return await func(...args);
} catch (error: any) {
const to = data.to;

if (
!to?.isStatusV3() ||
error.message !== '[messaging] unsupported remote jid type'
) {
throw error;
const [msg, perf] = args;
if (msg.data.to?.toString() == 'status@broadcast') {
const proto = createMsgProtobuf(msg.data);
try {
await encryptAndSendStatusMsg(msg as any, proto, perf);
return {
t: msg.data.t,
sync: null,
phash: null,
addressingMode: null,
count: null,
error: null,
};
} catch (error) {
return null;
}

if (localStorage.getItem('wpp-status-participants') !== 'custom') {
await updateParticipants();
}

const participants = await functions.getParticipants(to);

if (!participants || participants.participants.length === 0) {
throw new Error('empty participants for status@broadcast');
}

await functions.markForgetSenderKey(
to,
participants.participants.map(assertWid)
);

args[1].to.server = 'g.us';

return await func(...args);
}
return await func(...args);
});
});

wrapModuleFunction(encryptAndSendSenderKeyMsg, async (func, ...args) => {
try {
if (args[1].to.user === 'status') {
args[1].to.server = 'broadcast';
}
} catch (error) {}

return await func(...args);
webpack.onFullReady(() => {
// Force to load buttons and post status in whatsapp web
wrapModuleFunction(getABPropConfigValue, (func, ...args) => {
const [key] = args;
switch (key) {
case 'web_status_posting_enabled':
return 1;
case 'post_status_in_companion':
return 1;
}
return func(...args);
});

wrapModuleFunction(GROUP_JID, (func, ...args) => {
if (args[0].toString().includes('broadcast')) {
return CHAT_JID(...args);
wrapModuleFunction(primaryFeatureEnabled, (func, ...args) => {
const [key] = args;
switch (key) {
case 'post_status_in_companion':
return true;
case 'text_status_creation_support':
return true;
}
return func(...args);
});
Expand Down
Loading

0 comments on commit 740d1b5

Please sign in to comment.