zapo-js 1.4.0 → 1.5.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.
Files changed (94) hide show
  1. package/dist/appstate/types.d.ts +1 -2
  2. package/dist/auth/WaAuthClient.d.ts +10 -0
  3. package/dist/auth/WaAuthClient.js +17 -8
  4. package/dist/auth/credentials-flow.d.ts +8 -0
  5. package/dist/auth/credentials-flow.js +35 -2
  6. package/dist/auth/pairing/companion-host.d.ts +105 -0
  7. package/dist/auth/pairing/companion-host.js +148 -0
  8. package/dist/auth/types.d.ts +20 -9
  9. package/dist/client/WaClient.d.ts +15 -5
  10. package/dist/client/WaClient.js +46 -12
  11. package/dist/client/WaClientFactory.d.ts +3 -0
  12. package/dist/client/WaClientFactory.js +24 -6
  13. package/dist/client/coordinators/WaAppStateMutationCoordinator.d.ts +8 -0
  14. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +37 -1
  15. package/dist/client/coordinators/WaGroupCoordinator.js +6 -1
  16. package/dist/client/coordinators/WaMessageDispatchCoordinator.d.ts +3 -1
  17. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +13 -3
  18. package/dist/client/coordinators/WaMobileCoordinator.d.ts +192 -0
  19. package/dist/client/coordinators/WaMobileCoordinator.js +645 -0
  20. package/dist/client/messaging/companion-host.d.ts +43 -0
  21. package/dist/client/messaging/companion-host.js +61 -0
  22. package/dist/client/messaging/key-protocol.js +25 -1
  23. package/dist/client/persistence/companion-host.d.ts +36 -0
  24. package/dist/client/persistence/companion-host.js +57 -0
  25. package/dist/client/plugins/install.d.ts +2 -1
  26. package/dist/client/plugins/install.js +44 -11
  27. package/dist/client/types.d.ts +71 -7
  28. package/dist/esm/auth/WaAuthClient.js +18 -9
  29. package/dist/esm/auth/credentials-flow.js +36 -3
  30. package/dist/esm/auth/pairing/companion-host.js +140 -0
  31. package/dist/esm/client/WaClient.js +46 -12
  32. package/dist/esm/client/WaClientFactory.js +25 -7
  33. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +37 -1
  34. package/dist/esm/client/coordinators/WaGroupCoordinator.js +6 -1
  35. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +14 -4
  36. package/dist/esm/client/coordinators/WaMobileCoordinator.js +641 -0
  37. package/dist/esm/client/messaging/companion-host.js +56 -0
  38. package/dist/esm/client/messaging/key-protocol.js +25 -1
  39. package/dist/esm/client/persistence/companion-host.js +54 -0
  40. package/dist/esm/client/plugins/install.js +44 -11
  41. package/dist/esm/index.js +5 -2
  42. package/dist/esm/message/WaMessageClient.js +3 -2
  43. package/dist/esm/message/context-info.js +4 -0
  44. package/dist/esm/protocol/constants.js +4 -3
  45. package/dist/esm/protocol/device-identity.js +18 -0
  46. package/dist/esm/protocol/group.js +6 -0
  47. package/dist/esm/protocol/message.js +12 -0
  48. package/dist/esm/protocol/nodes.js +15 -1
  49. package/dist/esm/retry/replay.js +3 -3
  50. package/dist/esm/signal/attestation/WaAdvSignature.js +67 -2
  51. package/dist/esm/signal/attestation/constants.js +2 -0
  52. package/dist/esm/signal/index.js +1 -0
  53. package/dist/esm/transport/index.js +1 -1
  54. package/dist/esm/transport/node/builders/group.js +4 -3
  55. package/dist/esm/transport/node/builders/mobile.js +113 -0
  56. package/dist/esm/transport/noise/WaClientPayload.js +16 -7
  57. package/dist/esm/transport/wa-version-fetcher.js +152 -0
  58. package/dist/esm/util/index.js +1 -0
  59. package/dist/index.d.ts +10 -4
  60. package/dist/index.js +13 -4
  61. package/dist/message/WaMessageClient.js +2 -1
  62. package/dist/message/context-info.d.ts +2 -0
  63. package/dist/message/context-info.js +5 -0
  64. package/dist/protocol/constants.d.ts +6 -4
  65. package/dist/protocol/constants.js +8 -2
  66. package/dist/protocol/device-identity.d.ts +25 -0
  67. package/dist/protocol/device-identity.js +21 -0
  68. package/dist/protocol/group.d.ts +6 -0
  69. package/dist/protocol/group.js +7 -1
  70. package/dist/protocol/message.d.ts +14 -0
  71. package/dist/protocol/message.js +13 -1
  72. package/dist/protocol/nodes.d.ts +14 -0
  73. package/dist/protocol/nodes.js +15 -1
  74. package/dist/retry/replay.js +2 -2
  75. package/dist/signal/attestation/WaAdvSignature.d.ts +50 -1
  76. package/dist/signal/attestation/WaAdvSignature.js +71 -1
  77. package/dist/signal/attestation/constants.d.ts +2 -0
  78. package/dist/signal/attestation/constants.js +3 -1
  79. package/dist/signal/index.d.ts +1 -0
  80. package/dist/signal/index.js +13 -1
  81. package/dist/transport/index.d.ts +2 -2
  82. package/dist/transport/index.js +4 -3
  83. package/dist/transport/node/builders/group.js +4 -3
  84. package/dist/transport/node/builders/mobile.d.ts +68 -0
  85. package/dist/transport/node/builders/mobile.js +120 -0
  86. package/dist/transport/noise/WaClientPayload.js +16 -7
  87. package/dist/transport/wa-version-fetcher.d.ts +92 -0
  88. package/dist/transport/wa-version-fetcher.js +156 -0
  89. package/dist/util/index.d.ts +1 -0
  90. package/dist/util/index.js +3 -1
  91. package/package.json +1 -1
  92. package/dist/esm/transport/wa-web-version-fetcher.js +0 -91
  93. package/dist/transport/wa-web-version-fetcher.d.ts +0 -44
  94. package/dist/transport/wa-web-version-fetcher.js +0 -94
