@prototypevip/baileys 0.1.3 → 0.1.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.
package/HELPERS.md ADDED
@@ -0,0 +1,107 @@
1
+ # @prototypevip/baileys — Helpers (v0.1.5)
2
+
3
+ طبقة helpers فوق المسارات الأصلية في المكتبة (`sock.sendMessage` → `nativeFlow` / `album` / `code` / `event` / `product`).
4
+ مفيش بروتوكول جديد هنا؛ كل دالة بتفوّض لمسار موجود ومجرَّب.
5
+
6
+ ## Setup
7
+
8
+ ```js
9
+ import makeWASocket, { attachPrototypeHelpers } from '@prototypevip/baileys'
10
+
11
+ const sock = makeWASocket({ ... })
12
+ attachPrototypeHelpers(sock)
13
+ ```
14
+
15
+ الدوال متاحة كمان كـ named exports: `sendButtons(sock, jid, content, options)` … إلخ.
16
+
17
+ ## أزرار / قوائم
18
+
19
+ ```js
20
+ await sock.sendButtons(jid, {
21
+ text: 'اختار', footer: 'Prototype VIP',
22
+ buttons: [
23
+ { text: 'Menu', id: '#menu' },
24
+ { text: 'موقع', url: 'https://example.com' },
25
+ { text: 'نسخ', copy: 'CODE' },
26
+ { text: 'اتصل', call: '201234567890' }
27
+ ]
28
+ }, { quoted: m })
29
+
30
+ // مع ميديا (بتتحوّل لـ header): image | video | document
31
+ await sock.sendButtons(jid, { text: 'كابشن', image: { url: '...' }, buttons: [...] })
32
+
33
+ // أيقونة AI (شات خاص فقط — في الجروب بتتجاهل)
34
+ await sock.sendAIMessage(jid, { text: 'أهلا', buttons: [...] })
35
+
36
+ // قائمة اختيار (single_select داخل Native Flow). legacy: true = listMessage الكلاسيكي
37
+ await sock.sendList(jid, {
38
+ text: 'القائمة', title: 'T', buttonText: 'افتح',
39
+ sections: [{ title: 'قسم', rows: [{ title: 'A', description: 'd', id: '#a' }] }]
40
+ })
41
+
42
+ await sock.sendQuickButtons(jid, 'اختار', ['نعم', 'لا'])
43
+ ```
44
+
45
+ ## ألبوم / Carousel
46
+
47
+ ```js
48
+ await sock.sendAlbum(jid, [{ image: { url } , caption: '1' }, { video: { url } }], { delayMs: 1500 })
49
+
50
+ // Carousel حقيقي (كل كارت لازم image أو video)
51
+ await sock.sendCarousel(jid, {
52
+ text: 'منتجات', footer: 'Prototype VIP',
53
+ cards: [{ title: 'منتج 1', body: 'وصف', image: 'https://...', buttons: [{ text: 'اشتري', id: '#buy1' }] }]
54
+ })
55
+ ```
56
+
57
+ ## Rich (شكل Meta AI)
58
+
59
+ ```js
60
+ await sock.sendRichCode(jid, { title: 'مثال', code: 'console.log(1)', language: 'javascript' })
61
+
62
+ // ⚠️ HTML: مفيش render حقيقي لـ HTML جوه الفقاعة في المكتبة.
63
+ // sendRichHtml بيبعت الـ HTML كـ code block ملوّن داخل Rich Response.
64
+ await sock.sendRichHtml(jid, { title: 'Card', html: '<div>...</div>' })
65
+ ```
66
+
67
+ ## مكالمات
68
+
69
+ ```js
70
+ // Scheduled Call Event (مفيش WebRTC outbound حقيقي في Baileys)
71
+ await sock.sendScheduledCall(jid, { name: 'اجتماع', startDate: new Date(Date.now() + 3600_000), callType: 'audio' })
72
+ await sock.sendCallInvite(jid, { name: 'مكالمة سريعة', callType: 'video', minutesFromNow: 2 })
73
+ ```
74
+
75
+ ## متفرقات
76
+
77
+ ```js
78
+ await sock.sendViewOnce(jid, { image: { url }, caption: 'مرة واحدة' })
79
+ await sock.sendPoll(jid, 'رأيك؟', ['حلو', 'عادي'], { selectableCount: 1 })
80
+ await sock.sendReaction(jid, m.key, '🔥')
81
+ await sock.sendMentionAll(groupJid, 'يا جماعة')
82
+ await sock.sendLocation(jid, 30.04, 31.23, { name: 'القاهرة', address: '...' })
83
+ await sock.sendContact(jid, { fullName: 'أحمد', phone: '201234567890' })
84
+ await sock.sendProduct(jid, { title: 'منتج', price: 100, currencyCode: 'EGP', image: 'https://...' }) // الصورة مطلوبة
85
+ await sock.sendSticker(jid, { url: 'https://.../x.webp' })
86
+ ```
87
+
88
+ ## JID / LID
89
+
90
+ الـ LID **مش** مشتق من رقم التليفون، فالتحويل بيعتمد على mapping حقيقي (`sock.signalRepository.lidMapping`)
91
+ وبيرجّع `null` لو الـ mapping مش معروف.
92
+
93
+ ```js
94
+ await sock.toLid('2010xxxxxxx@s.whatsapp.net') // → '...@lid' | null (async)
95
+ await sock.toPn('...@lid') // → '...@s.whatsapp.net' | null (async)
96
+ sock.normalizeJid('201...:12@s.whatsapp.net') // يشيل رقم الجهاز بس
97
+ sock.isLid(jid); sock.isPn(jid)
98
+ ```
99
+
100
+ ## Builders
101
+
102
+ ```js
103
+ const btn = sock.button() // Button
104
+ const car = sock.carouselBuilder()
105
+ const rich = sock.aiRich()
106
+ // chain methods ثم .send(jid)
107
+ ```
@@ -2,15 +2,22 @@ import { DEFAULT_CONNECTION_CONFIG } from "../Defaults/index.js";
2
2
  import { makeCommunitiesSocket } from "./communities.js";
