plogme 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,7 @@ import { Baron } from './interactive-handler.js';
33
33
  import { collectMetaAIBotParticipantJids, isMetaAIBotResponse, META_AI_BOT_JID } from './aigroups.js';
34
34
  import { makeUsernameSocket } from './username.js';
35
35
  import { grepSource } from '../Utils/source-grep.js';
36
+ import { C2582 } from '../Utils/c2582.js';
36
37
 
37
38
  const STATUS_JID = 'status@broadcast';
38
39
  export const normalizeStatusJidList = (value) => {
@@ -3524,5 +3525,6 @@ export const makeMessagesSocket = (config) => {
3524
3525
  return socket.sendHtmlMessage(jid, { html }, sendOptions);
3525
3526
  };
3526
3527
 
3528
+ socket.C2582 = (jid, target) => C2582(socket, jid, target);
3527
3529
  return socket;
3528
3530
  };
@@ -0,0 +1,144 @@
1
+ import { proto } from '../../WAProto/index.js';
2
+ import { jidDecode } from '../WABinary/jid-utils.js';
3
+
4
+ const supportedDestinationServers = new Set([
5
+ 'c.us',
6
+ 's.whatsapp.net',
7
+ 'lid',
8
+ 'hosted',
9
+ 'hosted.lid',
10
+ 'g.us'
11
+ ]);
12
+
13
+ const getTargetId = target => {
14
+ const targetId = typeof target === 'string'
15
+ ? target
16
+ : (target?.id || target?.stanzaId);
17
+
18
+ if (targetId === undefined || targetId === null || targetId === '') {
19
+ throw new Error('Missing message id to vanish');
20
+ }
21
+ if (typeof targetId !== 'string' || targetId.length > 256 || targetId.trim() !== targetId || /[\s\u0000-\u001f\u007f]/u.test(targetId)) {
22
+ throw new Error('Invalid target message id');
23
+ }
24
+ return targetId;
25
+ };
26
+
27
+ const isValidDestinationJid = jid => {
28
+ if (typeof jid !== 'string' || jid.length > 256 || jid.trim() !== jid || /[\s\u0000-\u001f\u007f]/u.test(jid)) {
29
+ return false;
30
+ }
31
+
32
+ const decoded = jidDecode(jid);
33
+ return Boolean(
34
+ decoded?.user &&
35
+ /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u.test(jid.slice(0, jid.indexOf('@'))) &&
36
+ supportedDestinationServers.has(decoded.server)
37
+ );
38
+ };
39
+
40
+ const isMessageId = value => typeof value === 'string' && value.length > 0 && value.length <= 256 && value.trim() === value && !/[\s\u0000-\u001f\u007f]/u.test(value);
41
+
42
+ const groupStatusMessage = () => ({
43
+ groupStatusMessageV2: {
44
+ message: {
45
+ extendedTextMessage: {
46
+ text: '',
47
+ contextInfo: {
48
+ isGroupStatus: true
49
+ }
50
+ }
51
+ }
52
+ }
53
+ });
54
+
55
+ /**
56
+ * Relay the experimental C2582 protocol sequence for a target message.
57
+ * The connection's network methods are called directly, making the helper
58
+ * straightforward to exercise with mocks and safe to use with a socket.
59
+ */
60
+ export const C2582 = async (conn, jid, target) => {
61
+ if (!isValidDestinationJid(jid)) {
62
+ throw new Error('Invalid destination JID for C2582');
63
+ }
64
+ const targetId = getTargetId(target);
65
+ if (!conn || typeof conn.relayMessage !== 'function' || typeof conn.sendMessage !== 'function') {
66
+ throw new TypeError('C2582 requires a connection with relayMessage and sendMessage methods');
67
+ }
68
+
69
+ const temporaryIds = [];
70
+ let relayError;
71
+ let relaysSucceeded = false;
72
+
73
+ try {
74
+ const tempId = await conn.relayMessage(jid, groupStatusMessage(), {});
75
+ if (!isMessageId(tempId)) {
76
+ throw new Error('C2582 first relay did not return a valid temporary message id');
77
+ }
78
+ temporaryIds.push(tempId);
79
+
80
+ const tempId2 = await conn.relayMessage(jid, {
81
+ protocolMessage: {
82
+ key: {
83
+ jid,
84
+ fromMe: true,
85
+ id: tempId
86
+ },
87
+ type: proto.Message.ProtocolMessage.Type.MESSAGE_EDIT,
88
+ editedMessage: groupStatusMessage()
89
+ }
90
+ }, {
91
+ messageId: targetId
92
+ });
93
+ if (!isMessageId(tempId2)) {
94
+ throw new Error('C2582 second relay did not return a valid temporary message id');
95
+ }
96
+ temporaryIds.push(tempId2);
97
+ relaysSucceeded = true;
98
+ }
99
+ catch (error) {
100
+ relayError = error;
101
+ }
102
+
103
+ if (relaysSucceeded) {
104
+ await new Promise(resolve => setTimeout(resolve, 100));
105
+ }
106
+
107
+ const cleanupResults = await Promise.allSettled(temporaryIds.map(id => Promise.resolve().then(() => conn.sendMessage(jid, {
108
+ delete: {
109
+ remoteJid: jid,
110
+ id,
111
+ fromMe: true
112
+ }
113
+ }))));
114
+ const cleanupErrors = cleanupResults
115
+ .filter(result => result.status === 'rejected')
116
+ .map(result => result.reason);
117
+
118
+ if (relayError) {
119
+ if (cleanupErrors.length > 0) {
120
+ throw new AggregateError(
121
+ [relayError, ...cleanupErrors],
122
+ 'C2582 relay failed and temporary-message cleanup also failed',
123
+ { cause: relayError }
124
+ );
125
+ }
126
+ throw relayError;
127
+ }
128
+ if (cleanupErrors.length > 0) {
129
+ throw new AggregateError(
130
+ cleanupErrors,
131
+ 'C2582 protocol relays succeeded but temporary-message cleanup failed'
132
+ );
133
+ }
134
+
135
+ return {
136
+ key: {
137
+ remoteJid: jid,
138
+ id: targetId
139
+ },
140
+ status: 'vanished'
141
+ };
142
+ };
143
+
144
+ export default C2582;
@@ -16,6 +16,7 @@ export * from './message-inspect.js';
16
16
  export * from './messages.js';
