plogme 2.1.0 → 2.1.2
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/README.md +226 -2
- package/WAProto/WAProto.proto +12 -0
- package/WAProto/index.d.ts +12 -0
- package/WAProto/index.js +12 -0
- package/engine-requirements.js +12 -0
- package/lib/Defaults/ban-checker.js +12 -0
- package/lib/Defaults/index.js +12 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/group-session-builder.js +12 -0
- package/lib/Signal/Group/group_cipher.js +12 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +12 -0
- package/lib/Signal/Group/sender-chain-key.js +12 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +12 -0
- package/lib/Signal/Group/sender-key-message.js +12 -0
- package/lib/Signal/Group/sender-key-name.js +12 -0
- package/lib/Signal/Group/sender-key-record.js +12 -0
- package/lib/Signal/Group/sender-key-state.js +12 -0
- package/lib/Signal/Group/sender-message-key.js +12 -0
- package/lib/Signal/libsignal.js +12 -0
- package/lib/Signal/lid-mapping.js +12 -0
- package/lib/Socket/Client/index.js +12 -0
- package/lib/Socket/Client/types.js +12 -0
- package/lib/Socket/Client/websocket.js +12 -0
- package/lib/Socket/aigroups.js +12 -0
- package/lib/Socket/ban-checker.js +12 -0
- package/lib/Socket/business.js +12 -0
- package/lib/Socket/chats.js +12 -0
- package/lib/Socket/communities.js +12 -0
- package/lib/Socket/graphql.js +12 -0
- package/lib/Socket/groups.js +12 -0
- package/lib/Socket/index.js +12 -0
- package/lib/Socket/interactive-handler.js +12 -0
- package/lib/Socket/interop.js +12 -0
- package/lib/Socket/managed-account.js +12 -0
- package/lib/Socket/messages-recv.js +12 -0
- package/lib/Socket/messages-send.js +358 -7
- package/lib/Socket/mex.js +12 -0
- package/lib/Socket/newsletter.js +12 -0
- package/lib/Socket/privacy.js +12 -0
- package/lib/Socket/registration.js +12 -0
- package/lib/Socket/socket.js +12 -0
- package/lib/Socket/username.js +12 -0
- package/lib/Store/index.js +12 -0
- package/lib/Store/make-cache-manager-store.js +12 -0
- package/lib/Store/make-in-memory-store.js +12 -0
- package/lib/Store/make-ordered-dictionary.js +12 -0
- package/lib/Store/object-repository.js +12 -0
- package/lib/Types/Auth.js +12 -0
- package/lib/Types/Bussines.js +12 -0
- package/lib/Types/Call.js +12 -0
- package/lib/Types/Chat.js +12 -0
- package/lib/Types/Contact.js +12 -0
- package/lib/Types/Events.js +12 -0
- package/lib/Types/GroupMetadata.js +12 -0
- package/lib/Types/Label.js +12 -0
- package/lib/Types/LabelAssociation.js +12 -0
- package/lib/Types/Message.js +12 -0
- package/lib/Types/Mex.js +12 -0
- package/lib/Types/Product.js +12 -0
- package/lib/Types/RichType.js +12 -0
- package/lib/Types/Signal.js +12 -0
- package/lib/Types/Socket.js +12 -0
- package/lib/Types/State.js +12 -0
- package/lib/Types/USync.js +12 -0
- package/lib/Types/index.js +12 -0
- package/lib/Utils/auth-utils.js +12 -0
- package/lib/Utils/bot-capabilities.js +12 -0
- package/lib/Utils/bot-planning-replay.js +12 -0
- package/lib/Utils/browser-utils.js +12 -0
- package/lib/Utils/business.js +12 -0
- package/lib/Utils/channel-policy.js +12 -0
- package/lib/Utils/chat-utils.js +12 -0
- package/lib/Utils/companion-reg-client-utils.js +12 -0
- package/lib/Utils/consumer-application.js +12 -0
- package/lib/Utils/crypto.js +12 -0
- package/lib/Utils/decode-wa-message.js +12 -0
- package/lib/Utils/event-buffer.js +12 -0
- package/lib/Utils/games/miniapp.js +12 -0
- package/lib/Utils/games/slot-machine.js +12 -0
- package/lib/Utils/games/website-preview.js +12 -0
- package/lib/Utils/generics.js +12 -0
- package/lib/Utils/group-history.js +12 -0
- package/lib/Utils/history.js +12 -0
- package/lib/Utils/identity-change-handler.js +12 -0
- package/lib/Utils/index.js +12 -0
- package/lib/Utils/jid-display-normalization.js +12 -0
- package/lib/Utils/link-preview.js +12 -0
- package/lib/Utils/logger.js +12 -0
- package/lib/Utils/lt-hash.js +12 -0
- package/lib/Utils/make-mutex.js +12 -0
- package/lib/Utils/message-composer.js +18 -1
- package/lib/Utils/message-inspect.js +12 -0
- package/lib/Utils/message-retry-manager.js +12 -0
- package/lib/Utils/messages-media.js +12 -0
- package/lib/Utils/messages.js +232 -4
- package/lib/Utils/meta-ai-msmsg.js +12 -0
- package/lib/Utils/meta-compositing.js +12 -0
- package/lib/Utils/native-flow.js +12 -0
- package/lib/Utils/noise-handler.js +12 -0
- package/lib/Utils/offline-node-processor.js +12 -0
- package/lib/Utils/pre-key-manager.js +12 -0
- package/lib/Utils/process-message.js +12 -0
- package/lib/Utils/reporting-utils.js +12 -0
- package/lib/Utils/rich-message-utils.js +484 -91
- package/lib/Utils/signal.js +12 -0
- package/lib/Utils/source-grep.js +12 -0
- package/lib/Utils/stanza-ack.js +12 -0
- package/lib/Utils/sync-action-utils.js +12 -0
- package/lib/Utils/tc-token-utils.js +12 -0
- package/lib/Utils/use-multi-file-auth-state.js +12 -0
- package/lib/Utils/use-single-file-auth-state.js +12 -0
- package/lib/Utils/use-sqlite-auth-state.js +12 -0
- package/lib/Utils/validate-connection.js +12 -0
- package/lib/Utils/view-once-utils.js +12 -0
- package/lib/Utils/voip-rekey.js +12 -0
- package/lib/Utils/welcome-flow.js +12 -0
- package/lib/WABinary/constants.js +12 -0
- package/lib/WABinary/decode.js +12 -0
- package/lib/WABinary/encode.js +12 -0
- package/lib/WABinary/generic-utils.js +12 -0
- package/lib/WABinary/index.js +12 -0
- package/lib/WABinary/jid-utils.js +12 -0
- package/lib/WABinary/types.js +12 -0
- package/lib/WAM/BinaryInfo.js +12 -0
- package/lib/WAM/constants.js +12 -0
- package/lib/WAM/encode.js +12 -0
- package/lib/WAM/index.js +12 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +12 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +12 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +12 -0
- package/lib/WAUSync/Protocols/index.js +12 -0
- package/lib/WAUSync/USyncQuery.js +12 -0
- package/lib/WAUSync/USyncUser.js +12 -0
- package/lib/WAUSync/index.js +12 -0
- package/lib/index.d.ts +50 -2
- package/lib/index.js +12 -0
- package/package.json +9 -2
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/event-buffer.js
|
|
5
|
+
* About: Event buffer module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeEventBuffer
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import EventEmitter from 'events';
|
|
2
14
|
import { WAMessageStatus } from '../Types/index.js';
|
|
3
15
|
import { trimUndefined } from './generics.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/games/miniapp.js
|
|
5
|
+
* About: Miniapp module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: generateMiniAppHtml
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
/** Generate the attached interactive mini-app HTML game. */
|
|
2
14
|
export const generateMiniAppHtml = (options = {}) => {
|
|
3
15
|
const html = "<style>*{-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}</style>\n<body style=\"margin:0;background:transparent;font-family:Arial,sans-serif;color:#eee;touch-action:manipulation;cursor:pointer\">\n<div style=\"width:100%;max-width:620px;margin:auto;padding:16px;box-sizing:border-box\">\n<div style=\"background:rgba(255,255,255,.06);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1px solid rgba(255,255,255,.15);border-radius:16px;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,.35)\">\n<div style=\"padding:18px 20px;border-bottom:1px solid rgba(255,255,255,.12);display:flex;justify-content:space-between;align-items:center\">\n<div><div style=\"font-size:11px;letter-spacing:1.5px;color:rgba(255,255,255,.45)\">𝑶𝒓𝒊𝒈𝒊𝒏✦</div><div style=\"font-size:21px;font-weight:bold;color:#fff\">mini-app</div></div>\n<div style=\"text-align:right\"><div id=\"score\" style=\"font-size:18px;font-weight:bold;color:#fff;text-shadow:0 0 10px rgba(108,92,231,.85);transition:transform .15s\">00000</div><div id=\"best\" style=\"font-size:10px;color:rgba(255,255,255,.4);margin-top:2px\">BEST 00000</div></div>\n</div>\n<div style=\"padding:18px\">\n<canvas id=\"game\" width=\"560\" height=\"190\" style=\"width:100%;height:auto;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.12);border-radius:12px;display:block\"></canvas>\n<div id=\"status\" style=\"text-align:center;margin-top:10px;font-size:12px;color:rgba(255,255,255,.55)\">Velocità 5.0x</div>\n</div></div></div>\n<script>\nconst c=document.getElementById('game'),x=c.getContext('2d'),scoreEl=document.getElementById('score'),bestEl=document.getElementById('best'),statusEl=document.getElementById('status');\nconst GY=170;\nlet d,o,clouds,particles,ambient,trail,score,best=0,speed,gameOver,last,shake,flash,runT,spawnTimer,milestone,squash;\nfunction loadBest(){\nlet vals=[];\ntry{let v=localStorage.getItem('dino_best');if(v)vals.push(parseInt(v,10))}catch(e){}\ntry{let v=sessionStorage.getItem('dino_best');if(v)vals.push(parseInt(v,10))}catch(e){}\ntry{let m=document.cookie.match(/(?:^|;\\s*)dino_best=(\\d+)/);if(m)vals.push(parseInt(m[1],10))}catch(e){}\nreturn vals.length?Math.max(...vals.filter(v=>!isNaN(v))):0\n}\nfunction saveBest(v){\nlet val=String(Math.floor(v));\ntry{localStorage.setItem('dino_best',val)}catch(e){}\ntry{sessionStorage.setItem('dino_best',val)}catch(e){}\ntry{document.cookie='dino_best='+val+';max-age=31536000;path=/'}catch(e){}\ntry{\nlet rq=indexedDB.open('dino_db',1);\nrq.onupgradeneeded=()=>{rq.result.createObjectStore('kv')};\nrq.onsuccess=()=>{try{rq.result.transaction('kv','readwrite').objectStore('kv').put(val,'dino_best')}catch(e){}}\n}catch(e){}\n}\nfunction loadBestAsync(cb){\ntry{\nlet rq=indexedDB.open('dino_db',1);\nrq.onupgradeneeded=()=>{rq.result.createObjectStore('kv')};\nrq.onsuccess=()=>{\ntry{\nlet gr=rq.result.transaction('kv','readonly').objectStore('kv').get('dino_best');\ngr.onsuccess=()=>{if(gr.result)cb(parseInt(gr.result,10))}\n}catch(e){}\n}\n}catch(e){}\n}\nbest=loadBest();\nloadBestAsync(v=>{if(!isNaN(v)&&v>best){best=v;bestEl.textContent='BEST '+String(Math.floor(best)).padStart(5,'0')}});\nfunction reset(){\nd={x:55,y:132,w:27,h:30,vy:0,jumping:false};\no=[];\nclouds=[{x:120,y:32,w:44,s:.35},{x:300,y:52,w:60,s:.22},{x:460,y:26,w:36,s:.4},{x:560,y:70,w:50,s:.18}];\nparticles=[];\ntrail=[];\nif(!ambient){ambient=[];for(let i=0;i<18;i++)ambient.push({x:Math.random()*c.width,y:Math.random()*c.height,r:.5+Math.random()*1.5,vx:.1+Math.random()*.3,ph:Math.random()*10})}\nscore=0;speed=5;gameOver=false;last=0;shake=0;flash=0;runT=0;milestone=0;squash=1;\nspawnTimer=70+Math.random()*30;\nbestEl.textContent='BEST '+String(Math.floor(best)).padStart(5,'0');\nstatusEl.textContent='Speed 5.0x'\n}\nfunction burst(px,py,n,col,spd){for(let i=0;i<n;i++)particles.push({x:px,y:py,vx:(Math.random()-.5)*spd,vy:-Math.random()*spd,life:1,col,size:2+Math.random()*2})}\nfunction jumpDino(){\nif(gameOver){reset();return}\nif(!d.jumping){d.jumping=true;d.vy=-13;squash=.7;burst(d.x+13,d.y+30,10,'255,255,255',4)}\n}\nfunction cactus(){\nlet h=24+Math.random()*24;\no.push({x:c.width+20,y:GY-h,w:16+Math.random()*6,h});\nif(Math.random()<.22){o.push({x:c.width+20+34+Math.random()*10,y:GY-(20+Math.random()*18),w:16,h:20+Math.random()*18})}\n}\nfunction hit(a,b){return a.x+4<b.x+b.w&&a.x+a.w-4>b.x&&a.y+4<b.y+b.h&&a.y+a.h>b.y}\nfunction drawTrail(){\ntrail.forEach((p,i)=>{x.fillStyle='rgba(108,92,231,'+(.25*(i/trail.length))+')';x.fillRect(p.x,p.y,27,30)})\n}\nfunction drawDino(){\nx.save();\nlet cx=d.x+13,cy=d.y+30;\nx.translate(cx,cy);\nx.scale(1/squash,squash);\nx.translate(-cx,-cy);\nlet legOff=d.jumping?0:Math.sin(runT*.5)*5;\nx.fillStyle='#eaeaea';\nx.fillRect(d.x,d.y,27,30);\nx.fillRect(d.x+22,d.y+5,13,18);\nx.fillStyle='#6c5ce7';\nx.fillRect(d.x+29,d.y+8,4,4);\nx.fillStyle='#eaeaea';\nx.fillRect(d.x+5,d.y+30,6,8+legOff);\nx.fillRect(d.x+20,d.y+30,6,8-legOff);\nx.restore()\n}\nfunction drawCactus(q){\nx.save();\nx.shadowColor='rgba(255,90,90,.35)';x.shadowBlur=10;\nx.fillStyle='#e17a7a';\nx.fillRect(q.x,q.y,q.w,q.h);\nx.fillRect(q.x-7,q.y+10,7,6);\nx.fillRect(q.x-7,q.y+4,6,12);\nx.fillRect(q.x+q.w,q.y+18,7,6);\nx.fillRect(q.x+q.w+1,q.y+12,6,12);\nx.restore()\n}\nfunction drawParticles(){\nparticles.forEach(p=>{x.fillStyle='rgba('+p.col+','+Math.max(p.life,0)+')';x.fillRect(p.x,p.y,p.size,p.size)})\n}\nfunction drawAmbient(){\nambient.forEach(p=>{let a=.15+Math.sin(runT*.05+p.ph)*.1;x.fillStyle='rgba(180,160,255,'+a+')';x.beginPath();x.arc(p.x,p.y,p.r,0,7);x.fill()})\n}\nfunction draw(){\nx.clearRect(0,0,c.width,c.height);\nx.save();\nif(shake>0)x.translate((Math.random()-.5)*shake,(Math.random()-.5)*shake);\ndrawAmbient();\nx.fillStyle='rgba(255,255,255,.35)';\nclouds.forEach(q=>{let b=Math.sin(runT*.03+q.x)*2;x.fillRect(q.x,q.y+b,q.w,5);x.fillRect(q.x+10,q.y+b-5,q.w*.45,10)});\nx.strokeStyle='rgba(255,255,255,.25)';\nx.lineWidth=2;\nx.setLineDash([10,8]);\nx.lineDashOffset=-runT*speed*.6;\nx.beginPath();x.moveTo(0,GY);x.lineTo(c.width,GY);x.stroke();\nx.setLineDash([]);\ndrawTrail();\ndrawDino();\no.forEach(drawCactus);\ndrawParticles();\nif(flash>0){x.fillStyle='rgba(255,60,60,'+(flash*.35)+')';x.fillRect(0,0,c.width,c.height)}\nx.restore();\nif(gameOver){\nx.fillStyle='rgba(15,15,25,.55)';x.fillRect(0,0,c.width,c.height);\nx.fillStyle='#fff';x.textAlign='center';\nx.font='bold 24px Arial';x.fillText('GAME OVER',c.width/2,85);\nx.font='14px Arial';x.fillText('Tocca per giocare di nuovo',c.width/2,112);\nx.textAlign='left'\n}\n}\nfunction loop(t){\nif(!last)last=t;\nlet dt=Math.min((t-last)/16.67,2);\nlast=t;\nrunT+=dt;\nif(!gameOver){\nd.y+=d.vy*dt;d.vy+=.75*dt;\nif(d.y>=132){\nif(d.jumping){burst(d.x+13,GY,10,'255,255,255',3.5);squash=1.35}\nd.y=132;d.vy=0;d.jumping=false\n}\nif(d.jumping)trail.push({x:d.x,y:d.y});\nif(trail.length>6)trail.shift();\nif(!d.jumping)trail.length=0;\nsquash+=(1-squash)*.18*dt;\nif(!d.jumping&&Math.floor(runT)%8===0&&Math.random()<.4)burst(d.x+6,GY-2,1,'255,255,255',1.5);\nambient.forEach(p=>{p.x-=p.vx*dt;if(p.x<-4)p.x=c.width+4});\nspawnTimer-=dt;\nif(spawnTimer<=0){cactus();spawnTimer=Math.max(38,62-speed*1.4)+Math.random()*30}\no.forEach(q=>q.x-=speed*dt);\no=o.filter(q=>q.x>-40);\nclouds.forEach(q=>{q.x-=q.s*dt;if(q.x<-80)q.x=c.width+Math.random()*100});\nparticles.forEach(p=>{p.x+=p.vx*dt;p.y+=p.vy*dt;p.vy+=.3*dt;p.life-=.03*dt});\nparticles=particles.filter(p=>p.life>0);\nspeed=Math.min(11,speed+.0018*dt);\nscore+=dt*.6;\nif(score>best)best=score;\nif(Math.floor(score/500)>milestone){\nmilestone=Math.floor(score/500);\nscoreEl.style.transform='scale(1.35)';\nsetTimeout(()=>scoreEl.style.transform='scale(1)',150)\n}\nscoreEl.textContent=String(Math.floor(score)).padStart(5,'0');\nbestEl.textContent='BEST '+String(Math.floor(best)).padStart(5,'0');\nstatusEl.textContent='Speed '+speed.toFixed(1)+'x';\nfor(const q of o)if(hit(d,q)){\ngameOver=true;shake=14;flash=1;\nsaveBest(best);\nburst(d.x+13,d.y+15,18,'255,90,90',5)\n}\n}\nif(shake>0)shake=Math.max(0,shake-.6*dt);\nif(flash>0)flash=Math.max(0,flash-.05*dt);\ndraw();\nrequestAnimationFrame(loop)\n}\ndocument.addEventListener('pointerdown',e=>{e.preventDefault();jumpDino()});\ndocument.addEventListener('keydown',e=>{if(e.code==='Space'){e.preventDefault();jumpDino()}});\nreset();\nrequestAnimationFrame(loop);\n</script></body>";
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/games/slot-machine.js
|
|
5
|
+
* About: Slot machine module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: generateSlotMachineHtml, prepareSlotMachineMessage
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
/**
|
|
2
14
|
* Slot Machine Game — Fruit Bonanza
|
|
3
15
|
*
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/games/website-preview.js
|
|
5
|
+
* About: Website preview module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: generateWebsitePreviewHtml, generateLinkPreviewHtml
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
/**
|
|
2
14
|
* Website Preview — Mirror any website inside WhatsApp chat
|
|
3
15
|
*
|
package/lib/Utils/generics.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/generics.js
|
|
5
|
+
* About: Generics module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: BufferJSON, getKeyAuthor, isStringNullOrEmpty, writeRandomPadMax16, unpadRandomMax16, generateParticipantHashV2, encodeWAMessage, generateRegistrationId; …
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { Boom } from '@hapi/boom';
|
|
2
14
|
import { createHash, randomBytes, randomFillSync } from 'crypto';
|
|
3
15
|
import { proto } from '../../WAProto/index.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/group-history.js
|
|
5
|
+
* About: Group history module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: decodeGroupHistory, processGroupHistory
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { inflateSync } from 'zlib';
|
|
2
14
|
import { proto } from '../../WAProto/index.js';
|
|
3
15
|
|
package/lib/Utils/history.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/history.js
|
|
5
|
+
* About: History module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: downloadHistory, processHistoryMessage, downloadAndProcessHistorySyncNotification, getHistoryMsg
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { promisify } from 'util';
|
|
2
14
|
import { inflate } from 'zlib';
|
|
3
15
|
import { proto } from '../../WAProto/index.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/identity-change-handler.js
|
|
5
|
+
* About: Identity change handler module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: handleIdentityChange
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import NodeCache from '@cacheable/node-cache';
|
|
2
14
|
import { areJidsSameUser, getBinaryNodeChild, jidDecode } from '../WABinary/index.js';
|
|
3
15
|
import { isStringNullOrEmpty } from './generics.js';
|
package/lib/Utils/index.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/index.js
|
|
5
|
+
* About: Utils module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: No public exports detected; module side effects or declarations are local.
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
export * from './generics.js';
|
|
2
14
|
export * from './decode-wa-message.js';
|
|
3
15
|
export * from './message-inspect.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/jid-display-normalization.js
|
|
5
|
+
* About: Jid display normalization module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: normalizeMentionedJidsForSend, normalizeMessageForDisplayJids
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { isHostedLidUser, isHostedPnUser, isLidUser, isPnUser, jidDecode } from '../WABinary/index.js';
|
|
2
14
|
|
|
3
15
|
const createLidPnDebug = (logger) => {
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/link-preview.js
|
|
5
|
+
* About: Link preview module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: getUrlInfo
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { prepareWAMessageMedia } from './messages.js';
|
|
2
14
|
import { extractImageThumb, getHttpStream } from './messages-media.js';
|
|
3
15
|
const THUMBNAIL_WIDTH_PX = 192;
|
package/lib/Utils/logger.js
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/logger.js
|
|
5
|
+
* About: Logger module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: No public exports detected; module side effects or declarations are local.
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import P from 'pino';
|
|
2
14
|
export default P({ timestamp: () => `,"time":"${new Date().toJSON()}"` });
|
package/lib/Utils/lt-hash.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/lt-hash.js
|
|
5
|
+
* About: Lt hash module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: LT_HASH_ANTI_TAMPERING
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { LTHashAntiTampering } from 'whatsapp-rust-bridge';
|
|
2
14
|
/**
|
|
3
15
|
* LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data
|
package/lib/Utils/make-mutex.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/make-mutex.js
|
|
5
|
+
* About: Make mutex module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeMutex, makeKeyedMutex
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { Mutex as AsyncMutex } from 'async-mutex';
|
|
2
14
|
export const makeMutex = () => {
|
|
3
15
|
const mutex = new AsyncMutex();
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/message-composer.js
|
|
5
|
+
* About: Message composer module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: generateTableContent, generateListContent, generateCodeBlockContent, generateLatexContent, generateLatexImageContent, generateLatexInlineImageContent, captureUnifiedResponse, generateUnifiedResponseContent; …
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { proto } from '../../WAProto/index.js';
|
|
2
14
|
import { generateMessageIDV2 } from './generics.js';
|
|
3
15
|
|
|
@@ -265,7 +277,12 @@ const buildBotForwardedMessage = (submessages, contextInfo, unifiedResponse) =>
|
|
|
265
277
|
|
|
266
278
|
export const generateTableContent = (title, headers, rows, quoted, options = {}) => {
|
|
267
279
|
const { footer, headerText } = options;
|
|
268
|
-
const
|
|
280
|
+
const safeHeaders = Array.isArray(headers) ? headers.map(String) : [];
|
|
281
|
+
const safeRows = Array.isArray(rows) ? rows : [];
|
|
282
|
+
const tableRows = [
|
|
283
|
+
{ items: safeHeaders, isHeading: true },
|
|
284
|
+
...safeRows.map(row => ({ items: Array.isArray(row) ? row.map(String) : [String(row)] }))
|
|
285
|
+
];
|
|
269
286
|
const submessages = [];
|
|
270
287
|
if (headerText) {
|
|
271
288
|
submessages.push({ messageType: 2, messageText: headerText });
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/message-inspect.js
|
|
5
|
+
* About: Message inspect module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: isScheduledMessage, getScheduledMessageTime, getMessagePaymentInfo, getMessageCommentMetadata, getMessageAddOns, getPollCorrectAnswer, toJid, getSenderLid
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { proto } from '../../WAProto/index.js';
|
|
2
14
|
import { isLidUser, jidEncode } from '../WABinary/index.js';
|
|
3
15
|
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/message-retry-manager.js
|
|
5
|
+
* About: Message retry manager module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: RetryReason, MessageRetryManager
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { LRUCache } from 'lru-cache';
|
|
2
14
|
/** Number of sent messages to cache in memory for handling retry receipts */
|
|
3
15
|
const RECENT_MESSAGES_SIZE = 1024;
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/messages-media.js
|
|
5
|
+
* About: Messages media module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: getImageProcessingLibrary, hkdfInfoKey, getRawMediaUploadData, getMediaKeys, extractVideoThumb, extractImageThumb, encodeBase64EncodedStringForUpload, generateProfilePicture; …
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { Boom } from '@hapi/boom';
|
|
2
14
|
import { spawn } from 'child_process';
|
|
3
15
|
import * as Crypto from 'crypto';
|
package/lib/Utils/messages.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/messages.js
|
|
5
|
+
* About: Messages module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: extractUrlFromText, generateLinkPreviewIfRequired, prepareWAMessageMedia, prepareDisappearingMessageSettingContent, generateForwardMessageContent, hasNonNullishProperty, hasOptionalProperty, hasValidAlbumMedia; …
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { Boom } from '@hapi/boom';
|
|
2
14
|
import { randomBytes } from 'crypto';
|
|
3
15
|
import { zip } from 'fflate';
|
|
@@ -92,6 +104,21 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
92
104
|
if (!uploadData.mimetype) {
|
|
93
105
|
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
94
106
|
}
|
|
107
|
+
if (mediaType === 'sticker') {
|
|
108
|
+
// New compatibility names the native AI-sticker marker `meta`. WhatsApp's
|
|
109
|
+
// current StickerMessage schema exposes this as `isAiSticker`.
|
|
110
|
+
if (hasOptionalProperty(message, 'meta')) {
|
|
111
|
+
uploadData.isAiSticker = !!message.meta;
|
|
112
|
+
delete uploadData.meta;
|
|
113
|
+
}
|
|
114
|
+
// There is no protobuf field literally named `lock`. WhatsApp's
|
|
115
|
+
// compatible native marker for stickers that should not be saved is
|
|
116
|
+
// the avatar-sticker bit, which is what current clients inspect.
|
|
117
|
+
if (hasOptionalProperty(message, 'lock')) {
|
|
118
|
+
uploadData.isAvatar = !!message.lock;
|
|
119
|
+
delete uploadData.lock;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
95
122
|
if (cacheableKey) {
|
|
96
123
|
const mediaBuff = await options.mediaCache.get(cacheableKey);
|
|
97
124
|
if (mediaBuff) {
|
|
@@ -882,6 +909,33 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
882
909
|
m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false;
|
|
883
910
|
m.eventMessage.location = message.event.location;
|
|
884
911
|
}
|
|
912
|
+
else if (hasNonNullishProperty(message, 'imagePoll')) {
|
|
913
|
+
const imagePoll = message.imagePoll;
|
|
914
|
+
if (!Array.isArray(imagePoll.options) || imagePoll.options.length < 2 || imagePoll.options.length > 12) {
|
|
915
|
+
throw new Boom('imagePoll.options must contain between 2 and 12 options', { statusCode: 400 });
|
|
916
|
+
}
|
|
917
|
+
const selectableOptionsCount = imagePoll.selectableCount ?? 1;
|
|
918
|
+
if (selectableOptionsCount < 0 || selectableOptionsCount > imagePoll.options.length) {
|
|
919
|
+
throw new Boom(`imagePoll.selectableCount should be >= 0 and <= ${imagePoll.options.length}`, {
|
|
920
|
+
statusCode: 400
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
m.pollCreationMessageV3 = {
|
|
924
|
+
name: imagePoll.name,
|
|
925
|
+
selectableOptionsCount,
|
|
926
|
+
options: imagePoll.options.map(option => ({
|
|
927
|
+
optionName: option.optionName,
|
|
928
|
+
optionHash: option.optionHash
|
|
929
|
+
})),
|
|
930
|
+
pollContentType: WAProto.Message.PollContentType.IMAGE,
|
|
931
|
+
endTime: imagePoll.endDate ? imagePoll.endDate.getTime() : undefined,
|
|
932
|
+
hideParticipantName: imagePoll.hideVoter ?? false,
|
|
933
|
+
allowAddOption: imagePoll.canAddOption ?? false
|
|
934
|
+
};
|
|
935
|
+
m.messageContextInfo = {
|
|
936
|
+
messageSecret: imagePoll.messageSecret || randomBytes(32)
|
|
937
|
+
};
|
|
938
|
+
}
|
|
885
939
|
else if (hasNonNullishProperty(message, 'poll')) {
|
|
886
940
|
(_a = message.poll).selectableCount || (_a.selectableCount = 0);
|
|
887
941
|
(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false);
|
|
@@ -1390,7 +1444,7 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1390
1444
|
throw new Boom('Invalid media type for carousel card', { statusCode: 400 });
|
|
1391
1445
|
}
|
|
1392
1446
|
const carouselCard = {
|
|
1393
|
-
nativeFlowMessage: prepareNativeFlowButtons({
|
|
1447
|
+
nativeFlowMessage: card.nativeFlowMessage || prepareNativeFlowButtons({
|
|
1394
1448
|
...card,
|
|
1395
1449
|
nativeFlow: card.nativeFlow || card.buttons || []
|
|
1396
1450
|
}),
|
|
@@ -1429,8 +1483,8 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1429
1483
|
messageVersion: 1
|
|
1430
1484
|
}
|
|
1431
1485
|
};
|
|
1432
|
-
if (hasOptionalProperty(message, 'text')) {
|
|
1433
|
-
interactiveMessage.body = { text: message.text };
|
|
1486
|
+
if (hasOptionalProperty(message, 'text') || hasOptionalProperty(message, 'content')) {
|
|
1487
|
+
interactiveMessage.body = { text: message.text ?? message.content };
|
|
1434
1488
|
}
|
|
1435
1489
|
if (hasOptionalProperty(message, 'footer')) {
|
|
1436
1490
|
interactiveMessage.footer = { text: message.footer };
|
|
@@ -1550,6 +1604,10 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1550
1604
|
if (hasOptionalProperty(message, 'groupStatus') && !!message.groupStatus) {
|
|
1551
1605
|
const messageType = Object.keys(m)[0];
|
|
1552
1606
|
const key = m[messageType];
|
|
1607
|
+
const privateAudience = message.private;
|
|
1608
|
+
if (privateAudience !== undefined && (privateAudience === null || typeof privateAudience !== 'object' || Array.isArray(privateAudience))) {
|
|
1609
|
+
throw new Boom('groupStatus private metadata must be an object', { statusCode: 400 });
|
|
1610
|
+
}
|
|
1553
1611
|
if (key && 'contextInfo' in key && !!key.contextInfo) {
|
|
1554
1612
|
key.contextInfo.isGroupStatus = message.groupStatus;
|
|
1555
1613
|
}
|
|
@@ -1558,8 +1616,32 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1558
1616
|
isGroupStatus: message.groupStatus
|
|
1559
1617
|
};
|
|
1560
1618
|
}
|
|
1561
|
-
|
|
1619
|
+
if (privateAudience && (privateAudience.name != null || privateAudience.emoji != null)) {
|
|
1620
|
+
const name = privateAudience.name == null ? '' : String(privateAudience.name);
|
|
1621
|
+
const emoji = privateAudience.emoji == null ? '' : String(privateAudience.emoji);
|
|
1622
|
+
if (!name && !emoji) {
|
|
1623
|
+
throw new Boom('groupStatus private metadata requires a name or emoji', { statusCode: 400 });
|
|
1624
|
+
}
|
|
1625
|
+
const statusMessage = m[Object.keys(m)[0]];
|
|
1626
|
+
statusMessage.contextInfo = {
|
|
1627
|
+
...(statusMessage.contextInfo || {}),
|
|
1628
|
+
statusAudienceMetadata: {
|
|
1629
|
+
audienceType: proto.ContextInfo.StatusAudienceMetadata.AudienceType.CLOSE_FRIENDS,
|
|
1630
|
+
...(name ? { listName: name } : {}),
|
|
1631
|
+
...(emoji ? { listEmoji: emoji } : {})
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
// V2 remains the default. The legacy envelope is available for
|
|
1636
|
+
// compatibility testing with clients that still handle the two
|
|
1637
|
+
// group-status fields differently.
|
|
1638
|
+
const groupStatusVersion = message.groupStatusVersion || options?.groupStatusVersion;
|
|
1639
|
+
m = groupStatusVersion === 'legacy' || groupStatusVersion === 'v1'
|
|
1640
|
+
? { groupStatusMessage: { message: m } }
|
|
1641
|
+
: { groupStatusMessageV2: { message: m } };
|
|
1562
1642
|
delete message.groupStatus;
|
|
1643
|
+
delete message.groupStatusVersion;
|
|
1644
|
+
delete message.private;
|
|
1563
1645
|
}
|
|
1564
1646
|
// Media spoiler support uses WhatsApp's FutureProofMessage spoiler envelope plus
|
|
1565
1647
|
// contextInfo.isSpoiler. Text spoilers use ||...|| by default because native text
|
|
@@ -1790,6 +1872,152 @@ export const generateWAMessage = async (jid, content, options) => {
|
|
|
1790
1872
|
}
|
|
1791
1873
|
return generateWAMessageFromContent(jid, await generateWAMessageContent(content, options), options);
|
|
1792
1874
|
};
|
|
1875
|
+
/**
|
|
1876
|
+
* Hashes an image-poll option as SHA-256(SHA-256(option name) + base64(file SHA-256)).
|
|
1877
|
+
* This follows the WhatsApp Web image-poll format; the format remains experimental.
|
|
1878
|
+
*/
|
|
1879
|
+
export const hashImagePollOption = (optionName, fileSha256) => {
|
|
1880
|
+
const nameHash = sha256(Buffer.from(String(optionName), 'utf-8')).toString('hex');
|
|
1881
|
+
const mediaHash = fileSha256 ? Buffer.from(fileSha256).toString('base64') : '';
|
|
1882
|
+
return sha256(Buffer.from(nameHash + mediaHash, 'utf-8')).toString('hex');
|
|
1883
|
+
};
|
|
1884
|
+
/**
|
|
1885
|
+
* Sends a photo poll as one poll-creation message followed by associated image child messages.
|
|
1886
|
+
* `relay` receives `(message, relayOptions, webMessageInfo)` for each wire message.
|
|
1887
|
+
*/
|
|
1888
|
+
export const generateWAMessageFromImagePoll = async (jid, content, relay, options = {}) => {
|
|
1889
|
+
if (typeof relay !== 'function') {
|
|
1890
|
+
throw new Boom('image poll requires a relay callback', { statusCode: 400 });
|
|
1891
|
+
}
|
|
1892
|
+
if (!Array.isArray(content?.values) || content.values.length < 2 || content.values.length > 12) {
|
|
1893
|
+
throw new Boom('image poll requires between 2 and 12 values', { statusCode: 400 });
|
|
1894
|
+
}
|
|
1895
|
+
if (content.values.some(value => value && typeof value === 'object' && value.image) && typeof options.upload !== 'function') {
|
|
1896
|
+
throw new Boom('image poll requires a configured media uploader', { statusCode: 400 });
|
|
1897
|
+
}
|
|
1898
|
+
const prepared = [];
|
|
1899
|
+
const pollOptions = [];
|
|
1900
|
+
for (const value of content.values) {
|
|
1901
|
+
const option = typeof value === 'string' ? { name: value } : value;
|
|
1902
|
+
const optionName = option?.name ?? option?.optionName;
|
|
1903
|
+
if (typeof optionName !== 'string' || !optionName.trim()) {
|
|
1904
|
+
throw new Boom('Each image poll value must have a non-empty name', { statusCode: 400 });
|
|
1905
|
+
}
|
|
1906
|
+
let media;
|
|
1907
|
+
if (option.image) {
|
|
1908
|
+
media = await prepareWAMessageMedia({ image: option.image }, { ...options, jid });
|
|
1909
|
+
}
|
|
1910
|
+
prepared.push({ media });
|
|
1911
|
+
pollOptions.push({
|
|
1912
|
+
optionName,
|
|
1913
|
+
optionHash: hashImagePollOption(optionName, media?.imageMessage?.fileSha256)
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1916
|
+
if (!prepared.some(({ media }) => media)) {
|
|
1917
|
+
throw new Boom('At least one image poll option must include an image', { statusCode: 400 });
|
|
1918
|
+
}
|
|
1919
|
+
const pollMessageContent = await generateWAMessageContent({
|
|
1920
|
+
imagePoll: {
|
|
1921
|
+
name: content.name,
|
|
1922
|
+
selectableCount: content.selectableCount ?? 1,
|
|
1923
|
+
options: pollOptions,
|
|
1924
|
+
endDate: content.endDate,
|
|
1925
|
+
hideVoter: content.hideVoter,
|
|
1926
|
+
canAddOption: content.canAddOption,
|
|
1927
|
+
messageSecret: content.messageSecret
|
|
1928
|
+
}
|
|
1929
|
+
}, { ...options, jid });
|
|
1930
|
+
const poll = generateWAMessageFromContent(jid, pollMessageContent, { ...options, jid });
|
|
1931
|
+
const pollMeta = {
|
|
1932
|
+
tag: 'meta',
|
|
1933
|
+
attrs: {
|
|
1934
|
+
polltype: 'creation',
|
|
1935
|
+
contenttype: isJidNewsletter(jid) ? 'image' : undefined
|
|
1936
|
+
},
|
|
1937
|
+
content: undefined
|
|
1938
|
+
};
|
|
1939
|
+
await relay(poll.message, {
|
|
1940
|
+
messageId: poll.key.id,
|
|
1941
|
+
additionalNodes: [...(options.additionalNodes || []), pollMeta]
|
|
1942
|
+
}, poll);
|
|
1943
|
+
for (let index = 0; index < prepared.length; index++) {
|
|
1944
|
+
const media = prepared[index].media;
|
|
1945
|
+
if (!media) continue;
|
|
1946
|
+
const optionMessage = proto.Message.fromObject({
|
|
1947
|
+
pollCreationOptionImageMessage: { message: media },
|
|
1948
|
+
messageContextInfo: {
|
|
1949
|
+
messageAssociation: {
|
|
1950
|
+
associationType: proto.MessageAssociation.AssociationType.MEDIA_POLL,
|
|
1951
|
+
parentMessageKey: poll.key
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
});
|
|
1955
|
+
const option = generateWAMessageFromContent(jid, optionMessage, { ...options, jid, messageId: undefined });
|
|
1956
|
+
await relay(option.message, { messageId: option.key.id }, option);
|
|
1957
|
+
}
|
|
1958
|
+
return poll;
|
|
1959
|
+
};
|
|
1960
|
+
/**
|
|
1961
|
+
* Sends a motion photo as an image parent followed by an associated video child.
|
|
1962
|
+
* The static image may be supplied as `image` or `thumbnail`; otherwise the
|
|
1963
|
+
* prepared video thumbnail is used as the still image.
|
|
1964
|
+
*/
|
|
1965
|
+
export const generateWAMessageFromLivePhoto = async (jid, content, relay, options = {}) => {
|
|
1966
|
+
if (typeof relay !== 'function') {
|
|
1967
|
+
throw new Boom('live photo requires a relay callback', { statusCode: 400 });
|
|
1968
|
+
}
|
|
1969
|
+
if (!content?.video) {
|
|
1970
|
+
throw new Boom('live photo requires a video source', { statusCode: 400 });
|
|
1971
|
+
}
|
|
1972
|
+
const normalizeMedia = media => typeof media === 'string' ? { url: media } : media;
|
|
1973
|
+
const offset = content.motionPhotoPresentationOffsetMs ?? content.presentationOffsetMs;
|
|
1974
|
+
if (offset != null && (!Number.isSafeInteger(Number(offset)) || Number(offset) < 0)) {
|
|
1975
|
+
throw new Boom('motionPhotoPresentationOffsetMs must be a non-negative integer', { statusCode: 400 });
|
|
1976
|
+
}
|
|
1977
|
+
const video = await prepareWAMessageMedia({
|
|
1978
|
+
video: normalizeMedia(content.video),
|
|
1979
|
+
...(content.videoMimetype ? { mimetype: content.videoMimetype } : {}),
|
|
1980
|
+
...(content.videoThumbnail ? { jpegThumbnail: content.videoThumbnail } : {}),
|
|
1981
|
+
...(offset != null ? { motionPhotoPresentationOffsetMs: Number(offset) } : {})
|
|
1982
|
+
}, { ...options, jid });
|
|
1983
|
+
const videoMessage = video?.videoMessage;
|
|
1984
|
+
if (!videoMessage) {
|
|
1985
|
+
throw new Boom('live photo video could not be prepared', { statusCode: 400 });
|
|
1986
|
+
}
|
|
1987
|
+
const still = content.image || content.thumbnail || videoMessage.jpegThumbnail;
|
|
1988
|
+
if (!still) {
|
|
1989
|
+
throw new Boom('live photo needs a still image or a video with an extractable thumbnail', { statusCode: 400 });
|
|
1990
|
+
}
|
|
1991
|
+
const parent = await generateWAMessage(jid, {
|
|
1992
|
+
image: normalizeMedia(still),
|
|
1993
|
+
caption: content.caption ?? content.text ?? '',
|
|
1994
|
+
...(!content.image && !content.thumbnail && videoMessage.jpegThumbnail
|
|
1995
|
+
? { jpegThumbnail: videoMessage.jpegThumbnail }
|
|
1996
|
+
: content.imageThumbnail ? { jpegThumbnail: content.imageThumbnail } : {})
|
|
1997
|
+
}, { ...options, jid });
|
|
1998
|
+
const childContent = proto.Message.fromObject({
|
|
1999
|
+
videoMessage: {
|
|
2000
|
+
...videoMessage,
|
|
2001
|
+
...(offset != null ? { motionPhotoPresentationOffsetMs: Number(offset) } : {})
|
|
2002
|
+
},
|
|
2003
|
+
messageContextInfo: {
|
|
2004
|
+
messageAssociation: {
|
|
2005
|
+
associationType: proto.MessageAssociation.AssociationType.MOTION_PHOTO,
|
|
2006
|
+
parentMessageKey: parent.key
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
});
|
|
2010
|
+
const { quoted: _quoted, ...childOptions } = options;
|
|
2011
|
+
const child = generateWAMessageFromContent(jid, childContent, {
|
|
2012
|
+
...childOptions,
|
|
2013
|
+
jid,
|
|
2014
|
+
messageId: undefined
|
|
2015
|
+
});
|
|
2016
|
+
const relayOptions = options.relayOptions || {};
|
|
2017
|
+
await relay(parent.message, { ...relayOptions, messageId: parent.key.id }, parent);
|
|
2018
|
+
await relay(child.message, { ...relayOptions, messageId: child.key.id }, child);
|
|
2019
|
+
return parent;
|
|
2020
|
+
};
|
|
1793
2021
|
/** Get the key to access the true type of content */
|
|
1794
2022
|
export const getContentType = (content) => {
|
|
1795
2023
|
if (content) {
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/meta-ai-msmsg.js
|
|
5
|
+
* About: Meta ai msmsg module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: decryptMsmsgBotMessage, parseUnifiedResponseData, textFromUnifiedResponse, textFromRichResponse, extractMetaAiText, decodeUnifiedResponseInPlace, decodeDecryptedMsmsgMessage
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { proto } from '../../WAProto/index.js';
|
|
2
14
|
import { aesDecryptGCM, hkdf } from './crypto.js';
|
|
3
15
|
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Utils/meta-compositing.js
|
|
5
|
+
* About: Meta compositing module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: PlanningStepStatus, supportsMetaRendering, buildProgressIndicator, buildCompositingPlaceholder, buildPlainPlaceholder, metaTyping, editMetaMessage, sendMetaComposited; …
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
/**
|
|
2
14
|
* Lia@Changes [WIP]
|
|
3
15
|
* Meta Compositing — send rich messages with Meta AI-style progress indicator.
|