[READY FOR MERGE] Implement newsletter (#1532)

* feat: implement basic newsletter functionality with socket integration and event handling

* feat: enhance media handling for newsletters with raw media upload support

* feat: working updatePicture, removePicure, adminCount, mute, Unmute

* fix: fetchMessages

* chore: cleanup

* fix: update newsletter metadata path and query ID for consistency. newsletterMetadata works now

* chore: enhance newsletter metadata parsing and error handling

* fix: correct DELETE QueryId value in Newsletter.ts

* chore: split mex stuffs to own file

* chore: remove as any
This commit is contained in:
João Lucas de Oliveira Lopes
2025-06-30 23:22:09 -03:00
committed by GitHub
parent 5ffb19120d
commit 8391c02e0b
13 changed files with 697 additions and 19 deletions

View File

@@ -16,6 +16,7 @@ import {
assertMediaContent,
bindWaitForEvent,
decryptMediaRetryData,
encodeNewsletterMessage,
encodeSignedDeviceIdentity,
encodeWAMessage,
encryptMediaRetryRequest,
@@ -46,6 +47,7 @@ import {
} from '../WABinary'
import { USyncQuery, USyncUser } from '../WAUSync'
import { makeGroupsSocket } from './groups'
import { makeNewsletterSocket, NewsletterSocket } from './newsletter'
export const makeMessagesSocket = (config: SocketConfig) => {
const {
@@ -56,7 +58,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
patchMessageBeforeSending,
cachedGroupMetadata
} = config
const sock = makeGroupsSocket(config)
const sock: NewsletterSocket = makeNewsletterSocket(makeGroupsSocket(config))
const {
ev,
authState,
@@ -373,6 +375,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
const isGroup = server === 'g.us'
const isStatus = jid === statusJid
const isLid = server === 'lid'
const isNewsletter = server === 'newsletter'
msgId = msgId || generateMessageIDV2(sock.user?.id)
useUserDevicesCache = useUserDevicesCache !== false
@@ -411,6 +414,30 @@ export const makeMessagesSocket = (config: SocketConfig) => {
extraAttrs['mediatype'] = mediaType
}
if (isNewsletter) {
// Patch message if needed, then encode as plaintext
const patched = patchMessageBeforeSending ? await patchMessageBeforeSending(message, []) : message
const bytes = encodeNewsletterMessage(patched as proto.IMessage)
binaryNodeContent.push({
tag: 'plaintext',
attrs: {},
content: bytes
})
const stanza: BinaryNode = {
tag: 'message',
attrs: {
to: jid,
id: msgId,
type: getMessageType(message),
...(additionalAttributes || {})
},
content: binaryNodeContent
}
logger.debug({ msgId }, `sending newsletter message to ${jid}`)
await sendNode(stanza)
return
}
if (normalizeMessageContent(message)?.pinInChatMessage) {
extraAttrs['decrypt-fail'] = 'hide'
}