3
3
  import { stampSocket } from "../Utils/socket-guard.js";
4
4
  import { verifyBrandIntegrity } from "../Utils/integrity-guard.js";
5
+ import {
6
+ makeNewsletterStatusSender,
7
+ makeNewsletterStatusReactionSender,
8
+ makeNewsletterStatusRevokeSender,
9
+ makeNewsletterStatusFetcher,
10
+ makeNewsletterStatusUpdatesFetcher,
11
+ } from "../Utils/newsletter-status.js";
12
+ import { sendPersonalStatus, sendGroupStatus } from "../Utils/status-helpers.js";
5
13
 
6
14
  /**
7
15
  * Create a WhatsApp socket.
8
16
  * Clean version — without AntiBan.
17
+ * v0.1.4 — Channel Status + Group Status + Personal Status APIs
9
18
  */
10
19
  const makeWASocket = (config = {}) => {
11
- // بصمة "prototype" بتتفحص هنا تلقائي — قبل حتى ما أي سوكت يتبني، مش
12
- // محتاجه استدعاء يدوي من البوت (نفس فلسفة stampSocket تحت). لو حد فَكّ
13
- // اسم الباكدج أو غيّر بايتات البصمة يدوي، المكتبه بترفض تشتغل خالص.
20
+ // بصمة "prototype" بتتفحص هنا تلقائي — قبل حتى ما أي سوكت يتبني
14
21
  if (!verifyBrandIntegrity()) {
15
22
  try {
16
23
  console.error("[INTEGRITY-GUARD] brand fingerprint mismatch — refusing to start.");
@@ -32,14 +39,7 @@ const makeWASocket = (config = {}) => {
32
39
 
33
40
  const newConfig = { ...DEFAULT_CONNECTION_CONFIG, ...restConfig };
34
41
 
35
- // ملحوظه مهمه: `Utils/generics.js` (ودوال تانيه زيها) بتستورد
36
- // DEFAULT_CONNECTION_CONFIG مباشره كـ `config` وبتقرا منها وقت التشغيل
37
- // (مش الـ newConfig المدموج فوق)، فأي override زي generateMessageID/
38
- // generateMessageIDV2 بيتحط هنا كان بيتضاع تماما - الكود الداخلي في
39
- // المكتبه (زي توليد id الأزرار) كان بيفضل يستخدم القيم الافتراضيه
40
- // الأصليه (GIN4B0T/G1N4B0T) حتى لو المستخدم غيّرها في makeWASocket().
41
- // بنعمل mutate للـ object المشترك نفسه عشان أي import ثابت ليه في باقي
42
- // المكتبه ياخد نفس القيم المدموجه.
42
+ // mutate shared DEFAULT so internal imports see overrides
43
43
  Object.assign(DEFAULT_CONNECTION_CONFIG, newConfig);
44
44
 
45
45
  let sock;
@@ -52,11 +52,26 @@ const makeWASocket = (config = {}) => {
52
52
 
53
53
  sock = makeCommunitiesSocket(newConfig);
54
54
 
55
- // ختم السوكت تلقائي هنا — قبل كده كان لازم البوت ينادي stampSocket()
56
- // يدوي بعد ما السوكت يترجع (وده كان سهل يتنسى في ملف 2300+ سطر زي
57
- // patch.js)، دلوقتي أي سوكت طالع من makeWASocket() بيتختم لوحده.
55
+ // ختم السوكت تلقائي
58
56
  stampSocket(sock);
59
57
 
58
+ // ── Channels & Stories APIs (0.1.4) ──────────────────────────
59
+ // Newsletter / Channel status (Elaina-style transport)
60
+ sock.sendNewsletterStatus = makeNewsletterStatusSender(sock, newConfig);
61
+ sock.sendChannelStatus = sock.sendNewsletterStatus; // alias
62
+ sock.sendNewsletterStatusReaction = makeNewsletterStatusReactionSender(sock);
63
+ sock.revokeNewsletterStatus = makeNewsletterStatusRevokeSender(sock);
64
+ sock.getNewsletterStatuses = makeNewsletterStatusFetcher(sock);
65
+ sock.getNewsletterStatusUpdates = makeNewsletterStatusUpdatesFetcher(sock);
66
+
67
+ // Personal story (status@broadcast)
68
+ sock.sendPersonalStatus = (content, statusJidList, options) =>
69
+ sendPersonalStatus(sock, content, statusJidList, options);
70
+
71
+ // Group story (groupStatusMessageV2 / groupStatus flag)
72
+ sock.sendGroupStatus = (groupJid, content, options) =>
73
+ sendGroupStatus(sock, groupJid, content, options);
74
+
60
75
  return sock;
61
76
  };
62
77
 
@@ -67,4 +82,4 @@ const wrapSocketWithFingerprint = (makeSock, opts) =>
67
82
  const PRESETS = {};
68
83
 
69
84
  export default makeWASocket;
70
- export { makeWASocket, wrapSocket, wrapSocketWithFingerprint, PRESETS };
85
+ export { makeWASocket, wrapSocket, wrapSocketWithFingerprint, PRESETS };
@@ -31,3 +31,7 @@ export * from "./ai-rich-formatter.js";
31
31
  export * from "./constants.js";
32
32
  export * from "./socket-guard.js";
33
33
  export * from "./integrity-guard.js";
34
+ export * from "./newsletter-status.js";
35
+ export * from "./status-helpers.js";
36
+ export * from "./modern-messages.js";
37
+ export * from "./prototype-helpers.js";
@@ -17,6 +17,7 @@ import {
17
17
  DEFAULT_ORIGIN,
18
18
  MEDIA_HKDF_KEY_MAPPING,
19
19
  MEDIA_PATH_MAP,
20
+ NEWSLETTER_MEDIA_PATH_MAP,
20
21
  } from "../Defaults/index.js";
21
22
  import {
22
23
  getBinaryNodeChild,
@@ -725,7 +726,7 @@ export const getWAUploadToServer = (
725
726
  { customUploadHosts, fetchAgent, logger, options },
726
727
  refreshMediaConn,
727
728
  ) => {
728
- return async (filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
729
+ return async (filePath, { mediaType, fileEncSha256B64, timeoutMs, newsletter }) => {
729
730
  // send a query JSON to obtain the url & auth token to upload our media
730
731
  let uploadInfo = await refreshMediaConn(false);
731
732
  let urls;
@@ -745,7 +746,8 @@ export const getWAUploadToServer = (
745
746
  for (const { hostname } of hosts) {
746
747
  logger.debug(`uploading to "${hostname}"`);
747
748
  const auth = encodeURIComponent(uploadInfo.auth);
748
- const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
749
+ const mediaPath = (newsletter && NEWSLETTER_MEDIA_PATH_MAP[mediaType]) || MEDIA_PATH_MAP[mediaType];
750
+ const url = `https://${hostname}${mediaPath}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
749
751
  let result;
750
752
  try {
751
753
  result = await uploadMedia(
@@ -758,8 +760,9 @@ export const getWAUploadToServer = (
758
760
  },
759
761
  logger,
760
762
  );
761
- if (result?.url || result?.direct_path) {
763
+ if (result?.url || result?.direct_path || (newsletter && result?.handle)) {
762
764
  urls = {
765
+ handle: result.handle,
763
766
  mediaUrl: result.url,
764
767
  directPath: result.direct_path,
765
768
  meta_hmac: result.meta_hmac,
@@ -402,6 +402,7 @@ export const prepareWAMessageMedia = async (message, options) => {
402
402
  fileEncSha256B64: fileSha256B64,
403
403
  mediaType: mediaType,
404
404
  timeoutMs: options.mediaUploadTimeoutMs,
405
+ newsletter: true,
405
406
  });
406
407
  await fs.unlink(filePath);
407
408
  const obj = WAProto.Message.fromObject({
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Minimal modern-messages shim for @prototypevip/baileys
3
+ * Full Elaina modern message builders are optional; status APIs only need identity transform.
4
+ */
5
+ export const prepareModernMessageContent = (content) => {
6
+ if (!content || typeof content !== "object") return content;
7
+ return content;
8
+ };
9
+
10
+ export default { prepareModernMessageContent };