@@ -0,0 +1,113 @@
1
+ import { proto } from '../../../proto.js';
2
+ import { WA_DEFAULTS } from '../../../protocol/defaults.js';
3
+ import { WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../../protocol/nodes.js';
4
+ import { buildIqNode } from '../../node/query.js';
5
+ /**
6
+ * Builds the primary's `<iq type="set" xmlns="md">` carrying `<pair-device>`
7
+ * with `ref`, `pub-key`, `device-identity`, `key-index-list`, and optional
8
+ * `client-props`/`pem` children. The `id` is assigned by the send path.
9
+ */
10
+ export function buildPairDeviceIq(input) {
11
+ const children = [
12
+ { tag: WA_NODE_TAGS.REF, attrs: {}, content: input.ref },
13
+ { tag: WA_NODE_TAGS.PUB_KEY, attrs: {}, content: input.companionNoisePublicKey },
14
+ { tag: WA_NODE_TAGS.DEVICE_IDENTITY, attrs: {}, content: input.deviceIdentityBytes },
15
+ {
16
+ tag: WA_NODE_TAGS.KEY_INDEX_LIST,
17
+ attrs: { ts: String(input.keyIndexListTimestampSeconds) },
18
+ content: input.keyIndexListBytes
19
+ }
20
+ ];
21
+ if (input.clientProps) {
22
+ children.push({
23
+ tag: WA_NODE_TAGS.CLIENT_PROPS,
24
+ attrs: {},
25
+ content: proto.ClientPairingProps.encode({
26
+ isChatDbLidMigrated: input.clientProps.isChatDbLidMigrated,
27
+ isSyncdPureLidSession: input.clientProps.isSyncdPureLidSession,
28
+ isSyncdSnapshotRecoveryEnabled: input.clientProps.isSyncdSnapshotRecoveryEnabled
29
+ }).finish()
30
+ });
31
+ }
32
+ if (input.pem) {
33
+ children.push({
34
+ tag: WA_NODE_TAGS.PEM,
35
+ attrs: { version: '1', algorithm: 'rsa2048' },
36
+ content: [
37
+ { tag: WA_NODE_TAGS.PEM, attrs: {}, content: input.pem.aesGcmKeyBytes },
38
+ { tag: WA_NODE_TAGS.TTL, attrs: { ts_s: String(input.pem.ttlSeconds) } },
39
+ { tag: WA_NODE_TAGS.KEY_ID, attrs: {}, content: '1' }
40
+ ]
41
+ });
42
+ }
43
+ return buildIqNode(WA_IQ_TYPES.SET, WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.MD, [
44
+ { tag: WA_NODE_TAGS.PAIR_DEVICE, attrs: {}, content: children }
45
+ ]);
46
+ }
47
+ /**
48
+ * Builds the standalone key-index-list publish `<iq>` the primary sends when its
49
+ * companion set changes.
50
+ */
51
+ export function buildKeyIndexListPublishIq(input) {
52
+ return buildIqNode(WA_IQ_TYPES.SET, WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.MD, [
53
+ {
54
+ tag: WA_NODE_TAGS.KEY_INDEX_LIST,
55
+ attrs: { ts: String(input.timestampSeconds) },
56
+ content: input.keyIndexListBytes
57
+ }
58
+ ]);
59
+ }
60
+ /**
61
+ * Builds the `remove-companion-device` IQ that unlinks a companion from the
62
+ * account. The device is identified by its full device jid; `reason` is a
63
+ * free-form label the server records.
64
+ */
65
+ export function buildRemoveCompanionDeviceIq(input) {
66
+ return buildIqNode(WA_IQ_TYPES.SET, WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.MD, [
67
+ {
68
+ tag: WA_NODE_TAGS.REMOVE_COMPANION_DEVICE,
69
+ attrs: { jid: input.deviceJid, reason: input.reason }
70
+ }
71
+ ]);
72
+ }
73
+ /**
74
+ * Builds the `remove-companion-device` IQ that unlinks EVERY companion in one
75
+ * stanza: `all="true"` (no `jid`), mirroring the phone's "log out all companion
76
+ * devices". `excludeHostedCompanion` adds `exclude_hosted_companion="true"` to
77
+ * spare companions this account itself hosts.
78
+ */
79
+ export function buildRemoveAllCompanionDevicesIq(input) {
80
+ const attrs = { all: 'true', reason: input.reason };
81
+ if (input.excludeHostedCompanion) {
82
+ attrs.exclude_hosted_companion = 'true';
83
+ }
84
+ return buildIqNode(WA_IQ_TYPES.SET, WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.MD, [
85
+ { tag: WA_NODE_TAGS.REMOVE_COMPANION_DEVICE, attrs }
86
+ ]);
87
+ }
88
+ /**
89
+ * Builds the `primary_hello` IQ the primary sends to drive a link-code (pairing
90
+ * code) handshake: the code-wrapped primary ephemeral, the primary ADV identity
91
+ * public key, and the companion's pairing ref.
92
+ */
93
+ export function buildPrimaryHelloIq(input) {
94
+ return buildIqNode(WA_IQ_TYPES.SET, WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.MD, [
95
+ {
96
+ tag: WA_NODE_TAGS.LINK_CODE_COMPANION_REG,
97
+ attrs: { stage: 'primary_hello' },
98
+ content: [
99
+ {
100
+ tag: WA_NODE_TAGS.LINK_CODE_PAIRING_WRAPPED_PRIMARY_EPHEMERAL_PUB,
101
+ attrs: {},
102
+ content: input.wrappedPrimaryEphemeralPub
103
+ },
104
+ {
105
+ tag: WA_NODE_TAGS.PRIMARY_IDENTITY_PUB,
106
+ attrs: {},
107
+ content: input.primaryIdentityPub
108
+ },
109
+ { tag: WA_NODE_TAGS.LINK_CODE_PAIRING_REF, attrs: {}, content: input.ref }
110
+ ]
111
+ }
112
+ ]);
113
+ }
@@ -4,16 +4,21 @@ import { proto } from '../../proto.js';
4
4
  import { intToBytes } from '../../util/bytes.js';
5
5
  import { WA_VERSION } from '../../version-spec.js';
6
6
  function parseVersion(versionBase) {
7
- const [p = '2', s = '3000', t = '0'] = versionBase.split('.');
7
+ const parts = versionBase.split('.');
8
+ const [p = '2', s = '3000', t = '0'] = parts;
8
9
  const primary = Number.parseInt(p, 10);
9
10
  const secondary = Number.parseInt(s, 10);
10
11
  const tertiary = Number.parseInt(t, 10);
12
+ const quaternary = parts.length > 3 ? Number.parseInt(parts[3], 10) : undefined;
13
+ const quinary = parts.length > 4 ? Number.parseInt(parts[4], 10) : undefined;
11
14
  if (!Number.isSafeInteger(primary) ||
12
15
  !Number.isSafeInteger(secondary) ||
13
- !Number.isSafeInteger(tertiary)) {
16
+ !Number.isSafeInteger(tertiary) ||
17
+ (quaternary !== undefined && !Number.isSafeInteger(quaternary)) ||
18
+ (quinary !== undefined && !Number.isSafeInteger(quinary))) {
14
19
  throw new Error(`invalid versionBase: ${versionBase}`);
15
20
  }
16
- return { primary, secondary, tertiary };
21
+ return { primary, secondary, tertiary, quaternary, quinary };
17
22
  }
18
23
  let cachedLocale = null;
19
24
  function resolveLocale() {
@@ -67,7 +72,7 @@ export function resolveDevicePropsPlatformType(deviceBrowser) {
67
72
  }
68
73
  }
69
74
  function defaultUserAgent(versionBase, deviceOsDisplayName, version) {
70
- const { primary, secondary, tertiary } = version ?? parseVersion(versionBase);
75
+ const { primary, secondary, tertiary, quaternary, quinary } = version ?? parseVersion(versionBase);
71
76
  const locale = resolveLocale();
72
77
  return {
73
78
  platform: proto.ClientPayload.UserAgent.Platform.WEB,
@@ -75,7 +80,9 @@ function defaultUserAgent(versionBase, deviceOsDisplayName, version) {
75
80
  appVersion: {
76
81
  primary,
77
82
  secondary,
78
- tertiary
83
+ tertiary,
84
+ quaternary,
85
+ quinary
79
86
  },
80
87
  mcc: '000',
81
88
  mnc: '000',
@@ -89,13 +96,15 @@ function defaultUserAgent(versionBase, deviceOsDisplayName, version) {
89
96
  };
90
97
  }
91
98
  function defaultDeviceProps(versionBase, config, version) {
92
- const { primary, secondary, tertiary } = version ?? parseVersion(versionBase);
99
+ const { primary, secondary, tertiary, quaternary, quinary } = version ?? parseVersion(versionBase);
93
100
  return proto.DeviceProps.encode({
94
101
  os: config.deviceOsDisplayName ?? process.platform,
95
102
  version: {
96
103
  primary,
97
104
  secondary,
98
- tertiary
105
+ tertiary,
106
+ quaternary,
107
+ quinary
99
108
  },
100
109
  platformType: resolveDevicePropsPlatformType(config.deviceBrowser),
101
110
  requireFullSync: config.requireFullSync === true,
@@ -0,0 +1,152 @@
1
+ import { toProxyDispatcher } from './proxy.js';
2
+ import { toError } from '../util/primitives.js';
3
+ const DEFAULT_USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';
4
+ const DEFAULT_TIMEOUT_MS = 10000;
5
+ const SW_JS_URL = 'https://web.whatsapp.com/sw.js';
6
+ const CLIENT_REVISION_PATTERN = /\\?"client_revision\\?":\s*(\d+)/;
7
+ /**
8
+ * Public app-listing page whose markup embeds the current WhatsApp for
9
+ * Android release. WhatsApp's own `whatsapp.com/android` page only shows a
10
+ * stale minimum-requirement version, so a mirror that tracks the live
11
+ * release is used as the default source.
12
+ */
13
+ const MOBILE_SOURCE_URL = 'https://whatsapp-messenger.en.uptodown.com/android';
14
+ /**
15
+ * Matches a WhatsApp for Android version. These always start with `2.` and
16
+ * carry exactly four dotted numeric parts (`2.YY.WW.RR`) - the shape a mobile
17
+ * session requires in its login payload. The first match on the listing page
18
+ * is the current release; older releases appear further down the document.
19
+ */
20
+ const MOBILE_VERSION_PATTERN = /\b(2(?:\.\d{1,4}){3})\b/;
21
+ /**
22
+ * Fetches `url` with the shared timeout/abort/proxy scaffolding and returns
23
+ * the response body text. `label` names the source in error messages
24
+ * (`failed to fetch <label>: ...`, `<label> timed out after ...`).
25
+ */
26
+ async function fetchSourceText(url, label, defaultHeaders, options) {
27
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
28
+ const dispatcher = toProxyDispatcher(options.proxy);
29
+ const fetchImpl = options.fetch ?? fetch;
30
+ const controller = new AbortController();
31
+ const timer = setTimeout(() => controller.abort(new Error(`fetch ${label} timed out after ${timeoutMs}ms`)), timeoutMs);
32
+ timer.unref?.();
33
+ let onExternalAbort = null;
34
+ const externalSignal = options.signal;
35
+ if (externalSignal) {
36
+ if (externalSignal.aborted) {
37
+ controller.abort(externalSignal.reason);
38
+ }
39
+ else {
40
+ onExternalAbort = () => controller.abort(externalSignal.reason);
41
+ externalSignal.addEventListener('abort', onExternalAbort, { once: true });
42
+ }
43
+ }
44
+ try {
45
+ const headers = {
46
+ ...defaultHeaders,
47
+ 'user-agent': options.userAgent ?? DEFAULT_USER_AGENT
48
+ };
49
+ if (options.headers) {
50
+ for (const key in options.headers) {
51
+ headers[key.toLowerCase()] = options.headers[key];
52
+ }
53
+ }
54
+ const init = {
55
+ method: 'GET',
56
+ headers,
57
+ signal: controller.signal
58
+ };
59
+ if (dispatcher) {
60
+ ;
61
+ init.dispatcher = dispatcher;
62
+ }
63
+ let response;
64
+ try {
65
+ response = await fetchImpl(url, init);
66
+ }
67
+ catch (error) {
68
+ throw new Error(`failed to fetch ${label}: ${toError(error).message}`);
69
+ }
70
+ if (!response.ok) {
71
+ throw new Error(`failed to fetch ${label}: http ${response.status}`);
72
+ }
73
+ return await response.text();
74
+ }
75
+ finally {
76
+ clearTimeout(timer);
77
+ if (externalSignal && onExternalAbort) {
78
+ externalSignal.removeEventListener('abort', onExternalAbort);
79
+ }
80
+ }
81
+ }
82
+ /**
83
+ * Fetches the current WhatsApp Web `client_revision` from the public
84
+ * `sw.js` served by the WhatsApp Web frontend and assembles a
85
+ * `2.3000.x` version string suitable for `WaClientOptions.version`.
86
+ *
87
+ * Use this when the library's hardcoded default starts being rejected by
88
+ * the server with HTTP 405 / `failure_client_too_old`, and you need to
89
+ * refresh the version without waiting for a library bump.
90
+ *
91
+ * Network failures and parse errors throw; wrap in a `try`/`catch` and
92
+ * fall back to the hardcoded default.
93
+ *
94
+ * @example
95
+ * const latest = await fetchLatestWaWebVersion()
96
+ * const client = new WaClient({ store, sessionId, version: latest.version })
97
+ */
98
+ export async function fetchLatestWaWebVersion(options = {}) {
99
+ const body = await fetchSourceText(SW_JS_URL, 'sw.js', { 'sec-fetch-site': 'none' }, options);
100
+ const match = CLIENT_REVISION_PATTERN.exec(body);
101
+ if (!match?.[1]) {
102
+ throw new Error('client_revision not found in sw.js response');
103
+ }
104
+ const revision = Number.parseInt(match[1], 10);
105
+ if (!Number.isSafeInteger(revision) || revision <= 0) {
106
+ throw new Error(`invalid client_revision in sw.js: ${match[1]}`);
107
+ }
108
+ return {
109
+ version: `2.3000.${revision}`,
110
+ parts: [2, 3000, revision]
111
+ };
112
+ }
113
+ /**
114
+ * Fetches the current WhatsApp for Android app version by scraping a public
115
+ * app-listing page and assembles a `2.26.x.y` version string suitable for
116
+ * `WaMobileTransportDeviceInfo.appVersion` (the mobile login payload).
117
+ *
118
+ * This is the mobile counterpart to {@link fetchLatestWaWebVersion}. The Web
119
+ * client exposes its `client_revision` in a stable JSON blob (`sw.js`); the
120
+ * Android app version is only published on app-listing pages, so this reads
121
+ * HTML and is inherently more layout-dependent. Retarget it with `url` /
122
+ * `versionPattern` if the default source changes.
123
+ *
124
+ * Use this when the app version baked into your `deviceInfo` starts being
125
+ * rejected by the server as too old, and you need to refresh it without
126
+ * waiting for a library bump.
127
+ *
128
+ * Network failures and parse errors throw; wrap in a `try`/`catch` and fall
129
+ * back to a known-good hardcoded version.
130
+ *
131
+ * @example
132
+ * const latest = await fetchLatestWaMobileVersion()
133
+ * const deviceInfo = { ...baseDeviceInfo, appVersion: latest.version }
134
+ */
135
+ export async function fetchLatestWaMobileVersion(options = {}) {
136
+ const versionPattern = options.versionPattern ?? MOBILE_VERSION_PATTERN;
137
+ const body = await fetchSourceText(options.url ?? MOBILE_SOURCE_URL, 'wa-mobile version page', { accept: 'text/html,application/xhtml+xml', 'accept-language': 'en-US,en;q=0.9' }, options);
138
+ versionPattern.lastIndex = 0;
139
+ const match = versionPattern.exec(body);
140
+ if (!match?.[1]) {
141
+ throw new Error('wa-mobile version not found in page response');
142
+ }
143
+ const version = match[1];
144
+ const parts = version.split('.').map((part) => Number.parseInt(part, 10));
145
+ if (parts.length !== 4 || parts.some((part) => !Number.isSafeInteger(part) || part < 0)) {
146
+ throw new Error(`invalid wa-mobile version parsed from page: ${version}`);
147
+ }
148
+ return {
149
+ version,
150
+ parts: parts
151
+ };
152
+ }
@@ -1,3 +1,4 @@
1
+ export { delay } from './async.js';
1
2
  export { base64ToBytes, bytesToBase64, bytesToBase64UrlSafe, bytesToHex, concatBytes, decodeBase64Url, EMPTY_BYTES, hexToBytes, TEXT_DECODER, TEXT_ENCODER, toBytesView, uint8Equal, uint8TimingSafeEqual } from './bytes.js';
2
3
  export { asBytes, asNumber, asOptionalBytes, asOptionalNumber, asOptionalString, asString, resolvePositive, toBoolOrUndef } from './coercion.js';
3
4
  export { normalizeQueryLimit } from './collections.js';
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export type { WaClientDependencies } from './client/WaClientFactory';
4
4
  export type { WaClientEventMap, WaClientOptions, WaClientProxyOptions, WaDownloadMediaOptions, WaHistorySyncChunkEvent, WaHistorySyncOptions, WaWriteBehindOptions } from './client/types';
5
5
  export type { WaClientPluginContext, WaClientPluginDefinition } from './client/plugins';
6
6
  export type { WaMessageCoordinator } from './client/coordinators/WaMessageCoordinator';
7
- export type { WaAccountTakeoverNoticeEvent, WaAppStateMutationEvent, WaAppStateMutationSource, WaBusinessEvent, WaBusinessEventAction, WaBusinessProfileResult, WaConnectionEvent, WaGroupEvent, WaGroupEventAction, WaGroupEventLinkedGroup, WaGroupEventMembershipRequest, WaGroupEventParticipant, WaGroupEventSubgroupSuggestion, WaIgnoreKey, WaIgnoreKeyContext, WaIgnoreKeyPredicate, WaIgnoreStanzaKind, WaIncomingAddonEvent, WaIncomingBaseEvent, WaIncomingBotChunkEvent, WaIncomingCallEvent, WaIncomingChatstateEvent, WaIncomingErrorStanzaEvent, WaIncomingFailureEvent, WaIncomingMessageEvent, WaIncomingMessageKey, WaIncomingNewsletterEvent, WaIncomingNewsletterMessageUpdateEvent, WaIncomingNodeHandler, WaIncomingNodeHandlerRegistration, WaIncomingNotificationEvent, WaIncomingPresenceEvent, WaIncomingProtocolMessageEvent, WaIncomingReceiptEvent, WaIncomingStanzaFilter, WaIncomingUnavailableMessageEvent, WaIncomingUnhandledStanzaEvent, WaMexLidChangeEvent, WaMexMessageCappingEvent, WaMexMessageCappingStatus, WaMexNotificationEvent, WaMexNotificationGraphQlError, WaMexNotificationOperationName, WaMexNotificationUnknownEvent, WaMexOwnUsernameSyncEvent, WaMexTextStatusUpdateEvent, WaMexTextStatusUpdateHintEvent, WaMexUsernameDeleteEvent, WaMexUsernameSetEvent, WaMexUsernameUpdateHintEvent, WaOfflineResumeEvent, WaPictureEvent, WaPictureEventAction, WaPrivacyTokenUpdateEvent, WaReceiptStatus, WaRegistrationCodeEvent, WaSendMessageOptions, WaUnavailableMessageKind, WaVerifiedNameResult, WaAddonKind, WaNewsletterEventAction, WaNewsletterMessageUpdate, WaNewsletterPollVoteEntry, WaNewsletterReactionEntry } from './client/types';
7
+ export type { WaAccountTakeoverNoticeEvent, WaAppStateMutationEvent, WaAppStateMutationSource, WaBusinessEvent, WaBusinessEventAction, WaBusinessProfileResult, WaConnectionEvent, WaGroupEvent, WaGroupEventAction, WaGroupEventLinkedGroup, WaGroupEventMembershipRequest, WaGroupEventParticipant, WaGroupEventSubgroupSuggestion, WaIgnoreKey, WaIgnoreKeyContext, WaIgnoreKeyPredicate, WaIgnoreStanzaKind, WaIncomingAddonEvent, WaIncomingBaseEvent, WaIncomingBotChunkEvent, WaIncomingCallEvent, WaIncomingChatstateEvent, WaIncomingErrorStanzaEvent, WaIncomingFailureEvent, WaIncomingMessageEvent, WaIncomingMessageKey, WaIncomingNewsletterEvent, WaIncomingNewsletterMessageUpdateEvent, WaIncomingNodeHandler, WaIncomingNodeHandlerRegistration, WaIncomingNotificationEvent, WaIncomingPresenceEvent, WaIncomingProtocolMessageEvent, WaIncomingReceiptEvent, WaIncomingStanzaFilter, WaIncomingUnavailableMessageEvent, WaIncomingUnhandledStanzaEvent, WaMexLidChangeEvent, WaMexMessageCappingEvent, WaMexMessageCappingStatus, WaMexNotificationEvent, WaMexNotificationGraphQlError, WaMexNotificationOperationName, WaMexNotificationUnknownEvent, WaMexOwnUsernameSyncEvent, WaMexTextStatusUpdateEvent, WaMexTextStatusUpdateHintEvent, WaMexUsernameDeleteEvent, WaMexUsernameSetEvent, WaMexUsernameUpdateHintEvent, WaOfflineResumeEvent, WaOutgoingMessageEvent, WaPictureEvent, WaPictureEventAction, WaPrivacyTokenUpdateEvent, WaReceiptStatus, WaRegistrationCodeEvent, WaSendMessageOptions, WaUnavailableMessageKind, WaVerifiedNameResult, WaAddonKind, WaNewsletterEventAction, WaNewsletterMessageUpdate, WaNewsletterPollVoteEntry, WaNewsletterReactionEntry } from './client/types';
8
8
  export type { WaAppStateMutationCoordinator, WaBroadcastListParticipant, WaSetBroadcastListInput, WaSetStatusPrivacyInput } from './client/coordinators/WaAppStateMutationCoordinator';
9
9
  export type { WaBotCoordinator, WaBotInfo, WaBotPosingAsProfessional, WaBotProfileCommand, WaBotProfilePrompt, WaBotProfileResult, WaBotPromptOptions, WaGetBotProfileOptions } from './client/coordinators/WaBotCoordinator';
10
10
  export type { WaBroadcastListCoordinator, WaSendBroadcastListMessageInput } from './client/coordinators/WaBroadcastListCoordinator';
@@ -14,6 +14,9 @@ export type { WaDownloadMediaMessageOptions, WaUploadMediaSource } from './clien
14
14
  export type { WaEditBusinessProfileInput } from './transport/node/builders/business';
15
15
  export type { WaEmailCoordinator, WaEmailStatus, WaEmailVerifyCodeResult } from './client/coordinators/WaEmailCoordinator';
16
16
  export type { WaCommunityCreateOptions, WaCommunitySubGroup, WaCommunitySubGroupResult, WaCommunitySubGroupsResult, WaGroupCoordinator, WaGroupCreateOptions, WaGroupMetadata, WaGroupParticipant, WaLinkSubGroupsResult, WaMembershipRequest, WaUnlinkSubGroupsResult } from './client/coordinators/WaGroupCoordinator';
17
+ export type { LinkCompanionResult, WaMobileCoordinator } from './client/coordinators/WaMobileCoordinator';
18
+ export { createFileCompanionHostPersistence } from './client/persistence/companion-host';
19
+ export type { CompanionHostEpochState, CompanionHostPersistence, CompanionRecord } from './client/persistence/companion-host';
17
20
  export type { WaNewsletterAdminInfo, WaNewsletterAdminInviteInput, WaNewsletterAdminInviteResult, WaNewsletterAdminProfile, WaNewsletterCapabilityExposure, WaNewsletterCoordinator, WaNewsletterCreateInput, WaNewsletterDehydratedMetadata, WaNewsletterDirectoryCategoriesPreviewOptions, WaNewsletterDirectoryCategoryPreview, WaNewsletterDirectoryListOptions, WaNewsletterDirectoryResults, WaNewsletterDirectorySearchOptions, WaNewsletterDirectoryView, WaNewsletterFetchOptions, WaNewsletterFollower, WaNewsletterFollowersOptions, WaNewsletterFollowersPage, WaNewsletterInsightMetricRequest, WaNewsletterMetadata, WaNewsletterMuteInput, WaNewsletterPicture, WaNewsletterPollVoter, WaNewsletterReactInput, WaNewsletterReactionSenders, WaNewsletterRecommendedOptions, WaNewsletterRevokeInput, WaNewsletterSendOptions, WaNewsletterSendResult, WaNewsletterSimilarOptions, WaNewsletterUpdateInput, WaNewsletterViewReceiptInput, WaNewsletterVotePollInput, WaPageInfo } from './client/coordinators/WaNewsletterCoordinator';
18
21
  export type { WaBlocklistResult, WaPrivacyCoordinator, WaPrivacyDisallowedListResult, WaPrivacySettings } from './client/coordinators/WaPrivacyCoordinator';
19
22
  export type { WaDisappearingModeResult, WaOwnUsernameResult, WaProfileCoordinator, WaProfileInfo, WaProfilePictureResult, WaProfileStatusResult, WaSetTextStatusInput, WaSetUsernameInput, WaTextStatusResult, WaUsernameResult } from './client/coordinators/WaProfileCoordinator';
@@ -22,7 +25,8 @@ export { parseUsyncResultEnvelope } from './transport/node/builders/usync';
22
25
  export type { WaUsyncProtocolError, WaUsyncResultEnvelope } from './transport/node/builders/usync';
23
26
  export type { WaSendStatusInput, WaStatusCoordinator } from './client/coordinators/WaStatusCoordinator';
24
27
  export type { WaEncryptedMessageInput, WaMessageAckMetadata, WaMessageKey, WaMessagePublishOptions, WaMessagePublishResult, WaMessageRef, WaMessageTargetInput, WaSendEditKey, WaSendEventLocation, WaSendEventMessage, WaSendEventParent, WaSendEventResponseMessage, WaSendEventResponseType, WaSendKeepMessage, WaSendMediaMessage, WaSendMessageContent, WaSendPinMessage, WaSendPollMessage, WaSendPollOptionInput, WaSendPollParent, WaSendPollVoteMessage, WaSendReactionMessage, WaSendReceiptEventOptions, WaSendReceiptInput, WaSendReceiptOptions, WaSendRevokeMessage, WaSendStickerPackMessage, WaSendStickerPackStickerInput, WaSendStickerPackTrayIcon, WaSendTextMessage } from './message/types';
25
- export { getContentType, resolveMessageTarget } from './message/encode/content';
28
+ export { getContentType, resolveEncMediaType, resolveMessageTarget, unwrapMessage } from './message/encode/content';
29
+ export { getContextInfo } from './message/context-info';
26
30
  export { resolveMediaPayload } from './message/encode/media-payload';
27
31
  export { unpadPkcs7, writeRandomPadMax16 } from './message/encode/padding';
28
32
  export type { WaResolvedMediaPayload } from './message/encode/media-payload';
@@ -32,16 +36,18 @@ export type { SignalLidSyncResult } from './signal/api/SignalDeviceSyncApi';
32
36
  export type { WaAuthCredentials, WaVersionResolver } from './auth/types';
33
37
  export type { WaShortcakeAssertionSigner } from './auth/pairing/WaShortcakeFlow';
34
38
  export type { BinaryNode } from './transport/types';
35
- export { fetchLatestWaWebVersion } from './transport/wa-web-version-fetcher';
36
- export type { WaFetchLatestWebVersionOptions, WaLatestWebVersion } from './transport/wa-web-version-fetcher';
39
+ export { fetchLatestWaWebVersion, fetchLatestWaMobileVersion } from './transport/wa-version-fetcher';
40
+ export type { WaFetchVersionOptions, WaFetchLatestWebVersionOptions, WaFetchLatestMobileVersionOptions, WaLatestWebVersion, WaLatestMobileVersion } from './transport/wa-version-fetcher';
37
41
  export { ConsoleLogger } from './infra/log/ConsoleLogger';
38
42
  export { PinoLogger, createPinoLogger } from './infra/log/PinoLogger';
39
43
  export type { PinoLoggerOptions } from './infra/log/PinoLogger';
40
44
  export { createNoopLogger } from './infra/log/types';
41
45
  export type { Logger, LogLevel } from './infra/log/types';
46
+ export { WA_VERSION } from './version-spec';
42
47
  export { createStore, WaAuthMemoryStore } from './store';
43
48
  export type { WaAppStateCollectionStoreState, WaAppStateStore, WaAuthStore, WaContactStore, WaCreateStoreOptions, WaCreateStoreOptionsStrict, WaDeviceListSnapshot, WaDeviceListStore, WaGroupMetadataSnapshot, WaGroupMetadataStore, WaMessageStore, WaRetryStore, WaSenderKeyStore, WaSessionStore, WaSignalStore, WaIdentityStore, WaPreKeyStore, WaStoredContactRecord, WaStoredMessageRecord, WaStoredThreadRecord, WaStore, WaStoreBackend, WaStoreSession, WaThreadStore } from './store';
44
49
  export { delay } from './util/async';
45
50
  export { buildDeviceJid, canonicalizeSignalJid, canonicalizeSignalServer, getLoginIdentity, getWaCompanionPlatformId, getWaMediaHkdfInfo, isBotJid, isBroadcastJid, isGroupJid, isGroupOrBroadcastJid, isHostedDeviceId, isHostedDeviceJid, isHostedServer, isLidJid, isNewsletterJid, isStatusBroadcastJid, isUserJid, normalizeDeviceJid, normalizeRecipientJid, parseJidFull, parsePhoneJid, parseSignalAddressFromJid, signalAddressKey, splitJid, toUserJid, WA_ACCOUNT_SYNC_PROTOCOLS, WA_APP_STATE_COLLECTIONS, WA_APP_STATE_COLLECTION_STATES, WA_APP_STATE_ERROR_CODES, WA_APP_STATE_KDF_INFO, WA_APP_STATE_KEY_TYPES, WA_APP_STATE_SYNC_DATA_TYPE, WA_BROWSERS, WA_BUSINESS_HOURS_DAYS, WA_BUSINESS_HOURS_MODES, WA_COMPANION_PLATFORM_IDS, WA_DEFAULTS, WA_DIRTY_PROTOCOLS, WA_DIRTY_TYPES, WA_DISCONNECT_REASONS, WA_IQ_TYPES, WA_LOGOUT_REASONS, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_MEDIA_HKDF_INFO, WA_NODE_TAGS, WA_PAIRING_KDF_INFO, WA_PREVIEW_MEDIA_HKDF_INFO, WA_READY_STATES, WA_RETRYABLE_ACK_CODES, WA_SIGNALING, WA_STREAM_SIGNALING, WA_SUPPORTED_DIRTY_TYPES, WA_PRIVACY_CATEGORIES, WA_PRIVACY_CATEGORY_TO_SETTING, WA_PRIVACY_DISALLOWED_LIST_CATEGORIES, WA_PRIVACY_SETTING_TO_CATEGORY, WA_PRIVACY_TAGS, WA_PRIVACY_VALUES, WA_XMLNS } from './protocol';
46
51
  export type { ParsedJid, WaBusinessHoursDay, WaBusinessHoursMode, WaConnectionCode, WaConnectionOpenReason, WaDisconnectReason, WaFailureReasonCode, WaLogoutReason, WaPrivacyCategory, WaPrivacySettingName, WaPrivacyValue, WaStreamErrorCode } from './protocol';
47
52
  export { proto } from './proto';
53
+ export type { Proto } from './proto';
package/dist/index.js CHANGED
@@ -1,25 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WA_BROWSERS = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = exports.WA_APP_STATE_COLLECTIONS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.toUserJid = exports.splitJid = exports.signalAddressKey = exports.parseSignalAddressFromJid = exports.parsePhoneJid = exports.parseJidFull = exports.normalizeRecipientJid = exports.normalizeDeviceJid = exports.isUserJid = exports.isStatusBroadcastJid = exports.isNewsletterJid = exports.isLidJid = exports.isHostedServer = exports.isHostedDeviceJid = exports.isHostedDeviceId = exports.isGroupOrBroadcastJid = exports.isGroupJid = exports.isBroadcastJid = exports.isBotJid = exports.getWaMediaHkdfInfo = exports.getWaCompanionPlatformId = exports.getLoginIdentity = exports.canonicalizeSignalServer = exports.canonicalizeSignalJid = exports.buildDeviceJid = exports.delay = exports.WaAuthMemoryStore = exports.createStore = exports.createNoopLogger = exports.createPinoLogger = exports.PinoLogger = exports.ConsoleLogger = exports.fetchLatestWaWebVersion = exports.writeRandomPadMax16 = exports.unpadPkcs7 = exports.resolveMediaPayload = exports.resolveMessageTarget = exports.getContentType = exports.parseUsyncResultEnvelope = exports.downloadMediaMessage = exports.defineWaClientPlugin = exports.WaClient = void 0;
4
- exports.proto = exports.WA_XMLNS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_SIGNALING = exports.WA_RETRYABLE_ACK_CODES = exports.WA_READY_STATES = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_PAIRING_KDF_INFO = exports.WA_NODE_TAGS = exports.WA_MEDIA_HKDF_INFO = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_LOGOUT_REASONS = exports.WA_IQ_TYPES = exports.WA_DISCONNECT_REASONS = exports.WA_DIRTY_TYPES = exports.WA_DIRTY_PROTOCOLS = exports.WA_DEFAULTS = exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BUSINESS_HOURS_MODES = exports.WA_BUSINESS_HOURS_DAYS = void 0;
3
+ exports.WA_APP_STATE_COLLECTIONS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.toUserJid = exports.splitJid = exports.signalAddressKey = exports.parseSignalAddressFromJid = exports.parsePhoneJid = exports.parseJidFull = exports.normalizeRecipientJid = exports.normalizeDeviceJid = exports.isUserJid = exports.isStatusBroadcastJid = exports.isNewsletterJid = exports.isLidJid = exports.isHostedServer = exports.isHostedDeviceJid = exports.isHostedDeviceId = exports.isGroupOrBroadcastJid = exports.isGroupJid = exports.isBroadcastJid = exports.isBotJid = exports.getWaMediaHkdfInfo = exports.getWaCompanionPlatformId = exports.getLoginIdentity = exports.canonicalizeSignalServer = exports.canonicalizeSignalJid = exports.buildDeviceJid = exports.delay = exports.WaAuthMemoryStore = exports.createStore = exports.WA_VERSION = exports.createNoopLogger = exports.createPinoLogger = exports.PinoLogger = exports.ConsoleLogger = exports.fetchLatestWaMobileVersion = exports.fetchLatestWaWebVersion = exports.writeRandomPadMax16 = exports.unpadPkcs7 = exports.resolveMediaPayload = exports.getContextInfo = exports.unwrapMessage = exports.resolveMessageTarget = exports.resolveEncMediaType = exports.getContentType = exports.parseUsyncResultEnvelope = exports.createFileCompanionHostPersistence = exports.downloadMediaMessage = exports.defineWaClientPlugin = exports.WaClient = void 0;
4
+ exports.proto = exports.WA_XMLNS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_SIGNALING = exports.WA_RETRYABLE_ACK_CODES = exports.WA_READY_STATES = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_PAIRING_KDF_INFO = exports.WA_NODE_TAGS = exports.WA_MEDIA_HKDF_INFO = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_LOGOUT_REASONS = exports.WA_IQ_TYPES = exports.WA_DISCONNECT_REASONS = exports.WA_DIRTY_TYPES = exports.WA_DIRTY_PROTOCOLS = exports.WA_DEFAULTS = exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BUSINESS_HOURS_MODES = exports.WA_BUSINESS_HOURS_DAYS = exports.WA_BROWSERS = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = void 0;
5
5
  var _client_1 = require("./client");
6
6
  Object.defineProperty(exports, "WaClient", { enumerable: true, get: function () { return _client_1.WaClient; } });
7
7
  var plugins_1 = require("./client/plugins");
8
8
  Object.defineProperty(exports, "defineWaClientPlugin", { enumerable: true, get: function () { return plugins_1.defineWaClientPlugin; } });
9
9
  var media_1 = require("./client/media");
10
10
  Object.defineProperty(exports, "downloadMediaMessage", { enumerable: true, get: function () { return media_1.downloadMediaMessage; } });
11
+ var companion_host_1 = require("./client/persistence/companion-host");
12
+ Object.defineProperty(exports, "createFileCompanionHostPersistence", { enumerable: true, get: function () { return companion_host_1.createFileCompanionHostPersistence; } });
11
13
  var usync_1 = require("./transport/node/builders/usync");
12
14
  Object.defineProperty(exports, "parseUsyncResultEnvelope", { enumerable: true, get: function () { return usync_1.parseUsyncResultEnvelope; } });
13
15
  var content_1 = require("./message/encode/content");
14
16
  Object.defineProperty(exports, "getContentType", { enumerable: true, get: function () { return content_1.getContentType; } });
17
+ Object.defineProperty(exports, "resolveEncMediaType", { enumerable: true, get: function () { return content_1.resolveEncMediaType; } });
15
18
  Object.defineProperty(exports, "resolveMessageTarget", { enumerable: true, get: function () { return content_1.resolveMessageTarget; } });
19
+ Object.defineProperty(exports, "unwrapMessage", { enumerable: true, get: function () { return content_1.unwrapMessage; } });
20
+ var context_info_1 = require("./message/context-info");
21
+ Object.defineProperty(exports, "getContextInfo", { enumerable: true, get: function () { return context_info_1.getContextInfo; } });
16
22
  var media_payload_1 = require("./message/encode/media-payload");
17
23
  Object.defineProperty(exports, "resolveMediaPayload", { enumerable: true, get: function () { return media_payload_1.resolveMediaPayload; } });
18
24
  var padding_1 = require("./message/encode/padding");
19
25
  Object.defineProperty(exports, "unpadPkcs7", { enumerable: true, get: function () { return padding_1.unpadPkcs7; } });
20
26
  Object.defineProperty(exports, "writeRandomPadMax16", { enumerable: true, get: function () { return padding_1.writeRandomPadMax16; } });
21
- var wa_web_version_fetcher_1 = require("./transport/wa-web-version-fetcher");
22
- Object.defineProperty(exports, "fetchLatestWaWebVersion", { enumerable: true, get: function () { return wa_web_version_fetcher_1.fetchLatestWaWebVersion; } });
27
+ var wa_version_fetcher_1 = require("./transport/wa-version-fetcher");
28
+ Object.defineProperty(exports, "fetchLatestWaWebVersion", { enumerable: true, get: function () { return wa_version_fetcher_1.fetchLatestWaWebVersion; } });
29
+ Object.defineProperty(exports, "fetchLatestWaMobileVersion", { enumerable: true, get: function () { return wa_version_fetcher_1.fetchLatestWaMobileVersion; } });
23
30
  var ConsoleLogger_1 = require("./infra/log/ConsoleLogger");
24
31
  Object.defineProperty(exports, "ConsoleLogger", { enumerable: true, get: function () { return ConsoleLogger_1.ConsoleLogger; } });
25
32
  var PinoLogger_1 = require("./infra/log/PinoLogger");
@@ -27,6 +34,8 @@ Object.defineProperty(exports, "PinoLogger", { enumerable: true, get: function (
27
34
  Object.defineProperty(exports, "createPinoLogger", { enumerable: true, get: function () { return PinoLogger_1.createPinoLogger; } });
28
35
  var types_1 = require("./infra/log/types");
29
36
  Object.defineProperty(exports, "createNoopLogger", { enumerable: true, get: function () { return types_1.createNoopLogger; } });
37
+ var _version_spec_1 = require("./version-spec");
38
+ Object.defineProperty(exports, "WA_VERSION", { enumerable: true, get: function () { return _version_spec_1.WA_VERSION; } });
30
39
  var _store_1 = require("./store");
31
40
  Object.defineProperty(exports, "createStore", { enumerable: true, get: function () { return _store_1.createStore; } });
32
41
  Object.defineProperty(exports, "WaAuthMemoryStore", { enumerable: true, get: function () { return _store_1.WaAuthMemoryStore; } });
@@ -229,7 +229,8 @@ class WaMessageClient {
229
229
  }
230
230
  extractAckMetadata(ackNode) {
231
231
  const addressingModeRaw = ackNode.attrs.addressing_mode;
232
- const addressingMode = addressingModeRaw === 'pn' || addressingModeRaw === 'lid'
232
+ const addressingMode = addressingModeRaw === constants_1.WA_ADDRESSING_MODES.PN ||
233
+ addressingModeRaw === constants_1.WA_ADDRESSING_MODES.LID
233
234
  ? addressingModeRaw
234
235
  : undefined;
235
236
  return {
@@ -27,6 +27,8 @@ export declare function applyContextInfo(message: Proto.IMessage, ctx: WaSendCon
27
27
  * `undefined` when no submessage has an `expiration` set.
28
28
  */
29
29
  export declare function pickIncomingExpirationSeconds(message: Proto.IMessage | undefined): number | undefined;
30
+ /** Reads the `contextInfo` off a message's first content submessage (null when absent). */
31
+ export declare function getContextInfo(message: Proto.IMessage): Proto.IContextInfo | null;
30
32
  /**
31
33
  * Anything that identifies a quoted message. Accepts a {@link WaQuoteRef}, a
32
34
  * {@link WaMessageKey} (bare proto key), or a full incoming message event (its
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildContextInfoProto = buildContextInfoProto;
4
4
  exports.applyContextInfo = applyContextInfo;
5
5
  exports.pickIncomingExpirationSeconds = pickIncomingExpirationSeconds;
6
+ exports.getContextInfo = getContextInfo;
6
7
  exports.resolveSendContextInfo = resolveSendContextInfo;
7
8
  const jid_1 = require("../protocol/jid");
8
9
  function buildContextInfoProto(input) {
@@ -91,6 +92,10 @@ function pickContextInfoTarget(message) {
91
92
  }
92
93
  return null;
93
94
  }
95
+ /** Reads the `contextInfo` off a message's first content submessage (null when absent). */
96
+ function getContextInfo(message) {
97
+ return pickContextInfoTarget(message)?.contextInfo ?? null;
98
+ }
94
99
  function resolveSendContextInfo(input) {
95
100
  const ctx = {
96
101
  ...(input.contentLevel ?? {}),
@@ -1,12 +1,14 @@
1
- export { getWaCompanionPlatformId, WA_BROWSERS, WA_COMPANION_PLATFORM_IDS } from './browser';
1
+ export { getWaBrowserDisplayName, getWaCompanionPlatformId, WA_BROWSERS, WA_COMPANION_PLATFORM_IDS } from './browser';
2
+ export { resolveWaDeviceIdentity } from './device-identity';
3
+ export type { WaDeviceIdentity, WaDeviceIdentityOptions } from './device-identity';
2
4
  export { WA_SIGNALING, WA_PAIRING_KDF_INFO } from './auth';
3
5
  export { WA_CONNECTION_REASONS, WA_DISCONNECT_REASONS, WA_FAILURE_REASONS, WA_LOGOUT_REASONS, WA_READY_STATES, WA_STREAM_SIGNALING } from './stream';
4
6
  export type { WaConnectionCode, WaConnectionOpenReason, WaDisconnectReason, WaFailureReasonCode, WaLogoutReason, WaStreamErrorCode } from './stream';
5
7
  export { WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from './nodes';
6
8
  export { WA_CALL_CHILD_TAGS, WA_CALL_NODE_ATTRS, WA_CALL_PAYLOAD_TAGS, WA_CALL_RECEIPT_PAYLOAD_TAGS } from './call';
7
9
  export type { WaCallPayloadTag } from './call';
8
- export { WA_EDIT_ATTRS, WA_ENC_MEDIA_TYPES, WA_EVENT_META_TYPES, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NACK_REASONS, WA_POLL_META_TYPES, WA_RETRYABLE_ACK_CODES, WA_STANZA_MSG_TYPES } from './message';
9
- export type { WaOutboundReceiptType } from './message';
10
+ export { WA_ADDRESSING_MODES, WA_EDIT_ATTRS, WA_ENC_CIPHERTEXT_TYPES, WA_ENC_MEDIA_TYPES, WA_EVENT_META_TYPES, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NACK_REASONS, WA_POLL_META_TYPES, WA_RETRYABLE_ACK_CODES, WA_STANZA_MSG_TYPES } from './message';
11
+ export type { WaAddressingMode, WaEncCiphertextType, WaOutboundReceiptType } from './message';
10
12
  export { WA_APP_STATE_COLLECTIONS, WA_APP_STATE_COLLECTION_STATES, WA_APP_STATE_ERROR_CODES, WA_APP_STATE_KDF_INFO, WA_APP_STATE_KEY_TYPES, WA_APP_STATE_SYNC_DATA_TYPE } from './appstate';
11
13
  export { getWaMediaHkdfInfo, WA_MEDIA_HKDF_INFO, WA_PREVIEW_MEDIA_HKDF_INFO } from './media';
12
14
  export { WA_ACCOUNT_SYNC_PROTOCOLS, WA_DIRTY_PROTOCOLS, WA_DIRTY_TYPES, WA_SUPPORTED_DIRTY_TYPES } from './dirty';
@@ -27,7 +29,7 @@ export { WA_EMAIL_CONTEXTS, WA_EMAIL_ERROR_CODES, WA_EMAIL_LIMITS, WA_EMAIL_TAGS
27
29
  export type { WaEmailContext, WaEmailErrorCode } from './email';
28
30
  export { AB_PROP_CONFIGS, resolveAbPropNameByCode, WA_ABPROPS_PROTOCOL_VERSION, WA_ABPROPS_REFRESH_BOUNDS } from './abprops';
29
31
  export type { AbPropConfigEntry, AbPropName, AbPropType, AbPropValue } from './abprops';
30
- export { WA_GROUP_PARTICIPANT_TYPES, type WaGroupSetting } from './group';
32
+ export { WA_GROUP_MEMBERSHIP_ACTION_TAGS, WA_GROUP_PARTICIPANT_TYPES, type WaGroupSetting } from './group';
31
33
  export { WA_USYNC_CONTEXTS, WA_USYNC_DEFAULTS, WA_USYNC_MODES } from './usync';
32
34
  export { WA_NEWSLETTER_FETCH_KEY_TYPES, WA_NEWSLETTER_MUTE_TYPES, WA_NEWSLETTER_MUTE_VALUES, WA_NEWSLETTER_PICTURE_TYPES, WA_NEWSLETTER_RECEIVE_TYPES, WA_NEWSLETTER_ROLES, WA_NEWSLETTER_SEND_TYPES, WA_NEWSLETTER_STATE_TYPES, WA_NEWSLETTER_VERIFICATION_STATES, WA_NEWSLETTER_VIEW_ROLES } from './newsletter';
33
35
  export type { WaNewsletterReceiveType, WaNewsletterRole, WaNewsletterSendType, WaNewsletterStateType } from './newsletter';
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WA_PRESENCE_TYPES = exports.WA_PRESENCE_LAST_SENTINELS = exports.WA_CHATSTATE_MEDIA = exports.WA_BUSINESS_HOURS_MODES = exports.WA_BUSINESS_HOURS_DAYS = exports.WA_REGISTRATION_NOTIFICATION_TAGS = exports.WA_NOTIFICATION_TYPES = exports.WA_NEWSLETTER_NOTIFICATION_TAGS = exports.WA_GROUP_NOTIFICATION_TAGS = exports.WA_BUSINESS_NOTIFICATION_TAGS = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_DIRTY_TYPES = exports.WA_DIRTY_PROTOCOLS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_MEDIA_HKDF_INFO = exports.getWaMediaHkdfInfo = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = exports.WA_APP_STATE_COLLECTIONS = exports.WA_STANZA_MSG_TYPES = exports.WA_RETRYABLE_ACK_CODES = exports.WA_POLL_META_TYPES = exports.WA_NACK_REASONS = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_EVENT_META_TYPES = exports.WA_ENC_MEDIA_TYPES = exports.WA_EDIT_ATTRS = exports.WA_CALL_RECEIPT_PAYLOAD_TAGS = exports.WA_CALL_PAYLOAD_TAGS = exports.WA_CALL_NODE_ATTRS = exports.WA_CALL_CHILD_TAGS = exports.WA_XMLNS = exports.WA_NODE_TAGS = exports.WA_IQ_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_READY_STATES = exports.WA_LOGOUT_REASONS = exports.WA_FAILURE_REASONS = exports.WA_DISCONNECT_REASONS = exports.WA_CONNECTION_REASONS = exports.WA_PAIRING_KDF_INFO = exports.WA_SIGNALING = exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BROWSERS = exports.getWaCompanionPlatformId = void 0;
4
- exports.WA_NEWSLETTER_VIEW_ROLES = exports.WA_NEWSLETTER_VERIFICATION_STATES = exports.WA_NEWSLETTER_STATE_TYPES = exports.WA_NEWSLETTER_SEND_TYPES = exports.WA_NEWSLETTER_ROLES = exports.WA_NEWSLETTER_RECEIVE_TYPES = exports.WA_NEWSLETTER_PICTURE_TYPES = exports.WA_NEWSLETTER_MUTE_VALUES = exports.WA_NEWSLETTER_MUTE_TYPES = exports.WA_NEWSLETTER_FETCH_KEY_TYPES = exports.WA_USYNC_MODES = exports.WA_USYNC_DEFAULTS = exports.WA_USYNC_CONTEXTS = exports.WA_GROUP_PARTICIPANT_TYPES = exports.WA_ABPROPS_REFRESH_BOUNDS = exports.WA_ABPROPS_PROTOCOL_VERSION = exports.resolveAbPropNameByCode = exports.AB_PROP_CONFIGS = exports.WA_EMAIL_XMLNS = exports.WA_EMAIL_TAGS = exports.WA_EMAIL_LIMITS = exports.WA_EMAIL_ERROR_CODES = exports.WA_EMAIL_CONTEXTS = exports.WA_STATUS_DISTRIBUTION_SETTINGS = exports.WA_META_NODE_ATTRS_BOT = exports.WA_BOT_NODE_ATTRS = exports.WA_BOT_MSG_SECRET_BYTES = exports.WA_BOT_MSG_EDIT_TYPES = exports.WA_BOT_MSG_BODY_TYPES = exports.WA_BOT_KNOWN_JIDS = exports.WA_BOT_HKDF_INFO = exports.WA_BOT_DEFAULT_CAPABILITIES = exports.WA_BIZ_BOT_TYPES = exports.WA_DEFAULTS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_TC_TOKEN_DEFAULTS = exports.WA_PRIVACY_TOKEN_TYPES = exports.WA_PRIVACY_TOKEN_TAGS = exports.WA_PRIVACY_TOKEN_NOTIFICATION_TYPE = void 0;
3
+ exports.WA_BUSINESS_HOURS_DAYS = exports.WA_REGISTRATION_NOTIFICATION_TAGS = exports.WA_NOTIFICATION_TYPES = exports.WA_NEWSLETTER_NOTIFICATION_TAGS = exports.WA_GROUP_NOTIFICATION_TAGS = exports.WA_BUSINESS_NOTIFICATION_TAGS = exports.WA_SUPPORTED_DIRTY_TYPES = exports.WA_DIRTY_TYPES = exports.WA_DIRTY_PROTOCOLS = exports.WA_ACCOUNT_SYNC_PROTOCOLS = exports.WA_PREVIEW_MEDIA_HKDF_INFO = exports.WA_MEDIA_HKDF_INFO = exports.getWaMediaHkdfInfo = exports.WA_APP_STATE_SYNC_DATA_TYPE = exports.WA_APP_STATE_KEY_TYPES = exports.WA_APP_STATE_KDF_INFO = exports.WA_APP_STATE_ERROR_CODES = exports.WA_APP_STATE_COLLECTION_STATES = exports.WA_APP_STATE_COLLECTIONS = exports.WA_STANZA_MSG_TYPES = exports.WA_RETRYABLE_ACK_CODES = exports.WA_POLL_META_TYPES = exports.WA_NACK_REASONS = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = exports.WA_EVENT_META_TYPES = exports.WA_ENC_MEDIA_TYPES = exports.WA_ENC_CIPHERTEXT_TYPES = exports.WA_EDIT_ATTRS = exports.WA_ADDRESSING_MODES = exports.WA_CALL_RECEIPT_PAYLOAD_TAGS = exports.WA_CALL_PAYLOAD_TAGS = exports.WA_CALL_NODE_ATTRS = exports.WA_CALL_CHILD_TAGS = exports.WA_XMLNS = exports.WA_NODE_TAGS = exports.WA_IQ_TYPES = exports.WA_STREAM_SIGNALING = exports.WA_READY_STATES = exports.WA_LOGOUT_REASONS = exports.WA_FAILURE_REASONS = exports.WA_DISCONNECT_REASONS = exports.WA_CONNECTION_REASONS = exports.WA_PAIRING_KDF_INFO = exports.WA_SIGNALING = exports.resolveWaDeviceIdentity = exports.WA_COMPANION_PLATFORM_IDS = exports.WA_BROWSERS = exports.getWaCompanionPlatformId = exports.getWaBrowserDisplayName = void 0;
4
+ exports.WA_NEWSLETTER_VIEW_ROLES = exports.WA_NEWSLETTER_VERIFICATION_STATES = exports.WA_NEWSLETTER_STATE_TYPES = exports.WA_NEWSLETTER_SEND_TYPES = exports.WA_NEWSLETTER_ROLES = exports.WA_NEWSLETTER_RECEIVE_TYPES = exports.WA_NEWSLETTER_PICTURE_TYPES = exports.WA_NEWSLETTER_MUTE_VALUES = exports.WA_NEWSLETTER_MUTE_TYPES = exports.WA_NEWSLETTER_FETCH_KEY_TYPES = exports.WA_USYNC_MODES = exports.WA_USYNC_DEFAULTS = exports.WA_USYNC_CONTEXTS = exports.WA_GROUP_PARTICIPANT_TYPES = exports.WA_GROUP_MEMBERSHIP_ACTION_TAGS = exports.WA_ABPROPS_REFRESH_BOUNDS = exports.WA_ABPROPS_PROTOCOL_VERSION = exports.resolveAbPropNameByCode = exports.AB_PROP_CONFIGS = exports.WA_EMAIL_XMLNS = exports.WA_EMAIL_TAGS = exports.WA_EMAIL_LIMITS = exports.WA_EMAIL_ERROR_CODES = exports.WA_EMAIL_CONTEXTS = exports.WA_STATUS_DISTRIBUTION_SETTINGS = exports.WA_META_NODE_ATTRS_BOT = exports.WA_BOT_NODE_ATTRS = exports.WA_BOT_MSG_SECRET_BYTES = exports.WA_BOT_MSG_EDIT_TYPES = exports.WA_BOT_MSG_BODY_TYPES = exports.WA_BOT_KNOWN_JIDS = exports.WA_BOT_HKDF_INFO = exports.WA_BOT_DEFAULT_CAPABILITIES = exports.WA_BIZ_BOT_TYPES = exports.WA_DEFAULTS = exports.WA_PRIVACY_VALUES = exports.WA_PRIVACY_TAGS = exports.WA_PRIVACY_SETTING_TO_CATEGORY = exports.WA_PRIVACY_DISALLOWED_LIST_CATEGORIES = exports.WA_PRIVACY_CATEGORY_TO_SETTING = exports.WA_PRIVACY_CATEGORIES = exports.WA_TC_TOKEN_DEFAULTS = exports.WA_PRIVACY_TOKEN_TYPES = exports.WA_PRIVACY_TOKEN_TAGS = exports.WA_PRIVACY_TOKEN_NOTIFICATION_TYPE = exports.WA_PRESENCE_TYPES = exports.WA_PRESENCE_LAST_SENTINELS = exports.WA_CHATSTATE_MEDIA = exports.WA_BUSINESS_HOURS_MODES = void 0;
5
5
  var browser_1 = require("./browser");
6
+ Object.defineProperty(exports, "getWaBrowserDisplayName", { enumerable: true, get: function () { return browser_1.getWaBrowserDisplayName; } });
6
7
  Object.defineProperty(exports, "getWaCompanionPlatformId", { enumerable: true, get: function () { return browser_1.getWaCompanionPlatformId; } });
7
8
  Object.defineProperty(exports, "WA_BROWSERS", { enumerable: true, get: function () { return browser_1.WA_BROWSERS; } });
8
9
  Object.defineProperty(exports, "WA_COMPANION_PLATFORM_IDS", { enumerable: true, get: function () { return browser_1.WA_COMPANION_PLATFORM_IDS; } });
10
+ var device_identity_1 = require("./device-identity");
11
+ Object.defineProperty(exports, "resolveWaDeviceIdentity", { enumerable: true, get: function () { return device_identity_1.resolveWaDeviceIdentity; } });
9
12
  var auth_1 = require("./auth");
10
13
  Object.defineProperty(exports, "WA_SIGNALING", { enumerable: true, get: function () { return auth_1.WA_SIGNALING; } });
11
14
  Object.defineProperty(exports, "WA_PAIRING_KDF_INFO", { enumerable: true, get: function () { return auth_1.WA_PAIRING_KDF_INFO; } });
@@ -26,7 +29,9 @@ Object.defineProperty(exports, "WA_CALL_NODE_ATTRS", { enumerable: true, get: fu
26
29
  Object.defineProperty(exports, "WA_CALL_PAYLOAD_TAGS", { enumerable: true, get: function () { return call_1.WA_CALL_PAYLOAD_TAGS; } });
27
30
  Object.defineProperty(exports, "WA_CALL_RECEIPT_PAYLOAD_TAGS", { enumerable: true, get: function () { return call_1.WA_CALL_RECEIPT_PAYLOAD_TAGS; } });
28
31
  var message_1 = require("./message");
32
+ Object.defineProperty(exports, "WA_ADDRESSING_MODES", { enumerable: true, get: function () { return message_1.WA_ADDRESSING_MODES; } });
29
33
  Object.defineProperty(exports, "WA_EDIT_ATTRS", { enumerable: true, get: function () { return message_1.WA_EDIT_ATTRS; } });
34
+ Object.defineProperty(exports, "WA_ENC_CIPHERTEXT_TYPES", { enumerable: true, get: function () { return message_1.WA_ENC_CIPHERTEXT_TYPES; } });
30
35
  Object.defineProperty(exports, "WA_ENC_MEDIA_TYPES", { enumerable: true, get: function () { return message_1.WA_ENC_MEDIA_TYPES; } });
31
36
  Object.defineProperty(exports, "WA_EVENT_META_TYPES", { enumerable: true, get: function () { return message_1.WA_EVENT_META_TYPES; } });
32
37
  Object.defineProperty(exports, "WA_MESSAGE_TAGS", { enumerable: true, get: function () { return message_1.WA_MESSAGE_TAGS; } });
@@ -102,6 +107,7 @@ Object.defineProperty(exports, "resolveAbPropNameByCode", { enumerable: true, ge
102
107
  Object.defineProperty(exports, "WA_ABPROPS_PROTOCOL_VERSION", { enumerable: true, get: function () { return abprops_1.WA_ABPROPS_PROTOCOL_VERSION; } });
103
108
  Object.defineProperty(exports, "WA_ABPROPS_REFRESH_BOUNDS", { enumerable: true, get: function () { return abprops_1.WA_ABPROPS_REFRESH_BOUNDS; } });
104
109
  var group_1 = require("./group");
110
+ Object.defineProperty(exports, "WA_GROUP_MEMBERSHIP_ACTION_TAGS", { enumerable: true, get: function () { return group_1.WA_GROUP_MEMBERSHIP_ACTION_TAGS; } });
105
111
  Object.defineProperty(exports, "WA_GROUP_PARTICIPANT_TYPES", { enumerable: true, get: function () { return group_1.WA_GROUP_PARTICIPANT_TYPES; } });
106
112
  var usync_1 = require("./usync");
107
113
  Object.defineProperty(exports, "WA_USYNC_CONTEXTS", { enumerable: true, get: function () { return usync_1.WA_USYNC_CONTEXTS; } });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Raw device-identity inputs a caller may set. Any field left unset is filled
3
+ * with the same default the client uses, so callers that resolve identity
4
+ * independently (e.g. the WAM analytics plugin) stay consistent with the
5
+ * pairing `ClientPayload`.
6
+ */
7
+ export interface WaDeviceIdentityOptions {
8
+ readonly deviceBrowser?: string;
9
+ readonly deviceOsDisplayName?: string;
10
+ readonly devicePlatform?: string;
11
+ }
12
+ /** Fully-resolved device identity advertised to WhatsApp. */
13
+ export interface WaDeviceIdentity {
14
+ readonly browser: string;
15
+ readonly osDisplayName: string;
16
+ readonly platform: string;
17
+ }
18
+ /**
19
+ * Resolves the device identity from raw options, applying the shared defaults:
20
+ * browser falls back to {@link WA_DEFAULTS}.DEVICE_BROWSER, OS name to the
21
+ * detected runtime OS, and platform id is inferred from the browser. This is
22
+ * the single source of truth used by both the client factory and the auth
23
+ * client so the pairing payload and any analytics/telemetry agree.
24
+ */
25
+ export declare function resolveWaDeviceIdentity(options: WaDeviceIdentityOptions): WaDeviceIdentity;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveWaDeviceIdentity = resolveWaDeviceIdentity;
4
+ const browser_1 = require("./browser");
5
+ const defaults_1 = require("./defaults");
6
+ const runtime_1 = require("../util/runtime");
7
+ /**
8
+ * Resolves the device identity from raw options, applying the shared defaults:
9
+ * browser falls back to {@link WA_DEFAULTS}.DEVICE_BROWSER, OS name to the
10
+ * detected runtime OS, and platform id is inferred from the browser. This is
11
+ * the single source of truth used by both the client factory and the auth
12
+ * client so the pairing payload and any analytics/telemetry agree.
13
+ */
14
+ function resolveWaDeviceIdentity(options) {
15
+ const browser = options.deviceBrowser ?? defaults_1.WA_DEFAULTS.DEVICE_BROWSER;
16
+ return Object.freeze({
17
+ browser,
18
+ osDisplayName: options.deviceOsDisplayName ?? (0, runtime_1.getRuntimeOsDisplayName)(),
19
+ platform: options.devicePlatform ?? (0, browser_1.getWaCompanionPlatformId)(browser)
20
+ });
21
+ }
@@ -3,4 +3,10 @@ export declare const WA_GROUP_PARTICIPANT_TYPES: Readonly<{
3
3
  readonly ADMIN: "admin";
4
4
  readonly REGULAR: "participant";
5
5
  }>;
6
+ /** `<membership_requests_action>` child tags for approving/rejecting group join requests. */
7
+ export declare const WA_GROUP_MEMBERSHIP_ACTION_TAGS: Readonly<{
8
+ readonly REQUESTS_ACTION: "membership_requests_action";
9
+ readonly APPROVE: "approve";
10
+ readonly REJECT: "reject";
11
+ }>;
6
12
  export type WaGroupSetting = 'announcement' | 'restrict' | 'ephemeral' | 'membership_approval_mode' | 'allow_non_admin_sub_group_creation' | 'group_history' | 'allow_admin_reports' | 'no_frequently_forwarded';