@stone-wpp/ofc 1.0.3 → 1.0.5

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.
Files changed (90) hide show
  1. package/README.md +12 -12
  2. package/lib/Defaults/index.d.ts +1 -1
  3. package/lib/Defaults/index.js +1 -1
  4. package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
  5. package/lib/Signal/Group/sender-key-message.js +1 -1
  6. package/lib/Socket/chats.d.ts +1 -1
  7. package/lib/Socket/chats.js +1 -1
  8. package/lib/Socket/chats.js.bak +1 -1
  9. package/lib/Socket/communities.d.ts +1 -1
  10. package/lib/Socket/communities.js +1 -1
  11. package/lib/Socket/groups.d.ts +1 -1
  12. package/lib/Socket/groups.js +1 -1
  13. package/lib/Socket/index.d.ts +1 -1
  14. package/lib/Socket/index.js +3 -1
  15. package/lib/Socket/messages-recv.d.ts +1 -1
  16. package/lib/Socket/messages-recv.js +1 -1
  17. package/lib/Socket/messages-send.d.ts +1 -1
  18. package/lib/Socket/messages-send.js +1 -1
  19. package/lib/Socket/socket.js +1 -1
  20. package/lib/Socket/stone-features.d.ts +30 -0
  21. package/lib/Socket/stone-features.js +255 -0
  22. package/lib/Types/Auth.d.ts +1 -1
  23. package/lib/Types/Chat.d.ts +1 -1
  24. package/lib/Types/Events.d.ts +8 -1
  25. package/lib/Types/Events.js +1 -1
  26. package/lib/Types/Message.d.ts +1 -1
  27. package/lib/Types/Message.js +1 -1
  28. package/lib/Types/Signal.d.ts +1 -1
  29. package/lib/Types/Signal.js +1 -1
  30. package/lib/Types/Socket.d.ts +1 -1
  31. package/lib/Types/Socket.js +1 -1
  32. package/lib/Utils/browser-utils.js +1 -1
  33. package/lib/Utils/chat-utils.d.ts +1 -1
  34. package/lib/Utils/chat-utils.js +32 -1
  35. package/lib/Utils/decode-wa-message.js +1 -1
  36. package/lib/Utils/generics.d.ts +1 -1
  37. package/lib/Utils/generics.js +1 -1
  38. package/lib/Utils/history.d.ts +1 -1
  39. package/lib/Utils/history.js +1 -1
  40. package/lib/Utils/message-retry-manager.d.ts +1 -1
  41. package/lib/Utils/messages-media.d.ts +1 -1
  42. package/lib/Utils/messages-media.js +1 -1
  43. package/lib/Utils/messages.d.ts +1 -1
  44. package/lib/Utils/messages.js +9 -3
  45. package/lib/Utils/noise-handler.d.ts +1 -1
  46. package/lib/Utils/noise-handler.js +1 -1
  47. package/lib/Utils/process-message.d.ts +1 -1
  48. package/lib/Utils/process-message.js +1 -1
  49. package/lib/Utils/reporting-utils.d.ts +1 -1
  50. package/lib/Utils/reporting-utils.js +1 -1
  51. package/lib/Utils/sync-action-utils.d.ts +1 -1
  52. package/lib/Utils/sync-action-utils.js +1 -1
  53. package/lib/Utils/use-multi-file-auth-state.js +1 -1
  54. package/lib/Utils/validate-connection.d.ts +1 -1
  55. package/lib/Utils/validate-connection.js +1 -1
  56. package/lib/WABinary/generic-utils.d.ts +1 -1
  57. package/lib/WABinary/generic-utils.js +1 -1
  58. package/lib/index.d.ts +3 -4
  59. package/lib/index.js +3 -4
  60. package/package.json +7 -6
  61. package/lib/Recursos/Bots/index.js +0 -1
  62. package/lib/Recursos/Bots/mensagens.js +0 -21
  63. package/lib/Recursos/Canais/buscar.js +0 -12
  64. package/lib/Recursos/Canais/enquetes.js +0 -12
  65. package/lib/Recursos/Canais/estatisticas.js +0 -15
  66. package/lib/Recursos/Canais/index.js +0 -25
  67. package/lib/Recursos/Canais/reacoes.js +0 -13
  68. package/lib/Recursos/Chamadas/audio.js +0 -4
  69. package/lib/Recursos/Chamadas/index.js +0 -15
  70. package/lib/Recursos/Chamadas/video.js +0 -4
  71. package/lib/Recursos/Grupos/historico.js +0 -24
  72. package/lib/Recursos/Grupos/index.js +0 -7
  73. package/lib/Recursos/Grupos/permissoes.js +0 -21
  74. package/lib/Recursos/Listas/index.js +0 -1
  75. package/lib/Recursos/Listas/transmissao.js +0 -59
  76. package/lib/Recursos/index.d.ts +0 -58
  77. package/lib/Recursos/index.js +0 -8
  78. /package/{WAProto → Protocol}/GenerateStatics.sh +0 -0
  79. /package/{WAProto → Protocol}/WAProto.proto +0 -0
  80. /package/{WAProto → Protocol}/fix-imports.js +0 -0
  81. /package/{WAProto → Protocol}/index.d.ts +0 -0
  82. /package/{WAProto → Protocol}/index.js +0 -0
  83. /package/lib/{Store → DataLayer}/index.d.ts +0 -0
  84. /package/lib/{Store → DataLayer}/index.js +0 -0
  85. /package/lib/{Store → DataLayer}/json.js +0 -0
  86. /package/lib/{Store → DataLayer}/memory.js +0 -0
  87. /package/lib/{Store → DataLayer}/sqlite.js +0 -0
  88. /package/lib/{Plugins → Extensions}/index.d.ts +0 -0
  89. /package/lib/{Plugins → Extensions}/index.js +0 -0
  90. /package/lib/{Plugins → Extensions}/manager.js +0 -0
