Skip to content

Commit c30af94

Browse files
committed
fix: support newsletter media uploads
1 parent 63c7997 commit c30af94

5 files changed

Lines changed: 198 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ lerna-debug.log*
3838
!/test/
3939
/test/*
4040
!/test/createJid.test.ts
41+
!/test/baileysNewsletterMediaPatch.test.ts
4142
/src/env.yml
4243
/store
4344
*.env

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ LABEL contact="contato@evolution-api.com"
1010
WORKDIR /evolution
1111

1212
COPY ./package*.json ./
13+
COPY ./scripts ./scripts
1314
COPY ./tsconfig.json ./
1415
COPY ./tsup.config.ts ./
1516

@@ -43,6 +44,7 @@ WORKDIR /evolution
4344
COPY --from=builder /evolution/package.json ./package.json
4445
COPY --from=builder /evolution/package-lock.json ./package-lock.json
4546

47+
COPY --from=builder /evolution/scripts ./scripts
4648
COPY --from=builder /evolution/node_modules ./node_modules
4749
COPY --from=builder /evolution/dist ./dist
4850
COPY --from=builder /evolution/prisma ./prisma

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"db:studio": "node runWithProvider.js \"npx prisma studio --schema ./prisma/DATABASE_PROVIDER-schema.prisma\"",
2121
"db:migrate:dev": "node runWithProvider.js \"rm -rf ./prisma/migrations && cp -r ./prisma/DATABASE_PROVIDER-migrations ./prisma/migrations && npx prisma migrate dev --schema ./prisma/DATABASE_PROVIDER-schema.prisma && cp -r ./prisma/migrations/* ./prisma/DATABASE_PROVIDER-migrations\"",
2222
"db:migrate:dev:win": "node runWithProvider.js \"xcopy /E /I prisma\\DATABASE_PROVIDER-migrations prisma\\migrations && npx prisma migrate dev --schema prisma\\DATABASE_PROVIDER-schema.prisma\"",
23-
"prepare": "husky"
23+
"prepare": "husky",
24+
"postinstall": "node scripts/patch-baileys-newsletter-media.cjs"
2425
},
2526
"repository": {
2627
"type": "git",
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
const { existsSync, readFileSync, writeFileSync } = require('node:fs');
2+
const { join } = require('node:path');
3+
4+
const baileysLib = join(process.cwd(), 'node_modules', 'baileys', 'lib');
5+
6+
function replaceInFile(relativePath, replacements) {
7+
const filePath = join(baileysLib, relativePath);
8+
9+
if (!existsSync(filePath)) {
10+
throw new Error(`Baileys file not found: ${relativePath}`);
11+
}
12+
13+
let source = readFileSync(filePath, 'utf8');
14+
15+
for (const { from, to, marker } of replacements) {
16+
if (marker && source.includes(marker)) {
17+
continue;
18+
}
19+
20+
if (!source.includes(from)) {
21+
if (source.includes(to)) {
22+
continue;
23+
}
24+
25+
throw new Error(`Patch target not found in ${relativePath}: ${from.slice(0, 120)}`);
26+
}
27+
28+
source = source.replace(from, to);
29+
}
30+
31+
writeFileSync(filePath, source, 'utf8');
32+
}
33+
34+
replaceInFile('Defaults/index.js', [
35+
{
36+
marker: 'NEWSLETTER_MEDIA_PATH_MAP',
37+
from: `export const MEDIA_PATH_MAP = {
38+
image: '/mms/image',
39+
video: '/mms/video',
40+
document: '/mms/document',
41+
audio: '/mms/audio',
42+
sticker: '/mms/image',
43+
'thumbnail-link': '/mms/image',
44+
'product-catalog-image': '/product/image',
45+
'md-app-state': '',
46+
'md-msg-hist': '/mms/md-app-state',
47+
'biz-cover-photo': '/pps/biz-cover-photo'
48+
};`,
49+
to: `export const MEDIA_PATH_MAP = {
50+
image: '/mms/image',
51+
video: '/mms/video',
52+
document: '/mms/document',
53+
audio: '/mms/audio',
54+
sticker: '/mms/image',
55+
'thumbnail-link': '/mms/image',
56+
'product-catalog-image': '/product/image',
57+
'md-app-state': '',
58+
'md-msg-hist': '/mms/md-app-state',
59+
'biz-cover-photo': '/pps/biz-cover-photo'
60+
};
61+
export const NEWSLETTER_MEDIA_PATH_MAP = {
62+
image: '/newsletter/newsletter-image',
63+
video: '/newsletter/newsletter-video',
64+
document: '/newsletter/newsletter-document',
65+
audio: '/newsletter/newsletter-audio',
66+
sticker: '/newsletter/newsletter-image',
67+
'thumbnail-link': '/newsletter/newsletter-image'
68+
};`,
69+
},
70+
]);
71+
72+
replaceInFile('Utils/messages-media.js', [
73+
{
74+
marker: 'NEWSLETTER_MEDIA_PATH_MAP',
75+
from: `import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP } from '../Defaults/index.js';`,
76+
to: `import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP, NEWSLETTER_MEDIA_PATH_MAP } from '../Defaults/index.js';`,
77+
},
78+
{
79+
marker: 'newsletter }) =>',
80+
from: `export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
81+
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {`,
82+
to: `export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
83+
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs, newsletter }) => {`,
84+
},
85+
{
86+
marker: 'server_thumb_gen=1',
87+
from: ` const url = \`https://\${hostname}\${MEDIA_PATH_MAP[mediaType]}/\${fileEncSha256B64}?auth=\${auth}&token=\${fileEncSha256B64}\`;`,
88+
to: ` const mediaPathMap = newsletter ? NEWSLETTER_MEDIA_PATH_MAP : MEDIA_PATH_MAP;
89+
const serverThumbGen = newsletter ? '&server_thumb_gen=1' : '';
90+
const url = \`https://\${hostname}\${mediaPathMap[mediaType]}/\${fileEncSha256B64}?auth=\${auth}&token=\${fileEncSha256B64}\${serverThumbGen}\`;`,
91+
},
92+
{
93+
marker: 'thumbnailDirectPath: result.thumbnail_info?.thumbnail_direct_path',
94+
from: ` fbid: result.fbid,
95+
ts: result.ts`,
96+
to: ` fbid: result.fbid,
97+
thumbnailDirectPath: result.thumbnail_info?.thumbnail_direct_path,
98+
thumbnailSha256: result.thumbnail_info?.thumbnail_sha256,
99+
ts: result.ts`,
100+
},
101+
]);
102+
103+
replaceInFile('Utils/messages.js', [
104+
{
105+
marker: 'newsletter:' ,
106+
from: ` const cacheableKey = typeof uploadData.media === 'object' &&
107+
'url' in uploadData.media &&
108+
!!uploadData.media.url &&
109+
!!options.mediaCache &&
110+
mediaType + ':' + uploadData.media.url.toString();`,
111+
to: ` const isNewsletter = !!options.jid && isJidNewsletter(options.jid);
112+
const cacheableKey = typeof uploadData.media === 'object' &&
113+
'url' in uploadData.media &&
114+
!!uploadData.media.url &&
115+
!!options.mediaCache &&
116+
mediaType + ':' + (isNewsletter ? 'newsletter:' : 'normal:') + uploadData.media.url.toString();`,
117+
},
118+
{
119+
from: ` const isNewsletter = !!options.jid && isJidNewsletter(options.jid);
120+
if (isNewsletter) {`,
121+
to: ` if (isNewsletter) {`,
122+
},
123+
{
124+
marker: 'newsletter: isNewsletter',
125+
from: ` const { mediaUrl, directPath } = await options.upload(filePath, {
126+
fileEncSha256B64: fileSha256B64,
127+
mediaType: mediaType,
128+
timeoutMs: options.mediaUploadTimeoutMs
129+
});`,
130+
to: ` const { directPath, thumbnailDirectPath, thumbnailSha256 } = await options.upload(filePath, {
131+
fileEncSha256B64: fileSha256B64,
132+
mediaType: mediaType,
133+
timeoutMs: options.mediaUploadTimeoutMs,
134+
newsletter: isNewsletter
135+
});`,
136+
},
137+
{
138+
marker: 'thumbnailDirectPath,',
139+
from: ` url: mediaUrl,
140+
directPath,
141+
fileSha256,
142+
fileLength,
143+
...uploadData,
144+
media: undefined`,
145+
to: ` directPath,
146+
fileSha256,
147+
fileLength,
148+
thumbnailDirectPath,
149+
thumbnailSha256: thumbnailSha256 ? Buffer.from(thumbnailSha256, 'base64') : undefined,
150+
...uploadData,
151+
media: undefined`,
152+
},
153+
]);
154+
155+
replaceInFile('Socket/messages-send.js', [
156+
{
157+
marker: "attrs: extraAttrs",
158+
from: ` binaryNodeContent.push({
159+
tag: 'plaintext',
160+
attrs: {},
161+
content: bytes
162+
});`,
163+
to: ` binaryNodeContent.push({
164+
tag: 'plaintext',
165+
attrs: extraAttrs,
166+
content: bytes
167+
});`,
168+
},
169+
]);
170+
171+
console.log('Baileys newsletter media patch applied');
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import assert from 'node:assert/strict';
2+
import { readFileSync } from 'node:fs';
3+
import { join } from 'node:path';
4+
5+
const baileysLib = join(process.cwd(), 'node_modules', 'baileys', 'lib');
6+
7+
const defaults = readFileSync(join(baileysLib, 'Defaults', 'index.js'), 'utf8');
8+
const messagesMedia = readFileSync(join(baileysLib, 'Utils', 'messages-media.js'), 'utf8');
9+
const messages = readFileSync(join(baileysLib, 'Utils', 'messages.js'), 'utf8');
10+
const messagesSend = readFileSync(join(baileysLib, 'Socket', 'messages-send.js'), 'utf8');
11+
12+
assert.match(defaults, /NEWSLETTER_MEDIA_PATH_MAP/);
13+
assert.match(messagesMedia, /NEWSLETTER_MEDIA_PATH_MAP/);
14+
assert.match(messagesMedia, /timeoutMs, newsletter/);
15+
assert.match(messagesMedia, /server_thumb_gen=1/);
16+
assert.match(messages, /newsletter: isNewsletter/);
17+
assert.match(messages, /thumbnailDirectPath/);
18+
assert.match(messages, /thumbnailSha256/);
19+
assert.doesNotMatch(messages, /url:\\s*mediaUrl/);
20+
assert.match(messagesSend, /tag: 'plaintext',[\s\S]*attrs: extraAttrs/);
21+
22+
console.log('baileys newsletter media patch ok');

0 commit comments

Comments
 (0)