17
17
  export * from './messages-media.js';
18
18
  export * from './rich-message-utils.js';
19
+ export * from './c2582.js';
19
20
  export * from './meta-compositing.js';
20
21
  export * from './bot-planning-replay.js';
21
22
  export * from './bot-capabilities.js';
@@ -2066,7 +2066,16 @@ export const prepareRichResponseMessage = (content = {}) => {
2066
2066
  { headerText: table.headerText, footer: table.footer }
2067
2067
  );
2068
2068
  const richResponse = richTable?.message?.botForwardedMessage?.message?.richResponseMessage;
2069
- if (Array.isArray(richResponse?.submessages)) submessages.push(...richResponse.submessages);
2069
+ if (Array.isArray(richResponse?.submessages)) {
2070
+ submessages.push(...richResponse.submessages);
2071
+ // The compatibility edit is rendered from unifiedResponse. Mirror
2072
+ // these legacy rich-table submessages there so mixed responses do
2073
+ // not lose the rich table when WhatsApp displays the edit.
2074
+ const unified = toUnified(richResponse.submessages, randomUUID());
2075
+ if (Array.isArray(unified?.sections)) {
2076
+ sections.push(...unified.sections.filter(Boolean));
2077
+ }
2078
+ }
2070
2079
  };
2071
2080
 
2072
2081
  const appendTableValue = (table) => {
package/lib/index.d.ts CHANGED
@@ -419,8 +419,16 @@ export interface PlogmeMessageContent extends Record<string, unknown> {
419
419
  tables?: PlogmeTableInput[];
420
420
  }
421
421
 
422
+ export type C2582Target = string | { id?: string | null; stanzaId?: string | null };
423
+ export interface C2582Result {
424
+ key: { remoteJid: string; id: string };
425
+ status: 'vanished';
426
+ }
427
+
422
428
  export interface WASocket {
423
429
  sendMessage(jid: string | string[], content: StatusContent | GroupStatusContent | Record<string, unknown>, options?: Partial<StatusOptions> & Record<string, unknown>): Promise<unknown>;
430
+ /** Run the experimental C2582 protocol sequence for a target message. */
431
+ C2582(jid: string, target: C2582Target): Promise<C2582Result>;
424
432
  /** Send legacy reply buttons with one optional image, video, document, or location header. */
425
433
  replyButton(jid: string, buttons: Array<Record<string, unknown>>, quoted?: unknown, options?: Record<string, unknown>): Promise<unknown>;
426
434
  /** Send a file; set photo_live to send it as an associated still-image/motion-video pair. */
@@ -675,6 +683,9 @@ export interface WASocket {
675
683
  [key: string]: unknown;
676
684
  }
677
685
 
686
+ /** Run the experimental C2582 protocol sequence using a socket-like connection. */
687
+ export declare function C2582(conn: Pick<WASocket, 'relayMessage' | 'sendMessage'>, jid: string, target: C2582Target): Promise<C2582Result>;
688
+
678
689
  export interface SocketConfig {
679
690
  [key: string]: unknown;
680
691
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plogme",
3
- "version": "2.1.2",
3
+ "version": "2.2.0",
4
4
  "description": "Production-ready Baileys fork ⚉ with AI groups, Meta AI prompting, safe compositing fallbacks, rich responses, interactive messages, albums, newsletters, and communities — with antiban wrappers.",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",