@@ -1,6 +1,6 @@
1
1
  import { Boom } from '@hapi/boom';
2
2
  import { expandAppStateKeys } from 'whatsapp-rust-bridge';
3
- import { proto } from '../../WAProto/index.js';
3
+ import { proto } from '../../Protocol/index.js';
4
4
  import { LabelAssociationType } from '../Types/LabelAssociation.js';
5
5
  import { getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidNormalizedUser } from '../WABinary/index.js';
6
6
  import { aesDecrypt, aesEncrypt, hmacSign } from './crypto.js';
@@ -576,6 +576,27 @@ export const chatModificationToAppPatch = (mod, jid) => {
576
576
  operation: OP.SET
577
577
  };
578
578
  }
579
+ else if ('noteEdit' in mod) {
580
+ const note = mod.noteEdit;
581
+ if (!note?.id || !note?.chatId) {
582
+ throw new Boom('Note id and chatId are required', { statusCode: 400 });
583
+ }
584
+ patch = {
585
+ syncAction: {
586
+ noteEditAction: {
587
+ type: 1,
588
+ chatJid: note.chatId,
589
+ createdAt: note.createdAt,
590
+ deleted: !!note.deleted,
591
+ unstructuredContent: note.content ?? ''
592
+ }
593
+ },
594
+ index: ['note_edit', note.id],
595
+ type: 'regular_low',
596
+ apiVersion: 7,
597
+ operation: OP.SET
598
+ };
599
+ }
579
600
  else if ('addLabel' in mod) {
580
601
  patch = {
581
602
  syncAction: {
@@ -768,6 +789,16 @@ export const processSyncAction = (syncAction, ev, me, initialSyncOpts, logger) =
768
789
  ev.emit('chats.delete', [id]);
769
790
  }
770
791
  }
792
+ else if (action?.noteEditAction) {
793
+ const note = action.noteEditAction;
794
+ ev.emit('notes.edit', {
795
+ id: syncAction.index?.[1],
796
+ chatId: note.chatJid,
797
+ content: note.unstructuredContent,
798
+ createdAt: note.createdAt ? toNumber(note.createdAt) : undefined,
799
+ deleted: !!note.deleted
800
+ });
801
+ }
771
802
  else if (action?.labelEditAction) {
772
803
  const { name, color, deleted, predefinedId } = action.labelEditAction;
773
804
  ev.emit('labels.edit', {
@@ -1,5 +1,5 @@
1
1
  import { Boom } from '@hapi/boom';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import { areJidsSameUser, isHostedLidUser, isHostedPnUser, isJidBroadcast, isJidGroup, isJidMetaAI, isJidNewsletter, isJidStatusBroadcast, isLidUser, isPnUser
4
4
  // transferDevice
5
5
  } from '../WABinary/index.js';
@@ -1,5 +1,5 @@
1
1
  import type Long from 'long';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import type { StoneWPPEventEmitter, StoneWPPEventMap, ConnectionState, WACallUpdateType, WAMessageKey, WAVersion } from '../Types/index.js';
4
4
  import { type BinaryNode } from '../WABinary/index.js';
5
5
  export declare const BufferJSON: {
@@ -1,6 +1,6 @@
1
1
  import { Boom } from '@hapi/boom';
2
2
  import { createHash, randomBytes } from 'crypto';
3
- import { proto } from '../../WAProto/index.js';
3
+ import { proto } from '../../Protocol/index.js';
4
4
  const stoneWppVersion = [2, 3000, 1043857760];
5
5
  import { DisconnectReason } from '../Types/index.js';
6
6
  import { getAllBinaryNodeChildren, jidDecode } from '../WABinary/index.js';
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import type { Chat, Contact, LIDMapping, WAMessage } from '../Types/index.js';
3
3
  import type { ILogger } from './logger.js';
4
4
  export declare const downloadHistory: (msg: proto.Message.IHistorySyncNotification, options: RequestInit) => Promise<proto.HistorySync>;
@@ -1,7 +1,7 @@
1
1
  import { pipeline } from 'stream/promises';
2
2
  import { promisify } from 'util';
3
3
  import { createInflate, inflate } from 'zlib';
4
- import { proto } from '../../WAProto/index.js';
4
+ import { proto } from '../../Protocol/index.js';
5
5
  import { WAMessageStubType } from '../Types/index.js';
6
6
  import { isHostedLidUser, isHostedPnUser, isLidUser, isPnUser } from '../WABinary/index.js';
7
7
  import { toNumber } from './generics.js';
@@ -1,4 +1,4 @@
1
- import type { proto } from '../../WAProto/index.js';
1
+ import type { proto } from '../../Protocol/index.js';
2
2
  import type { ILogger } from './logger.js';
3
3
  export interface RecentMessageKey {
4
4
  to: string;
@@ -2,7 +2,7 @@ import { Boom } from '@hapi/boom';
2
2
  import type { Agent } from 'https';
3
3
  import { Readable, Transform } from 'stream';
4
4
  import { URL } from 'url';
5
- import { proto } from '../../WAProto/index.js';
5
+ import { proto } from '../../Protocol/index.js';
6
6
  import { type MediaType } from '../Defaults/index.js';
7
7
  import type { DownloadableMessage, MediaConnInfo, MediaDecryptionKeyInfo, SocketConfig, WAMediaUpload, WAMediaUploadFunction, WAMessageContent, WAMessageKey } from '../Types/index.js';
8
8
  import { type BinaryNode } from '../WABinary/index.js';
@@ -7,7 +7,7 @@ import { tmpdir } from 'os';
7
7
  import { join } from 'path';
8
8
  import { Readable, Transform } from 'stream';
9
9
  import { URL } from 'url';
10
- import { proto } from '../../WAProto/index.js';
10
+ import { proto } from '../../Protocol/index.js';
11
11
  import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP } from '../Defaults/index.js';
12
12
  import { getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary/index.js';
13
13
  import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto.js';
@@ -1,5 +1,5 @@
1
1
  import { type Transform } from 'stream';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import type { AnyMediaMessageContent, AnyMessageContent, ButtonsMessageInput, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, MessageUserReceipt, MiscMessageGenerationOptions, WAMessage, WAMessageContent, WAMessageKey } from '../Types/index.js';
4
4
  import type { ILogger } from './logger.js';
5
5
  import { type MediaDownloadOptions } from './messages-media.js';
@@ -2,7 +2,7 @@ import { Boom } from '@hapi/boom';
2
2
  import { randomBytes } from 'crypto';
3
3
  import { promises as fs } from 'fs';
4
4
  import {} from 'stream';
5
- import { proto } from '../../WAProto/index.js';
5
+ import { proto } from '../../Protocol/index.js';
6
6
  import { CALL_AUDIO_PREFIX, CALL_VIDEO_PREFIX, MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
7
7
  import { WAMessageStatus, WAProto } from '../Types/index.js';
8
8
  import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
@@ -425,10 +425,16 @@ const createInteractiveContent = async (message, options) => {
425
425
  : undefined,
426
426
  nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({
427
427
  buttons,
428
- messageParamsJson: source.messageParamsJson || '{}'
428
+ messageParamsJson: source.messageParamsJson || '{}',
429
+ ...(source.messageVersion == null ? {} : { messageVersion: source.messageVersion })
429
430
  })
430
431
  });
431
- return { interactiveMessage };
432
+ // Native payment flows carry a message secret, as expected by the WhatsApp client.
433
+ const isPaymentInfo = buttons.some(button => button.name === 'payment_info');
434
+ return {
435
+ interactiveMessage,
436
+ ...(isPaymentInfo ? { messageContextInfo: { messageSecret: randomBytes(32) } } : {})
437
+ };
432
438
  };
433
439
  export const generateWAMessageContent = async (message, options) => {
434
440
  var _a, _b;
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import type { KeyPair } from '../Types/index.js';
3
3
  import type { BinaryNode } from '../WABinary/index.js';
4
4
  import type { ILogger } from './logger.js';
@@ -1,5 +1,5 @@
1
1
  import { Boom } from '@hapi/boom';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import { NOISE_MODE, WA_CERT_DETAILS } from '../Defaults/index.js';
4
4
  import { decodeBinaryNode } from '../WABinary/index.js';
5
5
  import { aesDecryptGCM, aesEncryptGCM, Curve, hkdf, sha256 } from './crypto.js';
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import type { AuthenticationCreds, StoneWPPEventEmitter, CacheStore, SignalKeyStoreWithTransaction, SignalRepositoryWithLIDStore, SocketConfig, WAMessage, WAMessageKey } from '../Types/index.js';
3
3
  import type { ILogger } from './logger.js';
4
4
  type ProcessMessageContext = {
@@ -1,5 +1,5 @@
1
1
  import { Boom } from '@hapi/boom';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import { WAMessageStubType } from '../Types/index.js';
4
4
  import { getContentType, normalizeMessageContent } from '../Utils/messages.js';
5
5
  import { areJidsSameUser, isHostedLidUser, isHostedPnUser, isJidBroadcast, isJidStatusBroadcast, isLidUser, jidDecode, jidEncode, jidNormalizedUser } from '../WABinary/index.js';
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import type { WAMessageContent, WAMessageKey } from '../Types/index.js';
3
3
  import type { BinaryNode } from '../WABinary/index.js';
4
4
  export type ReportingField = {
@@ -1,5 +1,5 @@
1
1
  import { createHmac } from 'crypto';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import { hkdf } from './crypto.js';
4
4
  const reportingFields = [
5
5
  { f: 1 },
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import type { StoneWPPEventEmitter, StoneWPPEventMap, Contact } from '../Types/index.js';
3
3
  import type { ILogger } from './logger.js';
4
4
  export type ContactsUpsertResult = {
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import { isLidUser, isPnUser } from '../WABinary/index.js';
3
3
  /**
4
4
  * Process contactAction and return events to emit.
@@ -1,7 +1,7 @@
1
1
  import { Mutex } from 'async-mutex';
2
2
  import { mkdir, readFile, stat, unlink, writeFile } from 'fs/promises';
3
3
  import { join } from 'path';
4
- import { proto } from '../../WAProto/index.js';
4
+ import { proto } from '../../Protocol/index.js';
5
5
  import { initAuthCreds } from './auth-utils.js';
6
6
  import { BufferJSON } from './generics.js';
7
7
  // We need to lock files due to the fact that we are using async functions to read and write files
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import type { AuthenticationCreds, SignalCreds, SocketConfig } from '../Types/index.js';
3
3
  import { type BinaryNode } from '../WABinary/index.js';
4
4
  export declare const generateLoginNode: (userJid: string, config: SocketConfig) => proto.IClientPayload;
@@ -1,6 +1,6 @@
1
1
  import { Boom } from '@hapi/boom';
2
2
  import { createHash } from 'crypto';
3
- import { proto } from '../../WAProto/index.js';
3
+ import { proto } from '../../Protocol/index.js';
4
4
  import { KEY_BUNDLE_TYPE, WA_ADV_ACCOUNT_SIG_PREFIX, WA_ADV_DEVICE_SIG_PREFIX, WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX } from '../Defaults/index.js';
5
5
  import { getBinaryNodeChild, jidDecode, S_WHATSAPP_NET } from '../WABinary/index.js';
6
6
  import { Curve, hmacSign } from './crypto.js';
@@ -1,4 +1,4 @@
1
- import { proto } from '../../WAProto/index.js';
1
+ import { proto } from '../../Protocol/index.js';
2
2
  import { type BinaryNode } from './types.js';
3
3
  export declare const getBinaryNodeChildren: (node: BinaryNode | undefined, childTag: string) => BinaryNode[];
4
4
  export declare const getBinaryNodeChild: (node: BinaryNode | undefined, childTag: string) => BinaryNode | undefined;
@@ -1,5 +1,5 @@
1
1
  import { Boom } from '@hapi/boom';
2
- import { proto } from '../../WAProto/index.js';
2
+ import { proto } from '../../Protocol/index.js';
3
3
  import {} from './types.js';
4
4
  // some extra useful utilities
5
5
  const indexCache = new WeakMap();
package/lib/index.d.ts CHANGED
@@ -1,14 +1,13 @@
1
1
  import makeWASocket from './Socket/index.js';
2
- export * from '../WAProto/index.js';
2
+ export * from '../Protocol/index.js';
3
3
  export * from './Utils/index.js';
4
4
  export * from './Types/index.js';
5
5
  export * from './Defaults/index.js';
6
6
  export * from './WABinary/index.js';
7
7
  export * from './WAM/index.js';
8
8
  export * from './WAUSync/index.js';
9
- export * from './Recursos/index.js';
10
- export * from './Store/index.js';
11
- export * from './Plugins/index.js';
9
+ export * from './DataLayer/index.js';
10
+ export * from './Extensions/index.js';
12
11
  export type WASocket = ReturnType<typeof makeWASocket>;
13
12
  export { makeWASocket };
14
13
  export default makeWASocket;
package/lib/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import makeWASocket from './Socket/index.js';
2
- export * from '../WAProto/index.js';
2
+ export * from '../Protocol/index.js';
3
3
  export * from './Utils/index.js';
4
4
  export * from './Types/index.js';
5
5
  export * from './Defaults/index.js';
6
6
  export * from './WABinary/index.js';
7
7
  export * from './WAM/index.js';
8
8
  export * from './WAUSync/index.js';
9
- export * from './Recursos/index.js';
10
- export * from './Store/index.js';
11
- export * from './Plugins/index.js';
9
+ export * from './DataLayer/index.js';
10
+ export * from './Extensions/index.js';
12
11
  export { makeWASocket };
13
12
  export default makeWASocket;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@stone-wpp/ofc",
3
3
  "type": "module",
4
- "version": "1.0.3",
5
- "description": "Stone WPP — biblioteca modular para WhatsApp em Node.js: conexão, mensagens, grupos, canais, stores e plugins",
4
+ "version": "1.0.5",
5
+ "description": "Stone WPP — biblioteca modular para WhatsApp em Node.js: conexão, mensagens, grupos, canais, armazenamento e extensões",
6
6
  "keywords": [
7
7
  "stone-wpp",
8
8
  "whatsapp",
@@ -12,17 +12,18 @@
12
12
  "messages",
13
13
  "groups",
14
14
  "channels",
15
- "plugins",
16
- "automation"
15
+ "extensions",
16
+ "automation",
17
+ "storage"
17
18
  ],
18
- "homepage": "https://stone-wpp.vercel.app/",
19
+ "homepage": "https://stone-wpp.squareweb.app/",
19
20
  "license": "MIT",
20
21
  "author": "Dylan Modz",
21
22
  "main": "lib/index.js",
22
23
  "types": "lib/index.d.ts",
23
24
  "files": [
24
25
  "lib/**/*",
25
- "WAProto/**/*",
26
+ "Protocol/**/*",
26
27
  "engine-requirements.js",
27
28
  "README.md",
28
29
  "LICENSE"
@@ -1 +0,0 @@
1
- export { criarRecursosBots } from './mensagens.js';
@@ -1,21 +0,0 @@
1
- export function criarRecursosBots(socket) {
2
- return {
3
- listar: () => {
4
- if (typeof socket.getBotListV2 !== 'function') throw new Error('Busca de bots indisponível');
5
- return socket.getBotListV2();
6
- },
7
- enviar: (jid, mensagem, opcoes = {}) => socket.sendMessage(jid,
8
- typeof mensagem === 'string' ? { text: mensagem } : mensagem, opcoes),
9
- escutar: (jid, callback) => {
10
- if (typeof callback !== 'function') throw new TypeError('Callback obrigatório');
11
- if (!socket.ev?.on || !socket.ev?.off) throw new Error('Eventos indisponíveis');
12
- const listener = event => {
13
- for (const msg of event?.messages ?? []) {
14
- if (msg?.key?.remoteJid === jid) callback(msg);
15
- }
16
- };
17
- socket.ev.on('messages.upsert', listener);
18
- return () => socket.ev.off('messages.upsert', listener);
19
- }
20
- };
21
- }
@@ -1,12 +0,0 @@
1
- const norm = text => String(text ?? '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
2
-
3
- export function pesquisarCanais(canais, termo, { limite = 20 } = {}) {
4
- if (!Array.isArray(canais)) throw new TypeError('canais deve ser uma lista');
5
- if (!Number.isInteger(limite) || limite < 1 || limite > 100) throw new RangeError('limite deve ser de 1 a 100');
6
- const query = norm(termo).trim();
7
- return canais.filter(canal => {
8
- if (!canal || typeof canal !== 'object') return false;
9
- return !query || [canal.name, canal.title, canal.description, canal.id]
10
- .some(value => norm(value).includes(query));
11
- }).slice(0, limite);
12
- }
@@ -1,12 +0,0 @@
1
- export function resumirEnquete(enquete) {
2
- if (!enquete || typeof enquete !== 'object') throw new TypeError('Enquete inválida');
3
- const opcoes = enquete.options ?? enquete.opcoes ?? [];
4
- if (!Array.isArray(opcoes)) throw new TypeError('Opções inválidas');
5
- const total = opcoes.reduce((soma, opcao) => soma + Math.max(0, Number(opcao.votes ?? opcao.votos ?? 0) || 0), 0);
6
- return { titulo: enquete.name ?? enquete.title ?? enquete.titulo ?? '',
7
- totalVotos: total,
8
- opcoes: opcoes.map(opcao => ({
9
- nome: opcao.optionName ?? opcao.name ?? opcao.nome ?? '',
10
- votos: Math.max(0, Number(opcao.votes ?? opcao.votos ?? 0) || 0)
11
- })) };
12
- }
@@ -1,15 +0,0 @@
1
- export function calcularEstatisticas(mensagens = []) {
2
- if (!Array.isArray(mensagens)) throw new TypeError('Informe uma lista de mensagens');
3
- let visualizacoes = 0, reacoes = 0, enquetes = 0;
4
- for (const m of mensagens) {
5
- if (!m || typeof m !== 'object') continue;
6
- const views = Number(m.views ?? m.viewCount ?? m.view_count ?? 0);
7
- if (Number.isFinite(views) && views > 0) visualizacoes += views;
8
- const count = Number(m.reactionCount ?? m.reactions_count ?? 0);
9
- if (Number.isFinite(count) && count > 0) reacoes += count;
10
- else if (Array.isArray(m.reactions)) reacoes += m.reactions.length;
11
- if (m.poll || m.pollCreationMessage) enquetes++;
12
- }
13
- return { mensagens: mensagens.length, visualizacoes, reacoes, enquetes,
14
- taxaDeReacao: visualizacoes ? reacoes / visualizacoes : 0 };
15
- }
@@ -1,25 +0,0 @@
1
- import { pesquisarCanais } from './buscar.js';
2
- import { calcularEstatisticas } from './estatisticas.js';
3
- import { resumirReacoes } from './reacoes.js';
4
- import { resumirEnquete } from './enquetes.js';
5
-
6
- export { pesquisarCanais, calcularEstatisticas, resumirReacoes, resumirEnquete };
7
-
8
- export function criarRecursosCanais(socket) {
9
- const metodo = nome => {
10
- if (typeof socket[nome] !== 'function') throw new Error('Método Stone indisponível: ' + nome);
11
- return socket[nome].bind(socket);
12
- };
13
- return {
14
- informacoes: (chave, tipo = 'jid') => metodo('newsletterMetadata')(tipo, chave),
15
- mensagens: (jid, quantidade = 20, desde, depois) => metodo('newsletterFetchMessages')(jid, quantidade, desde, depois),
16
- seguidores: jid => metodo('newsletterSubscribers')(jid),
17
- reagir: (jid, id, emoji) => metodo('newsletterReactMessage')(jid, id, emoji),
18
- seguir: jid => metodo('newsletterFollow')(jid),
19
- deixar: jid => metodo('newsletterUnfollow')(jid),
20
- buscarLocal: pesquisarCanais,
21
- estatisticasLocais: calcularEstatisticas,
22
- resumirReacoes,
23
- resumirEnquete
24
- };
25
- }
@@ -1,13 +0,0 @@
1
- export function resumirReacoes(reacoes = []) {
2
- if (!Array.isArray(reacoes)) throw new TypeError('Informe uma lista de reações');
3
- const contagem = {};
4
- for (const item of reacoes) {
5
- const emoji = typeof item === 'string' ? item : item?.emoji ?? item?.code ?? item?.reaction;
6
- if (!emoji) continue;
7
- const quantidade = Number(typeof item === 'string' ? 1 : item.count ?? 1);
8
- if (Number.isFinite(quantidade) && quantidade > 0) {
9
- contagem[emoji] = (contagem[emoji] || 0) + quantidade;
10
- }
11
- }
12
- return contagem;
13
- }
@@ -1,4 +0,0 @@
1
- export async function criarLinkAudio(socket, evento, timeoutMs) {
2
- if (typeof socket.createCallLink !== 'function') throw new Error('Links de chamada indisponíveis');
3
- return socket.createCallLink('audio', evento, timeoutMs);
4
- }
@@ -1,15 +0,0 @@
1
- import { criarLinkAudio } from './audio.js';
2
- import { criarLinkVideo } from './video.js';
3
- export { criarLinkAudio, criarLinkVideo };
4
-
5
- export function criarRecursosChamadas(socket) {
6
- return {
7
- linkAudio: (evento, timeoutMs) => criarLinkAudio(socket, evento, timeoutMs),
8
- linkVideo: (evento, timeoutMs) => criarLinkVideo(socket, evento, timeoutMs),
9
- rejeitar: (id, remetente) => {
10
- if (!id || !remetente) throw new TypeError('ID e remetente da chamada são obrigatórios');
11
- if (typeof socket.rejectCall !== 'function') throw new Error('Rejeição de chamada indisponível');
12
- return socket.rejectCall(id, remetente);
13
- }
14
- };
15
- }
@@ -1,4 +0,0 @@
1
- export async function criarLinkVideo(socket, evento, timeoutMs) {
2
- if (typeof socket.createCallLink !== 'function') throw new Error('Links de chamada indisponíveis');
3
- return socket.createCallLink('video', evento, timeoutMs);
4
- }
@@ -1,24 +0,0 @@
1
- export function criarHistoricoGrupos(store) {
2
- if (!store || typeof store.get !== 'function' || typeof store.set !== 'function') {
3
- throw new TypeError('Stone Store inválido');
4
- }
5
- const chave = jid => {
6
- if (typeof jid !== 'string' || !jid.endsWith('@g.us')) throw new TypeError('JID de grupo inválido');
7
- return 'historico:' + jid;
8
- };
9
- return {
10
- async salvar(jid, mensagem, limite = 100) {
11
- if (!Number.isInteger(limite) || limite < 1 || limite > 1000) throw new RangeError('limite inválido');
12
- const id = chave(jid);
13
- const anteriores = await store.get(id) ?? [];
14
- const proximo = [...anteriores, mensagem].slice(-limite);
15
- await store.set(id, proximo);
16
- return proximo.length;
17
- },
18
- async listar(jid, limite = 50) {
19
- if (!Number.isInteger(limite) || limite < 1 || limite > 1000) throw new RangeError('limite inválido');
20
- return (await store.get(chave(jid)) ?? []).slice(-limite);
21
- },
22
- apagar: jid => store.delete(chave(jid))
23
- };
24
- }
@@ -1,7 +0,0 @@
1
- import { criarHistoricoGrupos } from './historico.js';
2
- import { criarPermissoesGrupos } from './permissoes.js';
3
-
4
- export { criarHistoricoGrupos, criarPermissoesGrupos };
5
- export function criarRecursosGrupos(socket, store) {
6
- return { permissoes: criarPermissoesGrupos(socket), historico: criarHistoricoGrupos(store) };
7
- }
@@ -1,21 +0,0 @@
1
- export function criarPermissoesGrupos(socket) {
2
- const executar = (nome, ...args) => {
3
- if (typeof socket[nome] !== 'function') throw new Error('Método Stone indisponível: ' + nome);
4
- return socket[nome](...args);
5
- };
6
- return {
7
- somenteAdminsEnviam: (jid, ativar = true) =>
8
- executar('groupSettingUpdate', jid, ativar ? 'announcement' : 'not_announcement'),
9
- somenteAdminsEditam: (jid, ativar = true) =>
10
- executar('groupSettingUpdate', jid, ativar ? 'locked' : 'unlocked'),
11
- aprovarEntrada: (jid, ativar = true) =>
12
- executar('groupJoinApprovalMode', jid, ativar ? 'on' : 'off'),
13
- permitirAdicaoPorMembros: (jid, ativar = true) =>
14
- executar('groupMemberAddMode', jid, ativar ? 'all_member_add' : 'admin_add'),
15
- solicitacoes: jid => executar('groupRequestParticipantsList', jid),
16
- decidirSolicitacoes: (jid, jids, acao) => {
17
- if (!['approve', 'reject'].includes(acao)) throw new RangeError('Use approve ou reject');
18
- return executar('groupRequestParticipantsUpdate', jid, jids, acao);
19
- }
20
- };
21
- }
@@ -1 +0,0 @@
1
- export { criarListasTransmissao } from './transmissao.js';
@@ -1,59 +0,0 @@
1
- export function criarListasTransmissao(socket, { maxDestinatarios = 100 } = {}) {
2
- const listas = new Map();
3
- const validar = pessoa => {
4
- if (!pessoa || typeof pessoa.jid !== 'string' || pessoa.consentimento !== true) {
5
- throw new TypeError('Cada destinatário precisa de jid e consentimento: true');
6
- }
7
- if (!/^[0-9]+@(s\.whatsapp\.net|lid)$/.test(pessoa.jid)) {
8
- throw new TypeError('JID de destinatário inválido');
9
- }
10
- return pessoa.jid;
11
- };
12
- return {
13
- criar(nome, pessoas = []) {
14
- if (typeof nome !== 'string' || !nome.trim()) throw new TypeError('Nome obrigatório');
15
- if (listas.has(nome)) throw new Error('Lista Stone já existe: ' + nome);
16
- const destinatarios = [...new Set(pessoas.map(validar))];
17
- if (destinatarios.length > maxDestinatarios) throw new RangeError('Limite de destinatários excedido');
18
- listas.set(nome, destinatarios);
19
- return destinatarios.length;
20
- },
21
- adicionar(nome, pessoa) {
22
- if (!listas.has(nome)) throw new Error('Lista Stone inexistente: ' + nome);
23
- const jid = validar(pessoa), participantes = listas.get(nome);
24
- if (!participantes.includes(jid)) {
25
- if (participantes.length >= maxDestinatarios) throw new RangeError('Limite de destinatários excedido');
26
- participantes.push(jid);
27
- }
28
- return participantes.length;
29
- },
30
- remover(nome, jid) {
31
- if (!listas.has(nome)) return false;
32
- const antigos = listas.get(nome);
33
- listas.set(nome, antigos.filter(item => item !== jid));
34
- return antigos.length !== listas.get(nome).length;
35
- },
36
- listar() { return [...listas].map(([nome, destinatarios]) => ({ nome, quantidade: destinatarios.length })); },
37
- destinatarios(nome) { return [...(listas.get(nome) ?? [])]; },
38
- apagar(nome) { return listas.delete(nome); },
39
- async enviar(nome, conteudo, { pausaMs = 500, enviarPara = undefined } = {}) {
40
- if (!listas.has(nome)) throw new Error('Lista Stone inexistente: ' + nome);
41
- if (!Number.isInteger(pausaMs) || pausaMs < 0 || pausaMs > 60000) throw new RangeError('pausaMs inválida');
42
- const destinatarios = [...listas.get(nome)];
43
- const resultados = [];
44
- for (const [index, jid] of destinatarios.entries()) {
45
- try {
46
- const resultado = await (enviarPara ?? socket.sendMessage.bind(socket))(jid,
47
- typeof conteudo === 'string' ? { text: conteudo } : conteudo);
48
- resultados.push({ jid, enviado: true, id: resultado?.key?.id });
49
- } catch (error) {
50
- resultados.push({ jid, enviado: false, erro: String(error?.message ?? error) });
51
- }
52
- if (index + 1 < destinatarios.length && pausaMs) {
53
- await new Promise(resolve => setTimeout(resolve, pausaMs));
54
- }
55
- }
56
- return resultados;
57
- }
58
- };
59
- }