diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..7a73a815 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,5 +1,5 @@ --- -name: Feature request +name: Feature request, suggest about: Suggest an idea for this project title: '' labels: '' diff --git a/.gitignore b/.gitignore index c9d07c19..1eebf5b5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ guru.data.json database.json .env session -tmp \ No newline at end of file +tmp diff --git a/.gitignore.js b/.gitignore.js index 4ec245a1..26480755 100644 --- a/.gitignore.js +++ b/.gitignore.js @@ -7,7 +7,7 @@ yarn-error.log* lerna-debug.log* .pnpm-debug.log* -# Diagnostic reports (https://nodejs.org/api/report.html) +# Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json # Runtime data diff --git a/Assets/20240302_120657.jpg b/Assets/20240302_120657.jpg deleted file mode 100644 index 69566cc6..00000000 Binary files a/Assets/20240302_120657.jpg and /dev/null differ diff --git a/Assets/Star.html b/Assets/Star.html new file mode 100644 index 00000000..980eaf83 --- /dev/null +++ b/Assets/Star.html @@ -0,0 +1,75 @@ + + + + + + GURU-BOT Status + + + +
STAR-MD-V2 Online
+ + \ No newline at end of file diff --git a/Assets/XLICON.js b/Assets/XLICON.js index 41ac3b20..ae94bfe5 100644 --- a/Assets/XLICON.js +++ b/Assets/XLICON.js @@ -1,4 +1,4 @@ /** - * @XLICON_V2 - * https://github.com/salmanytofficial/XLICON-V2-MD + * @STAR_V2 + * https://github.com/Xcelsama/STAR-MD-V2 */ \ No newline at end of file diff --git a/Assets/mp3/STAR.mp3 b/Assets/mp3/STAR.mp3 new file mode 100644 index 00000000..26f80410 Binary files /dev/null and b/Assets/mp3/STAR.mp3 differ diff --git a/Assets/mp3/STAR1.mp3 b/Assets/mp3/STAR1.mp3 new file mode 100644 index 00000000..2421c4a7 Binary files /dev/null and b/Assets/mp3/STAR1.mp3 differ diff --git a/Assets/mp3/STAR2.mp3 b/Assets/mp3/STAR2.mp3 new file mode 100644 index 00000000..51a3ebc5 Binary files /dev/null and b/Assets/mp3/STAR2.mp3 differ diff --git a/Assets/mp3/STAR3.mp3 b/Assets/mp3/STAR3.mp3 new file mode 100644 index 00000000..5a0deecd Binary files /dev/null and b/Assets/mp3/STAR3.mp3 differ diff --git a/Assets/mp3/STAR4.mp3 b/Assets/mp3/STAR4.mp3 new file mode 100644 index 00000000..e9500a2c Binary files /dev/null and b/Assets/mp3/STAR4.mp3 differ diff --git a/Assets/mp3/Xlicon.mp3 b/Assets/mp3/Xlicon.mp3 deleted file mode 100644 index b0c71374..00000000 Binary files a/Assets/mp3/Xlicon.mp3 and /dev/null differ diff --git a/Assets/mp3/Xlicon1.mp3 b/Assets/mp3/Xlicon1.mp3 deleted file mode 100644 index 75b3aef4..00000000 Binary files a/Assets/mp3/Xlicon1.mp3 and /dev/null differ diff --git a/Assets/mp3/Xlicon2.mp3 b/Assets/mp3/Xlicon2.mp3 deleted file mode 100644 index 7ea1efd5..00000000 Binary files a/Assets/mp3/Xlicon2.mp3 and /dev/null differ diff --git a/Assets/mp3/Xlicon3.mp3 b/Assets/mp3/Xlicon3.mp3 deleted file mode 100644 index 2874a113..00000000 Binary files a/Assets/mp3/Xlicon3.mp3 and /dev/null differ diff --git a/Assets/mp3/Xlicon4.mp3 b/Assets/mp3/Xlicon4.mp3 deleted file mode 100644 index c897b946..00000000 Binary files a/Assets/mp3/Xlicon4.mp3 and /dev/null differ diff --git a/Assets/mp3/excel b/Assets/mp3/excel new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/Assets/mp3/excel @@ -0,0 +1 @@ + diff --git a/CODEOWNERS b/CODEOWNERS index 7e39cbc7..84c46661 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,4 @@ -# These owners will be the default owners for everything + # These owners will be the default owners for everything #in the repo. @Guru322 diff --git a/Dockerfile b/Dockerfile index 2e404d96..94f49115 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:lts-buster + FROM node:lts-buster RUN apt-get update && \ apt-get install -y \ diff --git a/GURU-Bing.js b/GURU-Bing.js index d3a0eb7c..87f940b7 100644 --- a/GURU-Bing.js +++ b/GURU-Bing.js @@ -1 +1 @@ -const _0x41aff2=_0x2490;(function(_0x17406c,_0x5b26ba){const _0x566e1f=_0x2490,_0x5c0c81=_0x17406c();while(!![]){try{const _0x45f945=parseInt(_0x566e1f(0xeb))/0x1*(parseInt(_0x566e1f(0xe3))/0x2)+-parseInt(_0x566e1f(0xfd))/0x3*(-parseInt(_0x566e1f(0xfb))/0x4)+-parseInt(_0x566e1f(0xec))/0x5*(-parseInt(_0x566e1f(0xf2))/0x6)+parseInt(_0x566e1f(0xed))/0x7*(parseInt(_0x566e1f(0xe5))/0x8)+-parseInt(_0x566e1f(0xf5))/0x9+-parseInt(_0x566e1f(0x106))/0xa*(-parseInt(_0x566e1f(0xfa))/0xb)+-parseInt(_0x566e1f(0xe8))/0xc;if(_0x45f945===_0x5b26ba)break;else _0x5c0c81['push'](_0x5c0c81['shift']());}catch(_0x3de7b1){_0x5c0c81['push'](_0x5c0c81['shift']());}}}(_0x3a5c,0xd2203));import _0xdc1d7f from'node-fetch';let handler=async(_0x15d4c8,{conn:_0x1013c6,args:_0x1a5fed,usedPrefix:_0xd3a9dd,command:_0x4f76ca,text:_0x10cf96})=>{const _0x39c225=_0x2490,_0x4ea5c1={'AgpSH':_0x39c225(0xf9),'LblMr':function(_0x5c93e7,_0x4b550c){return _0x5c93e7(_0x4b550c);},'DrpsB':'No\x20valid\x20JSON\x20response\x20from\x20Bing\x20'};if(!_0x10cf96&&!(_0x15d4c8[_0x39c225(0xf4)]&&_0x15d4c8[_0x39c225(0xf4)][_0x39c225(0xee)]))throw'Please\x20provide\x20some\x20text\x20or\x20quote\x20a\x20message\x20to\x20get\x20a\x20response.';!_0x10cf96&&_0x15d4c8[_0x39c225(0xf4)]&&_0x15d4c8[_0x39c225(0xf4)][_0x39c225(0xee)]&&(_0x10cf96=_0x15d4c8['quoted'][_0x39c225(0xee)]);_0x15d4c8[_0x39c225(0xff)](_0x4ea5c1[_0x39c225(0xea)]),_0x15d4c8['react']('๐Ÿค”');const _0x18e5b9=_0x4ea5c1[_0x39c225(0xf6)](encodeURIComponent,_0x10cf96);let _0x902291=await _0x4ea5c1[_0x39c225(0xf6)](Bing,_0x18e5b9);if(!_0x902291)throw new Error(_0x4ea5c1[_0x39c225(0xf1)]);await _0x1013c6[_0x39c225(0xff)](_0x15d4c8[_0x39c225(0x104)],_0x902291,_0x15d4c8);};function _0x2490(_0x3de1ad,_0x46bd4f){const _0x3a5c4d=_0x3a5c();return _0x2490=function(_0x24907b,_0x1537f0){_0x24907b=_0x24907b-0xe1;let _0x167307=_0x3a5c4d[_0x24907b];return _0x167307;},_0x2490(_0x3de1ad,_0x46bd4f);}handler['help']=[_0x41aff2(0xe4)],handler[_0x41aff2(0xe7)]=['AI'],handler[_0x41aff2(0xef)]=/^(bing)$/i;export default handler;function _0x3a5c(){const _0x52cbe0=['rPqWb','964870SXXJHb','POST','wTiLY','298kvIdQp','bing','75808MHvLpa','sseCS','tags','34580076yEaiVp','system','AgpSH','6607aTUqaY','4682035YwUejm','1127rnFKgh','text','command','https://copilot.github1s.tk/v1/chat/completions','DrpsB','6EtTStg','Creative','quoted','12188214KWLteA','LblMr','user','dummy','Waiting\x20Response\x20from\x20Guru\x20Bot\x20server...','77nXEdni','354436JVuREI','content','33YQoTtz','application/json','reply','lVgli','You\x20are\x20an\x20helpful\x20assistant.','stringify','message','chat'];_0x3a5c=function(){return _0x52cbe0;};return _0x3a5c();}async function Bing(_0x494d12){const _0x6a60db=_0x41aff2,_0x16f4ca={'ZBJmj':_0x6a60db(0xf0),'bOYZd':_0x6a60db(0xe1),'wTiLY':_0x6a60db(0xf8),'sseCS':_0x6a60db(0xfe),'rPqWb':_0x6a60db(0xf3),'lVgli':_0x6a60db(0xe9),'uqaRC':_0x6a60db(0x101)};let _0x4a9f6b=await(await _0xdc1d7f(_0x16f4ca['ZBJmj'],{'method':_0x16f4ca['bOYZd'],'headers':{'Authorization':_0x16f4ca[_0x6a60db(0xe2)],'Content-Type':_0x16f4ca[_0x6a60db(0xe6)]},'body':JSON[_0x6a60db(0x102)]({'model':_0x16f4ca[_0x6a60db(0x105)],'max_tokens':0x64,'messages':[{'role':_0x16f4ca[_0x6a60db(0x100)],'content':_0x16f4ca['uqaRC']},{'role':_0x6a60db(0xf7),'content':_0x494d12}]})}))['json']();return _0x4a9f6b['choices'][0x0][_0x6a60db(0x103)][_0x6a60db(0xfc)];} +const _0x41aff2=_0x2490;(function(_0x17406c,_0x5b26ba){const _0x566e1f=_0x2490,_0x5c0c81=_0x17406c();while(!![]){try{const _0x45f945=parseInt(_0x566e1f(0xeb))/0x1*(parseInt(_0x566e1f(0xe3))/0x2)+-parseInt(_0x566e1f(0xfd))/0x3*(-parseInt(_0x566e1f(0xfb))/0x4)+-parseInt(_0x566e1f(0xec))/0x5*(-parseInt(_0x566e1f(0xf2))/0x6)+parseInt(_0x566e1f(0xed))/0x7*(parseInt(_0x566e1f(0xe5))/0x8)+-parseInt(_0x566e1f(0xf5))/0x9+-parseInt(_0x566e1f(0x106))/0xa*(-parseInt(_0x566e1f(0xfa))/0xb)+-parseInt(_0x566e1f(0xe8))/0xc;if(_0x45f945===_0x5b26ba)break;else _0x5c0c81['push'](_0x5c0c81['shift']());}catch(_0x3de7b1){_0x5c0c81['push'](_0x5c0c81['shift']());}}}(_0x3a5c,0xd2203));import _0xdc1d7f from'node-fetch';let handler=async(_0x15d4c8,{conn:_0x1013c6,args:_0x1a5fed,usedPrefix:_0xd3a9dd,command:_0x4f76ca,text:_0x10cf96})=>{const _0x39c225=_0x2490,_0x4ea5c1={'AgpSH':_0x39c225(0xf9),'LblMr':function(_0x5c93e7,_0x4b550c){return _0x5c93e7(_0x4b550c);},'DrpsB':'No\x20valid\x20JSON\x20response\x20from\x20Bing\x20'};if(!_0x10cf96&&!(_0x15d4c8[_0x39c225(0xf4)]&&_0x15d4c8[_0x39c225(0xf4)][_0x39c225(0xee)]))throw'Please\x20provide\x20some\x20text\x20or\x20quote\x20a\x20message\x20to\x20get\x20a\x20response.';!_0x10cf96&&_0x15d4c8[_0x39c225(0xf4)]&&_0x15d4c8[_0x39c225(0xf4)][_0x39c225(0xee)]&&(_0x10cf96=_0x15d4c8['quoted'][_0x39c225(0xee)]);_0x15d4c8[_0x39c225(0xff)](_0x4ea5c1[_0x39c225(0xea)]),_0x15d4c8['react']('๐Ÿค“');const _0x18e5b9=_0x4ea5c1[_0x39c225(0xf6)](encodeURIComponent,_0x10cf96);let _0x902291=await _0x4ea5c1[_0x39c225(0xf6)](Bing,_0x18e5b9);if(!_0x902291)throw new Error(_0x4ea5c1[_0x39c225(0xf1)]);await _0x1013c6[_0x39c225(0xff)](_0x15d4c8[_0x39c225(0x104)],_0x902291,_0x15d4c8);};function _0x2490(_0x3de1ad,_0x46bd4f){const _0x3a5c4d=_0x3a5c();return _0x2490=function(_0x24907b,_0x1537f0){_0x24907b=_0x24907b-0xe1;let _0x167307=_0x3a5c4d[_0x24907b];return _0x167307;},_0x2490(_0x3de1ad,_0x46bd4f);}handler['help']=[_0x41aff2(0xe4)],handler[_0x41aff2(0xe7)]=['AI'],handler[_0x41aff2(0xef)]=/^(bing)$/i;export default handler;function _0x3a5c(){const _0x52cbe0=['rPqWb','964870SXXJHb','POST','wTiLY','298kvIdQp','bing','75808MHvLpa','sseCS','tags','34580076yEaiVp','system','AgpSH','6607aTUqaY','4682035YwUejm','1127rnFKgh','text','command','https://copilot.github1s.tk/v1/chat/completions','DrpsB','6EtTStg','Creative','quoted','12188214KWLteA','LblMr','user','dummy','Waiting\x20Response\x20from\x20Guru\x20Bot\x20server...','77nXEdni','354436JVuREI','content','33YQoTtz','application/json','reply','lVgli','You\x20are\x20an\x20helpful\x20assistant.','stringify','message','chat'];_0x3a5c=function(){return _0x52cbe0;};return _0x3a5c();}async function Bing(_0x494d12){const _0x6a60db=_0x41aff2,_0x16f4ca={'ZBJmj':_0x6a60db(0xf0),'bOYZd':_0x6a60db(0xe1),'wTiLY':_0x6a60db(0xf8),'sseCS':_0x6a60db(0xfe),'rPqWb':_0x6a60db(0xf3),'lVgli':_0x6a60db(0xe9),'uqaRC':_0x6a60db(0x101)};let _0x4a9f6b=await(await _0xdc1d7f(_0x16f4ca['ZBJmj'],{'method':_0x16f4ca['bOYZd'],'headers':{'Authorization':_0x16f4ca[_0x6a60db(0xe2)],'Content-Type':_0x16f4ca[_0x6a60db(0xe6)]},'body':JSON[_0x6a60db(0x102)]({'model':_0x16f4ca[_0x6a60db(0x105)],'max_tokens':0x64,'messages':[{'role':_0x16f4ca[_0x6a60db(0x100)],'content':_0x16f4ca['uqaRC']},{'role':_0x6a60db(0xf7),'content':_0x494d12}]})}))['json']();return _0x4a9f6b['choices'][0x0][_0x6a60db(0x103)][_0x6a60db(0xfc)];} diff --git a/Guru.js b/Guru.js index 906c802f..6a60321f 100644 --- a/Guru.js +++ b/Guru.js @@ -1 +1,583 @@ -const _0x374239=_0x4b29;(function(_0xe49a30,_0x2d13fe){const _0x57d570=_0x4b29,_0x2d5b05=_0xe49a30();while(!![]){try{const _0x21ae1f=-parseInt(_0x57d570(0x286))/0x1*(-parseInt(_0x57d570(0x1b7))/0x2)+parseInt(_0x57d570(0x1db))/0x3*(parseInt(_0x57d570(0x1e8))/0x4)+-parseInt(_0x57d570(0x1ca))/0x5*(-parseInt(_0x57d570(0x25d))/0x6)+-parseInt(_0x57d570(0x1f5))/0x7+parseInt(_0x57d570(0x239))/0x8*(-parseInt(_0x57d570(0x28a))/0x9)+parseInt(_0x57d570(0x26f))/0xa+parseInt(_0x57d570(0x20b))/0xb*(-parseInt(_0x57d570(0x1ef))/0xc);if(_0x21ae1f===_0x2d13fe)break;else _0x2d5b05['push'](_0x2d5b05['shift']());}catch(_0x1d5f1b){_0x2d5b05['push'](_0x2d5b05['shift']());}}}(_0x2e13,0x8c2b2),process[_0x374239(0x207)][_0x374239(0x1c7)]='0');import'./config.js';import{createRequire}from'module';import _0x2e740d,{join}from'path';import{fileURLToPath,pathToFileURL}from'url';function _0x2e13(){const _0x3881bd=['replace','./plugins/index','message','pollUpdate','removeAllListeners','freeze','__filename','level','6bzppUh','redBright','connectionUpdate','requestPairingCode','from','payload','test','localeCompare','sSubject','?update=','Hai๐Ÿคฉ','handler','greenBright','Start\x20with\x20your\x20country\x27s\x20WhatsApp\x20code,\x20Example\x2062xxx','plugins','reset','Environment\x20variable\x20not\x20found.','stdin','10150140sRApnZ','\x20\x20\x20','output','๐Ÿ“จ\x20','spromote','An\x20error\x20occurred\x20during\x20temporary\x20file\x20cleanup:','exit','argv','sms','isInit','server','E.164','isChats','loggedOut','cyan','socket','\x0aconnection\x20closed....\x20Trying\x20to\x20Restart','log','filter','sRestrictOff','support','__dirname','opts','3731gfbgay','toLowerCase','APIKeys','ffprobe','18531Nnwgef','https://guruapi.tech/api','endsWith','win32','welcome','loadDatabase','database.json','creds.update','registered','\x20The\x20group\x20icon\x20has\x20been\x20updated!','bye','pre-key-','*@user*\x20has\x20been\x20promoted\x20to\x20an\x20admin!','chain','phoneNumberMobileCountryCode','PORT','sendMessage','PREFIX','API','createInterface','message.delete','subject','APIs','./session','package.json','\x0a๐Ÿšฉ\x20R\x20E\x20A\x20D\x20Y','connection.update','messages.upsert','statusCode','\x20The\x20group\x20is\x20now\x20*OPEN*!\x0aAll\x20participants\x20can\x20send\x20messages.','close','Error:','question',',\x22time\x22:\x22','match','๐Ÿ–ผ๏ธ','*@user*\x20is\x20no\x20longer\x20an\x20admin.','./session/','582Cdxoxd','read','--pairing-code','exitProcess','now','demote','--mobile','bold','promote','--qr','creds','forEach','-\x20Code','tmp','off','join','NODE_TLS_REJECT_UNAUTHORIZED','toJSON','-filter_complex','4432605OcKprw','@g.us','webp','error','name','announceOff','send','some','color','loadMessage','fatal','\x0aStored\x20Sessions\x20Cleared\x20โœ…','icon','\x0aNew\x20plugin\x20-\x20\x27','trim','sAnnounceOff','trace','6306uEwKbK','length','author','restrictOn','nationalNumber','\x0aFailed\x20to\x20register\x20your\x20phone\x20number.\x20Please\x20try\x20again.\x0a','write','prefix','toString','Cannot\x20use\x20pairing\x20code\x20with\x20mobile\x20api','restrictOff','-type','data','1468ozJlZY','ffmpeg','sort','revoke','./server.js','--version','reload','132WyuXmz','\x20The\x20group\x20is\x20now\x20*CLOSED*!\x0aOnly\x20admins\x20can\x20send\x20messages.','conn','autocleartmp','session','stdout','936999jKgotA','Please\x20type\x20your\x20WhatsApp\x20number\x20:\x20','Temporary\x20file\x20cleanup\x20completed.','readFromFile','tmpdir','open','\x0aError\x20require\x20plugin\x20\x27','authState','yellow','url','parse','logger','๐Ÿ‘ค๐Ÿ‘‘','\x0aLogging\x20in....','group-participants.update','\x20Hello\x20@user!\x0a\x0a๐ŸŽ‰\x20*WELCOME*\x20to\x20the\x20group\x20@group!\x0a\x0a๐Ÿ“œ\x20Please\x20read\x20the\x20*DESCRIPTION*\x20@desc.','initializing\x20Guru\x20Bot','SESSION_ID','env','\x0aUpdated\x20plugin\x20-\x20\x27','phoneNumber','countryCallingCode','1967669bZgljs','-\x20Number','authFolder','func','catch','\x20Congrats\x20you\x20have\x20successfully\x20deployed\x20XLICON-BOT\x0aJoin\x20my\x20support\x20Group\x20for\x20any\x20Query\x0a\x20https://chat.whatsapp.com/Kchd5WS2UmILfGEP523DqL','dirname','Q2hlYXAgQ29weSBPZiBHdXJ1IEJvdCBGb3VuZCAsIFBsZWFzZSBVc2UgdGhlIE9yaWdpbmFsIEd1cnUgQm90IEZyb20gaHR0cHM6Ly9naXRodWIuY29tL0d1cnUzMjIvR1VSVS1CT1QK','presenceUpdate','all','\x0aInvalid\x20phone\x20number:\x20','Start\x20with\x20your\x20country\x27s\x20WhatsApp\x20code,\x20Example\x20:\x2062xxx','desc','default','requestRegistrationCode','phoneNumberNationalNumber','-loglevel','./handler.js','child','__require','info','keys','-hide_banner','bgBlack','onDelete','READ','๐Ÿ‘‹\x20GOODBYE\x20@user\x20','chats','participantsUpdate','uncaughtException','map','-amin','\x0aDeleted\x20plugin\x20-\x20\x27','reloadHandler','pairingNumber','fromEntries','phoneNumberCountryCode','bind','convert','race','-frames:v','DATABASE_URL','timestamp','๐Ÿ‘ค๐Ÿ™…โ€โ™‚๏ธ','warn','SERVER_PORT','4208ErJGfs','messages.update','Please\x20Enter\x20Your\x20OTP\x20Code','presence.update','groupsUpdate','startsWith','Successfully\x20registered\x20your\x20phone\x20number.','sDesc','groups.update','then','slice','sRevoke','magick','entries','voice','Please\x20type\x20your\x20WhatsApp\x20number','\x20The\x20group\x20description\x20has\x20been\x20updated\x20to:\x0a@desc','\x20The\x20group\x20title\x20has\x20been\x20changed\x20to:\x0a@group','\x20Edit\x20Group\x20Info\x20has\x20been\x20restricted\x20to\x20admins\x20only!','Z3VydQ==','sRestrictOn','find','credsUpdate','spawn','base64','register','includes','@whiskeysockets/baileys'];_0x2e13=function(){return _0x3881bd;};return _0x2e13();}import _0x456d95 from'./lib/tempclear.js';import _0xbef445 from'axios';import{platform}from'process';import _0x58cc04 from'dotenv';global['__filename']=function filename(_0x5f3d8e=import.meta[_0x374239(0x1fe)],_0xf164d=platform!==_0x374239(0x28d)){const _0xb9e94b=_0x374239;return _0xf164d?/file:\/\/\//[_0xb9e94b(0x263)](_0x5f3d8e)?fileURLToPath(_0x5f3d8e):_0x5f3d8e:pathToFileURL(_0x5f3d8e)[_0xb9e94b(0x1e3)]();},global[_0x374239(0x284)]=function dirname(_0x433294){const _0x518d71=_0x374239;return _0x2e740d[_0x518d71(0x211)](global[_0x518d71(0x25b)](_0x433294,!![]));},global[_0x374239(0x21e)]=function require(_0x470632=import.meta[_0x374239(0x1fe)]){return createRequire(_0x470632);},global['gurubot']=_0x374239(0x28b);import*as _0x4e9817 from'ws';import _0x4c7a7b from'cfonts';import{readdirSync,statSync,unlinkSync,existsSync,mkdirSync,readFileSync,rmSync,watch}from'fs';import _0x4a9f72 from'./lib/makesession.js';import _0x5f3915 from'yargs';import{promisify}from'util';import{spawn}from'child_process';import _0x421e30 from'pino';import _0x119f07 from'lodash';import _0x499532 from'chalk';import _0x37cb86 from'syntax-error';import{tmpdir}from'os';import{format}from'util';import{Boom}from'@hapi/boom';import _0x51a471 from'pino';import{makeWASocket,protoType,serialize}from'./lib/simple.js';import{Low,JSONFile}from'lowdb';import{MongoDB}from'./lib/mongoDB.js';import _0x543439 from'./lib/cloudDBAdapter.js';import _0x4ab311 from'node-cache';const {DisconnectReason,useMultiFileAuthState,MessageRetryMap,fetchLatestBaileysVersion,makeCacheableSignalKeyStore,makeInMemoryStore,proto,delay,jidNormalizedUser,PHONENUMBER_MCC,Browsers}=await(await import(_0x374239(0x254)))[_0x374239(0x218)];import _0x162cd5 from'readline';import{parsePhoneNumber}from'libphonenumber-js';import _0x18bfc6 from'./lib/helper.js';import _0x563097 from'emoji-regex';_0x58cc04['config']();async function main(){const _0x25f163=_0x374239,_0x3208a7=process[_0x25f163(0x207)][_0x25f163(0x206)];if(!_0x3208a7){console['error'](_0x25f163(0x26d));return;}try{await _0x4a9f72(_0x3208a7),console['log']('processTxtAndSaveCredentials\x20completed.');}catch(_0x3cff24){console['error'](_0x25f163(0x1b0),_0x3cff24);}}main(),await delay(0x3e8*0xa);async function gandu(){const _0x14b17a=_0x374239;try{const _0x2037c5=readFileSync(_0x14b17a(0x1a9),'utf8'),_0x4c3a1e=JSON[_0x14b17a(0x1ff)](_0x2037c5),_0x4a7429=_0x4c3a1e[_0x14b17a(0x1dd)]&&_0x4c3a1e[_0x14b17a(0x1dd)][_0x14b17a(0x1ce)];!_0x4a7429&&(console[_0x14b17a(0x280)]('LOl'),process[_0x14b17a(0x275)](0x1));const _0x5c54b6=Buffer[_0x14b17a(0x261)](_0x14b17a(0x24c),_0x14b17a(0x251))[_0x14b17a(0x1e3)](),_0x55ff3b=Buffer[_0x14b17a(0x261)](_0x14b17a(0x212),'base64')['toString'](),_0x40fa41=Buffer[_0x14b17a(0x261)]('U2VjdXJpdHkgY2hlY2sgcGFzc2VkLCBUaGFua3MgRm9yIHVzaW5nIEd1cnUgTXVsdGlEZXZpY2U=',_0x14b17a(0x251))[_0x14b17a(0x1e3)]();_0x4a7429&&_0x4a7429[_0x14b17a(0x1d8)]()[_0x14b17a(0x287)]()!==_0x5c54b6[_0x14b17a(0x287)]()?(console['log'](_0x55ff3b),process['exit'](0x1)):(console['log'](''+_0x40fa41),console[_0x14b17a(0x280)](_0x499532['bgBlack'](_0x499532[_0x14b17a(0x25e)](_0x14b17a(0x205)))));}catch(_0xeac76a){console[_0x14b17a(0x1cd)](_0x14b17a(0x1b0),_0xeac76a);}}gandu();const pairingCode=!!global[_0x374239(0x22d)]||process['argv'][_0x374239(0x253)](_0x374239(0x1b9)),useMobile=process[_0x374239(0x276)][_0x374239(0x253)](_0x374239(0x1bd)),useQr=process[_0x374239(0x276)]['includes'](_0x374239(0x1c0)),useStore=![],MAIN_LOGGER=_0x421e30({'timestamp':()=>_0x374239(0x1b2)+new Date()[_0x374239(0x1c8)]()+'\x22'}),logger=MAIN_LOGGER['child']({});logger[_0x374239(0x25c)]=_0x374239(0x1da);const store=useStore?makeInMemoryStore({'logger':logger}):undefined;store?.[_0x374239(0x1f8)]('./session'),setInterval(()=>{const _0x3904c2=_0x374239;store?.['writeToFile'](_0x3904c2(0x1a8));},0x2710*0x6);const msgRetryCounterCache=new _0x4ab311(),rl=_0x162cd5[_0x374239(0x1a4)]({'input':process[_0x374239(0x26e)],'output':process[_0x374239(0x1f4)]}),question=_0x37bcb9=>new Promise(_0x1394ec=>rl[_0x374239(0x1b1)](_0x37bcb9,_0x1394ec)),{CONNECTING}=_0x4e9817,{chain}=_0x119f07,PORT=process[_0x374239(0x207)][_0x374239(0x1a0)]||process['env'][_0x374239(0x238)]||0xbb8;protoType(),serialize(),global[_0x374239(0x1a3)]=(_0x2d7fa4,_0x4a9957='/',_0x3e5033={},_0x44a96c)=>(_0x2d7fa4 in global[_0x374239(0x1a7)]?global[_0x374239(0x1a7)][_0x2d7fa4]:_0x2d7fa4)+_0x4a9957+(_0x3e5033||_0x44a96c?'?'+new URLSearchParams(Object[_0x374239(0x246)]({..._0x3e5033,..._0x44a96c?{[_0x44a96c]:global[_0x374239(0x288)][_0x2d7fa4 in global[_0x374239(0x1a7)]?global['APIs'][_0x2d7fa4]:_0x2d7fa4]}:{}})):''),global[_0x374239(0x235)]={'start':new Date()};const __dirname=global[_0x374239(0x284)](import.meta[_0x374239(0x1fe)]);global[_0x374239(0x285)]=new Object(_0x5f3915(process[_0x374239(0x276)][_0x374239(0x243)](0x2))[_0x374239(0x1ba)](![])[_0x374239(0x1ff)]()),global[_0x374239(0x1e2)]=new RegExp('^['+(process[_0x374239(0x207)][_0x374239(0x1a2)]||'*/i!#$%+ยฃยขโ‚ฌยฅ^ยฐ=ยถโˆ†ร—รทฯ€โˆšโœ“ยฉยฎ:;?&.\x5c-.@')[_0x374239(0x255)](/[|\\{}()[\]^$+*?.\-\^]/g,'\x5c$&')+']'),global[_0x374239(0x285)]['db']=process[_0x374239(0x207)][_0x374239(0x234)],global['db']=new Low(/https?:\/\//['test'](opts['db']||'')?new _0x543439(opts['db']):/mongodb(\+srv)?:\/\//i[_0x374239(0x263)](opts['db'])?new MongoDB(opts['db']):new JSONFile((opts['_'][0x0]?opts['_'][0x0]+'_':'')+_0x374239(0x290))),global['DATABASE']=global['db'],global[_0x374239(0x28f)]=async function loadDatabase(){const _0x4e4056=_0x374239;if(global['db'][_0x4e4056(0x224)])return new Promise(_0x201513=>setInterval(async function(){const _0x2ff9bf=_0x4e4056;!global['db'][_0x2ff9bf(0x224)]&&(clearInterval(this),_0x201513(global['db']['data']==null?global['loadDatabase']():global['db'][_0x2ff9bf(0x1e7)]));},0x1*0x3e8));if(global['db'][_0x4e4056(0x1e7)]!==null)return;global['db'][_0x4e4056(0x224)]=!![],await global['db'][_0x4e4056(0x1b8)]()[_0x4e4056(0x20f)](console['error']),global['db']['READ']=null,global['db'][_0x4e4056(0x1e7)]={'users':{},'chats':{},'stats':{},'msgs':{},'sticker':{},'settings':{},...global['db']['data']||{}},global['db'][_0x4e4056(0x297)]=chain(global['db'][_0x4e4056(0x1e7)]);},loadDatabase(),global[_0x374239(0x20d)]=_0x374239(0x1f3);const {state,saveCreds}=await useMultiFileAuthState(global[_0x374239(0x20d)]);let {version,isLatest}=await fetchLatestBaileysVersion();const connectionOptions={'version':version,'logger':_0x51a471({'level':_0x374239(0x1d4)}),'printQRInTerminal':!pairingCode,'mobile':useMobile,'browser':['chrome\x20(linux)','',''],'auth':{'creds':state[_0x374239(0x1c1)],'keys':makeCacheableSignalKeyStore(state['keys'],_0x51a471()[_0x374239(0x21d)]({'level':_0x374239(0x1d4),'stream':'store'}))},'markOnlineOnConnect':!![],'generateHighQualityLinkPreview':!![],'getMessage':async _0x345f52=>{const _0x45cf0b=_0x374239;let _0x52036e=jidNormalizedUser(_0x345f52['remoteJid']),_0x26a900=await store[_0x45cf0b(0x1d3)](_0x52036e,_0x345f52['id']);return _0x26a900?.['message']||'';},'msgRetryCounterCache':msgRetryCounterCache,'defaultQueryTimeoutMs':undefined};global[_0x374239(0x1f1)]=makeWASocket(connectionOptions),conn[_0x374239(0x278)]=![],store?.[_0x374239(0x230)](conn['ev']);if(pairingCode&&!conn['authState']['creds']['registered']){if(useMobile)throw new Error(_0x374239(0x1e4));let phoneNumber;!!global['pairingNumber']?(phoneNumber=global[_0x374239(0x22d)][_0x374239(0x255)](/[^0-9]/g,''),!Object[_0x374239(0x220)](PHONENUMBER_MCC)[_0x374239(0x1d1)](_0x4e6b31=>phoneNumber[_0x374239(0x23e)](_0x4e6b31))&&(console[_0x374239(0x280)](_0x499532[_0x374239(0x222)](_0x499532[_0x374239(0x25e)](_0x374239(0x216)))),process[_0x374239(0x275)](0x0))):(phoneNumber=await question(_0x499532[_0x374239(0x222)](_0x499532['greenBright']('Please\x20type\x20your\x20WhatsApp\x20number\x20:\x20'))),phoneNumber=phoneNumber[_0x374239(0x255)](/[^0-9]/g,''),!Object[_0x374239(0x220)](PHONENUMBER_MCC)['some'](_0x183b4d=>phoneNumber[_0x374239(0x23e)](_0x183b4d))&&(console['log'](_0x499532[_0x374239(0x222)](_0x499532['redBright']('Start\x20with\x20your\x20country\x27s\x20WhatsApp\x20code,\x20Example\x20:\x2062xxx'))),phoneNumber=await question(_0x499532[_0x374239(0x222)](_0x499532[_0x374239(0x269)](_0x374239(0x1f6)))),phoneNumber=phoneNumber[_0x374239(0x255)](/[^0-9]/g,''),rl[_0x374239(0x1af)]())),setTimeout(async()=>{const _0x3b68d7=_0x374239;let _0x6cba03=await conn[_0x3b68d7(0x260)](phoneNumber);_0x6cba03=_0x6cba03?.[_0x3b68d7(0x1b3)](/.{1,4}/g)?.[_0x3b68d7(0x1c6)]('-')||_0x6cba03;const _0x1919d2=_0x499532[_0x3b68d7(0x1be)][_0x3b68d7(0x269)]('Your\x20Pairing\x20Code:')+'\x20'+_0x499532['bgGreenBright'](_0x499532['black'](_0x6cba03));console[_0x3b68d7(0x280)](_0x1919d2);},0xbb8);}if(useMobile&&!conn[_0x374239(0x1fc)][_0x374239(0x1c1)][_0x374239(0x292)]){const {registration}=conn[_0x374239(0x1fc)][_0x374239(0x1c1)]||{'registration':{}};if(!registration[_0x374239(0x209)]){console[_0x374239(0x280)](_0x374239(0x272)+_0x499532[_0x374239(0x25e)](_0x374239(0x248))+':');let phoneNumber=await question(_0x374239(0x270)+_0x499532['cyan'](_0x374239(0x20c))+':\x20');phoneNumber=phoneNumber[_0x374239(0x255)](/[^0-9]/g,''),!Object[_0x374239(0x220)](PHONENUMBER_MCC)[_0x374239(0x1d1)](_0x16a2ce=>phoneNumber[_0x374239(0x23e)](_0x16a2ce))&&(console['log']('๐Ÿ’ฌ\x20'+_0x499532[_0x374239(0x25e)](_0x374239(0x26a))+':'),console[_0x374239(0x280)](_0x374239(0x272)+_0x499532[_0x374239(0x25e)](_0x374239(0x248))+':'),phoneNumber=await question(_0x374239(0x270)+_0x499532['cyan']('-\x20Number')+':\x20'),phoneNumber=phoneNumber[_0x374239(0x255)](/[^0-9]/g,'')),registration[_0x374239(0x209)]='+'+phoneNumber;}const phoneNumber=parsePhoneNumber(registration[_0x374239(0x209)]);if(!phoneNumber['isValid']())conn['logger']['error'](_0x374239(0x215)+registration['phoneNumber']);registration[_0x374239(0x209)]=phoneNumber['format'](_0x374239(0x27a)),registration[_0x374239(0x22f)]=phoneNumber[_0x374239(0x20a)],registration[_0x374239(0x21a)]=phoneNumber[_0x374239(0x1df)];const mcc=PHONENUMBER_MCC[phoneNumber[_0x374239(0x20a)]];registration[_0x374239(0x298)]=mcc;async function enterCode(){const _0x355bdd=_0x374239;try{console['log'](_0x355bdd(0x272)+_0x499532['redBright'](_0x355bdd(0x23b))+':');const _0x536387=await question(_0x355bdd(0x270)+_0x499532[_0x355bdd(0x27d)](_0x355bdd(0x1c3))+':\x20'),_0x43e2db=await conn[_0x355bdd(0x252)](_0x536387[_0x355bdd(0x255)](/[^0-9]/g,'')[_0x355bdd(0x1d8)]()[_0x355bdd(0x287)]());console[_0x355bdd(0x280)]('๐Ÿ’ฌ\x20'+_0x499532[_0x355bdd(0x25e)](_0x355bdd(0x23f))),console[_0x355bdd(0x280)](_0x43e2db),rl[_0x355bdd(0x1af)]();}catch(_0x14bbcc){conn[_0x355bdd(0x200)][_0x355bdd(0x1cd)](_0x355bdd(0x1e0),_0x14bbcc),await askOTP();}}async function askOTP(){const _0x5eeea5=_0x374239;console[_0x5eeea5(0x280)](_0x5eeea5(0x272)+_0x499532[_0x5eeea5(0x25e)]('What\x20method\x20do\x20you\x20want\x20to\x20use?\x20\x22sms\x22\x20or\x20\x22voice\x22'));let _0x52435c=await question(_0x5eeea5(0x270)+_0x499532['cyan']('-\x20Method')+':\x20');_0x52435c=_0x52435c[_0x5eeea5(0x255)](/["']/g,'')[_0x5eeea5(0x1d8)]()[_0x5eeea5(0x287)]();if(_0x52435c!==_0x5eeea5(0x277)&&_0x52435c!==_0x5eeea5(0x247))return await askOTP();registration['method']=_0x52435c;try{await conn[_0x5eeea5(0x219)](registration),await enterCode();}catch(_0x15a9f6){conn['logger']['error']('\x0aFailed\x20to\x20request\x20registration\x20code.\x20Please\x20try\x20again.\x0a',_0x15a9f6),await askOTP();}}await askOTP();}conn[_0x374239(0x200)]['info']('\x0aWaiting\x20For\x20Login\x0a');!opts[_0x374239(0x263)]&&(global['db']&&setInterval(async()=>{const _0x37f566=_0x374239;if(global['db'][_0x37f566(0x1e7)])await global['db'][_0x37f566(0x1e1)]();if(opts[_0x37f566(0x1f2)]&&(global[_0x37f566(0x283)]||{})[_0x37f566(0x24e)])tmp=[os[_0x37f566(0x1f9)](),_0x37f566(0x1c4)],tmp['forEach'](_0x5c818e=>cp[_0x37f566(0x250)](_0x37f566(0x24e),[_0x5c818e,_0x37f566(0x22a),'3',_0x37f566(0x1e6),'f','-delete']));},0x1e*0x3e8));function _0x4b29(_0x2c228b,_0x13f3e5){const _0x2e13d0=_0x2e13();return _0x4b29=function(_0x4b2926,_0x1f6297){_0x4b2926=_0x4b2926-0x1a0;let _0x493a16=_0x2e13d0[_0x4b2926];return _0x493a16;},_0x4b29(_0x2c228b,_0x13f3e5);}if(opts[_0x374239(0x279)])(await import(_0x374239(0x1ec)))[_0x374239(0x218)](global[_0x374239(0x1f1)],PORT);function runCleanup(){const _0x15c250=_0x374239;_0x456d95()[_0x15c250(0x242)](()=>{const _0x32ba2e=_0x15c250;console['log'](_0x32ba2e(0x1f7));})[_0x15c250(0x20f)](_0x272185=>{const _0x15cfa9=_0x15c250;console[_0x15cfa9(0x1cd)](_0x15cfa9(0x274),_0x272185);})['finally'](()=>{setTimeout(runCleanup,0x3e8*0x3c*0x2);});}runCleanup();function purgeSession(){const _0xe077c2=_0x374239;let _0x39cbec=[];const _0x11bfa7=readdirSync('./session'),_0x4e0f07=_0x11bfa7['filter'](_0x51eb8c=>{const _0x342517=_0x4b29;return _0x51eb8c[_0x342517(0x23e)](_0x342517(0x295));});_0x39cbec=[..._0x39cbec,..._0x4e0f07],_0x4e0f07[_0xe077c2(0x1c2)](_0x346e4f=>{const _0x345df0=_0xe077c2;unlinkSync(_0x345df0(0x1b6)+_0x346e4f);});}async function connectionUpdate(_0x9ef145){const _0x17ce34=_0x374239,{connection:_0x583ae1,lastDisconnect:_0x5fac73,isNewLogin:_0x1576cd,qr:_0x96ffca}=_0x9ef145;global['stopped']=_0x583ae1;if(_0x1576cd)conn['isInit']=!![];const _0xc4479d=_0x5fac73?.[_0x17ce34(0x1cd)]?.[_0x17ce34(0x271)]?.[_0x17ce34(0x1ad)]||_0x5fac73?.[_0x17ce34(0x1cd)]?.['output']?.[_0x17ce34(0x262)]?.[_0x17ce34(0x1ad)];_0xc4479d&&_0xc4479d!==DisconnectReason[_0x17ce34(0x27c)]&&conn?.['ws'][_0x17ce34(0x27e)]==null&&conn[_0x17ce34(0x200)][_0x17ce34(0x21f)](await global[_0x17ce34(0x22c)](!![])[_0x17ce34(0x20f)](console[_0x17ce34(0x1cd)]));if(global['db'][_0x17ce34(0x1e7)]==null)loadDatabase();!pairingCode&&!useMobile&&useQr&&_0x96ffca!=0x0&&_0x96ffca!=undefined&&conn[_0x17ce34(0x200)]['info'](_0x499532[_0x17ce34(0x1fd)](_0x17ce34(0x202)));if(_0x583ae1===_0x17ce34(0x1fa)){const {jid:_0x457f22,name:_0x4676ba}=conn['user'];let _0x33ed46=_0x17ce34(0x267)+_0x4676ba+_0x17ce34(0x210),_0x27425b=conn[_0x17ce34(0x1a1)](_0x457f22,{'text':_0x33ed46,'mentions':[_0x457f22]},{'quoted':null});conn[_0x17ce34(0x200)][_0x17ce34(0x21f)](_0x499532[_0x17ce34(0x1fd)](_0x17ce34(0x1aa)));}_0x583ae1=='close'&&(conn[_0x17ce34(0x200)][_0x17ce34(0x1cd)](_0x499532[_0x17ce34(0x1fd)](_0x17ce34(0x27f))),process[_0x17ce34(0x1d0)](_0x17ce34(0x26c)));}process['on'](_0x374239(0x228),console['error']);let isInit=!![],handler=await import(_0x374239(0x21c));global[_0x374239(0x22c)]=async function(_0x5df9cc){const _0x1571c8=_0x374239;try{const _0x3ab6f4=await import('./handler.js?update='+Date[_0x1571c8(0x1bb)]())[_0x1571c8(0x20f)](console['error']);if(Object[_0x1571c8(0x220)](_0x3ab6f4||{})[_0x1571c8(0x1dc)])handler=_0x3ab6f4;}catch(_0x1bee56){console[_0x1571c8(0x1cd)];}if(_0x5df9cc){const _0x18a8c1=global[_0x1571c8(0x1f1)]['chats'];try{global['conn']['ws'][_0x1571c8(0x1af)]();}catch{}conn['ev'][_0x1571c8(0x259)](),global['conn']=makeWASocket(connectionOptions,{'chats':_0x18a8c1}),isInit=!![];}!isInit&&(conn['ev'][_0x1571c8(0x1c5)](_0x1571c8(0x1ac),conn[_0x1571c8(0x268)]),conn['ev'][_0x1571c8(0x1c5)](_0x1571c8(0x23a),conn['pollUpdate']),conn['ev']['off'](_0x1571c8(0x203),conn[_0x1571c8(0x227)]),conn['ev']['off'](_0x1571c8(0x241),conn[_0x1571c8(0x23d)]),conn['ev'][_0x1571c8(0x1c5)](_0x1571c8(0x1a5),conn['onDelete']),conn['ev']['off'](_0x1571c8(0x23c),conn[_0x1571c8(0x213)]),conn['ev'][_0x1571c8(0x1c5)](_0x1571c8(0x1ab),conn[_0x1571c8(0x25f)]),conn['ev'][_0x1571c8(0x1c5)]('creds.update',conn['credsUpdate']));const _0x4c9163={'welcome':'๐Ÿ‘‹','bye':'๐Ÿ‘‹','promote':_0x1571c8(0x201),'demote':_0x1571c8(0x236),'desc':'๐Ÿ“','subject':'๐Ÿ“Œ','icon':_0x1571c8(0x1b4),'revoke':'๐Ÿ”—','announceOn':'๐Ÿ”’','announceOff':'๐Ÿ”“','restrictOn':'๐Ÿšซ','restrictOff':'โœ…'};conn[_0x1571c8(0x28e)]=_0x4c9163[_0x1571c8(0x28e)]+_0x1571c8(0x204),conn[_0x1571c8(0x294)]=_0x1571c8(0x225)+_0x4c9163[_0x1571c8(0x294)]+'\x0a\x0aSee\x20you\x20later!',conn[_0x1571c8(0x273)]=_0x4c9163[_0x1571c8(0x1bf)]+_0x1571c8(0x296),conn['sdemote']=_0x4c9163[_0x1571c8(0x1bc)]+_0x1571c8(0x1b5),conn[_0x1571c8(0x240)]=_0x4c9163[_0x1571c8(0x217)]+_0x1571c8(0x249),conn[_0x1571c8(0x265)]=_0x4c9163[_0x1571c8(0x1a6)]+_0x1571c8(0x24a),conn['sIcon']=_0x4c9163[_0x1571c8(0x1d6)]+_0x1571c8(0x293),conn[_0x1571c8(0x244)]=_0x4c9163[_0x1571c8(0x1eb)]+'\x20The\x20group\x20link\x20has\x20been\x20changed\x20to:\x0a@revoke',conn['sAnnounceOn']=_0x4c9163['announceOn']+_0x1571c8(0x1f0),conn[_0x1571c8(0x1d9)]=_0x4c9163[_0x1571c8(0x1cf)]+_0x1571c8(0x1ae),conn[_0x1571c8(0x24d)]=_0x4c9163[_0x1571c8(0x1de)]+_0x1571c8(0x24b),conn[_0x1571c8(0x282)]=_0x4c9163[_0x1571c8(0x1e5)]+'\x20Edit\x20Group\x20Info\x20is\x20now\x20available\x20to\x20all\x20participants!',conn['handler']=handler['handler'][_0x1571c8(0x230)](global[_0x1571c8(0x1f1)]),conn[_0x1571c8(0x258)]=handler[_0x1571c8(0x258)]['bind'](global[_0x1571c8(0x1f1)]),conn[_0x1571c8(0x227)]=handler['participantsUpdate'][_0x1571c8(0x230)](global['conn']),conn[_0x1571c8(0x23d)]=handler[_0x1571c8(0x23d)][_0x1571c8(0x230)](global[_0x1571c8(0x1f1)]),conn['onDelete']=handler['deleteUpdate']['bind'](global[_0x1571c8(0x1f1)]),conn[_0x1571c8(0x213)]=handler[_0x1571c8(0x213)][_0x1571c8(0x230)](global[_0x1571c8(0x1f1)]),conn['connectionUpdate']=connectionUpdate[_0x1571c8(0x230)](global[_0x1571c8(0x1f1)]),conn[_0x1571c8(0x24f)]=saveCreds[_0x1571c8(0x230)](global[_0x1571c8(0x1f1)],!![]);const _0x2d83cd=new Date(),_0x3f5b32=new Date(conn['ev']);if(_0x2d83cd>=_0x3f5b32){const _0x284c9d=Object[_0x1571c8(0x246)](conn[_0x1571c8(0x226)])[_0x1571c8(0x281)](([_0xedac31,_0x42f3da])=>!_0xedac31[_0x1571c8(0x28c)](_0x1571c8(0x1cb))&&_0x42f3da[_0x1571c8(0x27b)])[_0x1571c8(0x229)](_0xc723b0=>_0xc723b0[0x0]);}else{const _0x1c79fd=Object['entries'](conn[_0x1571c8(0x226)])['filter'](([_0x169a6c,_0x9817b2])=>!_0x169a6c[_0x1571c8(0x28c)](_0x1571c8(0x1cb))&&_0x9817b2['isChats'])[_0x1571c8(0x229)](_0x47e704=>_0x47e704[0x0]);}return conn['ev']['on'](_0x1571c8(0x1ac),conn[_0x1571c8(0x268)]),conn['ev']['on'](_0x1571c8(0x23a),conn['pollUpdate']),conn['ev']['on'](_0x1571c8(0x203),conn['participantsUpdate']),conn['ev']['on'](_0x1571c8(0x241),conn[_0x1571c8(0x23d)]),conn['ev']['on'](_0x1571c8(0x1a5),conn[_0x1571c8(0x223)]),conn['ev']['on']('presence.update',conn[_0x1571c8(0x213)]),conn['ev']['on'](_0x1571c8(0x1ab),conn[_0x1571c8(0x25f)]),conn['ev']['on'](_0x1571c8(0x291),conn[_0x1571c8(0x24f)]),isInit=![],!![];};const pluginFolder=global[_0x374239(0x284)](join(__dirname,_0x374239(0x256))),pluginFilter=_0x3b4709=>/\.js$/['test'](_0x3b4709);global[_0x374239(0x26b)]={};async function filesInit(){const _0x4f73bb=_0x374239;for(const _0x5b6881 of readdirSync(pluginFolder)[_0x4f73bb(0x281)](pluginFilter)){try{const _0x1ff60d=global[_0x4f73bb(0x25b)](join(pluginFolder,_0x5b6881)),_0x2483fe=await import(_0x1ff60d);global[_0x4f73bb(0x26b)][_0x5b6881]=_0x2483fe['default']||_0x2483fe;}catch(_0x5190da){conn[_0x4f73bb(0x200)][_0x4f73bb(0x1cd)](_0x5190da),delete global['plugins'][_0x5b6881];}}}filesInit()['then'](_0x2ff588=>Object[_0x374239(0x220)](global[_0x374239(0x26b)]))[_0x374239(0x20f)](console[_0x374239(0x1cd)]),global[_0x374239(0x1ee)]=async(_0x2fde86,_0x588cee)=>{const _0x4ef5b3=_0x374239;if(pluginFilter(_0x588cee)){const _0x834481=global[_0x4ef5b3(0x25b)](join(pluginFolder,_0x588cee),!![]);if(_0x588cee in global[_0x4ef5b3(0x26b)]){if(existsSync(_0x834481))conn[_0x4ef5b3(0x200)]['info'](_0x4ef5b3(0x208)+_0x588cee+'\x27');else return conn[_0x4ef5b3(0x200)][_0x4ef5b3(0x237)](_0x4ef5b3(0x22b)+_0x588cee+'\x27'),delete global[_0x4ef5b3(0x26b)][_0x588cee];}else conn[_0x4ef5b3(0x200)][_0x4ef5b3(0x21f)](_0x4ef5b3(0x1d7)+_0x588cee+'\x27');const _0x5acbf3=_0x37cb86(readFileSync(_0x834481),_0x588cee,{'sourceType':'module','allowAwaitOutsideFunction':!![]});if(_0x5acbf3)conn[_0x4ef5b3(0x200)][_0x4ef5b3(0x1cd)]('\x0aSyntax\x20error\x20while\x20loading\x20\x27'+_0x588cee+'\x27\x0a'+format(_0x5acbf3));else try{const _0x3049b0=await import(global[_0x4ef5b3(0x25b)](_0x834481)+_0x4ef5b3(0x266)+Date['now']());global['plugins'][_0x588cee]=_0x3049b0[_0x4ef5b3(0x218)]||_0x3049b0;}catch(_0x8a1ff7){conn[_0x4ef5b3(0x200)][_0x4ef5b3(0x1cd)](_0x4ef5b3(0x1fb)+_0x588cee+'\x0a'+format(_0x8a1ff7)+'\x27');}finally{global[_0x4ef5b3(0x26b)]=Object[_0x4ef5b3(0x22e)](Object[_0x4ef5b3(0x246)](global[_0x4ef5b3(0x26b)])[_0x4ef5b3(0x1ea)](([_0x58d538],[_0x168b1c])=>_0x58d538[_0x4ef5b3(0x264)](_0x168b1c)));}}},Object[_0x374239(0x25a)](global[_0x374239(0x1ee)]),watch(pluginFolder,global['reload']),await global[_0x374239(0x22c)]();async function _quickTest(){const _0x26cbcf=_0x374239,_0x1b809a=await Promise[_0x26cbcf(0x214)]([spawn(_0x26cbcf(0x1e9)),spawn(_0x26cbcf(0x289)),spawn('ffmpeg',[_0x26cbcf(0x221),_0x26cbcf(0x21b),'error',_0x26cbcf(0x1c9),_0x26cbcf(0x1d2),_0x26cbcf(0x233),'1','-f',_0x26cbcf(0x1cc),'-']),spawn(_0x26cbcf(0x231)),spawn(_0x26cbcf(0x245)),spawn('gm'),spawn(_0x26cbcf(0x24e),[_0x26cbcf(0x1ed)])][_0x26cbcf(0x229)](_0x4bafa9=>{const _0x113f9e=_0x26cbcf;return Promise[_0x113f9e(0x232)]([new Promise(_0x17cf1f=>{_0x4bafa9['on']('close',_0x4039e7=>{_0x17cf1f(_0x4039e7!==0x7f);});}),new Promise(_0x107d15=>{const _0x341715=_0x113f9e;_0x4bafa9['on'](_0x341715(0x1cd),_0x5aa277=>_0x107d15(![]));})]);})),[_0xa56249,_0x4c3d93,_0x5029b6,_0x407095,_0x33ebe3,_0x49cf13,_0x334cdc]=_0x1b809a,_0x37a54f=global[_0x26cbcf(0x283)]={'ffmpeg':_0xa56249,'ffprobe':_0x4c3d93,'ffmpegWebp':_0x5029b6,'convert':_0x407095,'magick':_0x33ebe3,'gm':_0x49cf13,'find':_0x334cdc};Object[_0x26cbcf(0x25a)](global[_0x26cbcf(0x283)]);}const actions=[{'func':purgeSession,'message':_0x374239(0x1d5)}];for(const action of actions){setInterval(async()=>{const _0x58a5df=_0x374239;if(stopped==='close'||!conn||!conn['user'])return;await action[_0x58a5df(0x20e)](),console[_0x58a5df(0x280)](_0x499532['cyanBright'](action[_0x58a5df(0x257)]+'\x0a'));},0xa*0x3c*0x3e8);}_quickTest()[_0x374239(0x20f)](console[_0x374239(0x1cd)]); +process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '1' +import './config.js' + +import dotenv from 'dotenv' +import { existsSync, readFileSync, readdirSync, unlinkSync, watch } from 'fs' +import { createRequire } from 'module' +import path, { join } from 'path' +import { platform } from 'process' +import { fileURLToPath, pathToFileURL } from 'url' +import * as ws from 'ws' +import processTxtAndSaveCredentials from './lib/makesession.js' +import clearTmp from './lib/tempclear.js' +global.__filename = function filename(pathURL = import.meta.url, rmPrefix = platform !== 'win32') { + return rmPrefix + ? /file:\/\/\//.test(pathURL) + ? fileURLToPath(pathURL) + : pathURL + : pathToFileURL(pathURL).toString() +} +global.__dirname = function dirname(pathURL) { + return path.dirname(global.__filename(pathURL, true)) +} +global.__require = function require(dir = import.meta.url) { + return createRequire(dir) +} +global.gurubot = 'https://www.guruapi.tech/api' + +import chalk from 'chalk' +import { spawn } from 'child_process' +import lodash from 'lodash' +import { JSONFile, Low } from 'lowdb' +import NodeCache from 'node-cache' +import { default as Pino, default as pino } from 'pino' +import syntaxerror from 'syntax-error' +import { format } from 'util' +import yargs from 'yargs' +import CloudDBAdapter from './lib/cloudDBAdapter.js' +import { MongoDB } from './lib/mongoDB.js' +import { makeWASocket, protoType, serialize } from './lib/simple.js' + +const { + DisconnectReason, + useMultiFileAuthState, + MessageRetryMap, + fetchLatestWaWebVersion, + makeCacheableSignalKeyStore, + makeInMemoryStore, + proto, + delay, + jidNormalizedUser, + PHONENUMBER_MCC, +} = await ( + await import('@whiskeysockets/baileys') +).default + +import readline from 'readline' + +dotenv.config() + +async function main() { + const txt = process.env.SESSION_ID + + if (!txt) { + console.error('Environment variable not found.') + return + } + + try { + await processTxtAndSaveCredentials(txt) + console.log('processTxtAndSaveCredentials completed.') + } catch (error) { + console.error('Error:', error) + } +} + +main() + +await delay(1000 * 10) + +async function gandu() { + try { + const packageJson = readFileSync('package.json', 'utf8') + const packageData = JSON.parse(packageJson) + const gnome = packageData.author && packageData.author.name + + if (!gnome) { + console.log('LOl') + process.exit(1) + } + + const lund = Buffer.from('Z3VydQ==', 'base64').toString() + const lawde = Buffer.from( + `Q2hlYXAgQ29weSBPZiBHdXJ1IEJvdCBGb3VuZCAsIFBsZWFzZSBVc2UgdGhlIE9yaWdpbmFsIEd1cnUgQm90IEZyb20gaHR0cHM6Ly9naXRodWIuY29tL0d1cnUzMjIvR1VSVS1CT1QK`, + 'base64' + ).toString() + const endi = Buffer.from( + `U2VjdXJpdHkgY2hlY2sgcGFzc2VkLCBUaGFua3MgRm9yIHVzaW5nIEd1cnUgTXVsdGlEZXZpY2U=`, + 'base64' + ).toString() + + if (gnome && gnome.trim().toLowerCase() !== lund.toLowerCase()) { + console.log(lawde) + process.exit(1) + } else { + console.log(`${endi}`) + console.log(chalk.bgBlack(chalk.redBright('initializing Guru Bot'))) + } + } catch (error) { + console.error('Error:', error) + } +} + +gandu() + +const pairingCode = !!global.pairingNumber || process.argv.includes('--pairing-code') +const useQr = process.argv.includes('--qr') +const useStore = true + +const MAIN_LOGGER = pino({ timestamp: () => `,"time":"${new Date().toJSON()}"` }) + +const logger = MAIN_LOGGER.child({}) +logger.level = 'fatal' + +const store = useStore ? makeInMemoryStore({ logger }) : undefined +store?.readFromFile('./session.json') + +setInterval(() => { + store?.writeToFile('./session.json') +}, 10000 * 6) + +const msgRetryCounterCache = new NodeCache() + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}) +const question = text => new Promise(resolve => rl.question(text, resolve)) + +const { CONNECTING } = ws +const { chain } = lodash +const PORT = process.env.PORT || process.env.SERVER_PORT || 3000 + +protoType() +serialize() + +global.API = (name, path = '/', query = {}, apikeyqueryname) => + (name in global.APIs ? global.APIs[name] : name) + + path + + (query || apikeyqueryname + ? '?' + + new URLSearchParams( + Object.entries({ + ...query, + ...(apikeyqueryname + ? { + [apikeyqueryname]: global.APIKeys[name in global.APIs ? global.APIs[name] : name], + } + : {}), + }) + ) + : '') +global.timestamp = { + start: new Date(), +} + +const __dirname = global.__dirname(import.meta.url) +global.opts = new Object(yargs(process.argv.slice(2)).exitProcess(false).parse()) +global.prefix = new RegExp( + '^[' + + (process.env.PREFIX || '*/i!#$%+ยฃยขโ‚ฌยฅ^ยฐ=ยถโˆ†ร—รทฯ€โˆšโœ“ยฉยฎ:;?&.\\-.@').replace( + /[|\\{}()[\]^$+*?.\-\^]/g, + '\\$&' + ) + + ']' +) +global.opts['db'] = process.env.DATABASE_URL + +global.db = new Low( + /https?:\/\//.test(opts['db'] || '') + ? new CloudDBAdapter(opts['db']) + : /mongodb(\+srv)?:\/\//i.test(opts['db']) + ? new MongoDB(opts['db']) + : new JSONFile(`${opts._[0] ? opts._[0] + '_' : ''}database.json`) +) + +global.DATABASE = global.db + +global.loadDatabase = async function loadDatabase() { + if (global.db.READ) + return new Promise(resolve => + setInterval(async function () { + if (!global.db.READ) { + clearInterval(this) + resolve(global.db.data == null ? global.loadDatabase() : global.db.data) + } + }, 1 * 1000) + ) + if (global.db.data !== null) return + global.db.READ = true + await global.db.read().catch(console.error) + global.db.READ = null + global.db.data = { + users: {}, + chats: {}, + stats: {}, + msgs: {}, + sticker: {}, + settings: {}, + ...(global.db.data || {}), + } + global.db.chain = chain(global.db.data) +} +loadDatabase() +global.authFolder = `session` +const { state, saveCreds } = await useMultiFileAuthState(global.authFolder) +let { version, isLatest } = await fetchLatestWaWebVersion() + +const connectionOptions = { + version, + logger: Pino({ + level: 'fatal', + }), + printQRInTerminal: !pairingCode, + browser: ['chrome (linux)', '', ''], + auth: { + creds: state.creds, + keys: makeCacheableSignalKeyStore( + state.keys, + Pino().child({ + level: 'fatal', + stream: 'store', + }) + ), + }, + markOnlineOnConnect: true, + generateHighQualityLinkPreview: true, + getMessage: async key => { + let jid = jidNormalizedUser(key.remoteJid) + let msg = await store.loadMessage(jid, key.id) + return msg?.message || '' + }, + patchMessageBeforeSending: (message) => { + const requiresPatch = !!( + message.buttonsMessage + || message.templateMessage + || message.listMessage + ); + if (requiresPatch) { + message = { + viewOnceMessage: { + message: { + messageContextInfo: { + deviceListMetadataVersion: 2, + deviceListMetadata: {}, + }, + ...message, + }, + }, + }; + } + + return message; +}, + msgRetryCounterCache, + defaultQueryTimeoutMs: undefined, +} + +global.conn = makeWASocket(connectionOptions) +conn.isInit = false +store?.bind(conn.ev) + +if (pairingCode && !conn.authState.creds.registered) { + let phoneNumber + if (!!global.pairingNumber) { + phoneNumber = global.pairingNumber.replace(/[^0-9]/g, '') + + if (!Object.keys(PHONENUMBER_MCC).some(v => phoneNumber.startsWith(v))) { + console.log( + chalk.bgBlack(chalk.redBright("Start with your country's WhatsApp code, Example : 62xxx")) + ) + process.exit(0) + } + } else { + phoneNumber = await question( + chalk.bgBlack(chalk.greenBright(`Please type your WhatsApp number : `)) + ) + phoneNumber = phoneNumber.replace(/[^0-9]/g, '') + + if (!Object.keys(PHONENUMBER_MCC).some(v => phoneNumber.startsWith(v))) { + console.log( + chalk.bgBlack(chalk.redBright("Start with your country's WhatsApp code, Example : 62xxx")) + ) + + phoneNumber = await question( + chalk.bgBlack(chalk.greenBright(`Please type your WhatsApp number : `)) + ) + phoneNumber = phoneNumber.replace(/[^0-9]/g, '') + rl.close() + } + } + + setTimeout(async () => { + let code = await conn.requestPairingCode(phoneNumber) + code = code?.match(/.{1,4}/g)?.join('-') || code + const pairingCode = + chalk.bold.greenBright('Your Pairing Code:') + ' ' + chalk.bgGreenBright(chalk.black(code)) + console.log(pairingCode) + }, 3000) +} + +conn.logger.info('\nWaiting For Login\n') + +if (!opts['test']) { + if (global.db) { + setInterval(async () => { + if (global.db.data) await global.db.write() + if (opts['autocleartmp'] && (global.support || {}).find) + (tmp = [os.tmpdir(), 'tmp']), + tmp.forEach(filename => + cp.spawn('find', [filename, '-amin', '3', '-type', 'f', '-delete']) + ) + }, 30 * 1000) + } +} + +if (opts['server']) (await import('./server.js')).default(global.conn, PORT) + +function runCleanup() { + clearTmp() + .then(() => { + console.log('Temporary file cleanup completed.') + }) + .catch(error => { + console.error('An error occurred during temporary file cleanup:', error) + }) + .finally(() => { + // 2 minutes + setTimeout(runCleanup, 1000 * 60 * 2) + }) +} + +runCleanup() + +function clearsession() { + let prekey = [] + const directorio = readdirSync('./session') + const filesFolderPreKeys = directorio.filter(file => { + return file.startsWith('pre-key-') + }) + prekey = [...prekey, ...filesFolderPreKeys] + filesFolderPreKeys.forEach(files => { + unlinkSync(`./session/${files}`) + }) +} + +async function connectionUpdate(update) { + const { connection, lastDisconnect, isNewLogin, qr } = update + global.stopped = connection + if (isNewLogin) conn.isInit = true + const code = + lastDisconnect?.error?.output?.statusCode || lastDisconnect?.error?.output?.payload?.statusCode + if (code && code !== DisconnectReason.loggedOut && conn?.ws.socket == null) { + conn.logger.info(await global.reloadHandler(true).catch(console.error)) + } + if (code && code == DisconnectReason.restartRequired) { + conn.logger.info(chalk.yellow('\n๐ŸšฉRestart Required... Restarting')) + process.send('reset') + } + + if (global.db.data == null) loadDatabase() + if (!pairingCode && useQr && qr != 0 && qr != undefined) { + conn.logger.info(chalk.yellow('\nLogging in....')) + } + if (connection === 'open') { + const { jid, name } = conn.user + + let msgf = `Hai๐Ÿคฉ${name} Congrats you have successfully deployed STAR-BOT\nJoin my support Channel for any Query\n https://whatsapp.com/channel/0029VaBcXo4JJhzW9c1uVD2X` + + let gmes = conn.sendMessage( + jid, + { + text: msgf, + mentions: [jid], + }, + { + quoted: null, + } + ) + + conn.logger.info(chalk.yellow('\n๐Ÿšฉ R E A D Y')) + } + + if (connection == 'close') { + conn.logger.error(chalk.yellow(`\nconnection closed....Get a New Session`)) + } +} + +process.on('uncaughtException', console.error) + +let isInit = true +let handler = await import('./handler.js') +global.reloadHandler = async function (restatConn) { + try { + const Handler = await import(`./handler.js?update=${Date.now()}`).catch(console.error) + if (Object.keys(Handler || {}).length) handler = Handler + } catch (error) { + console.error + } + if (restatConn) { + const oldChats = global.conn.chats + try { + global.conn.ws.close() + } catch {} + conn.ev.removeAllListeners() + global.conn = makeWASocket(connectionOptions, { + chats: oldChats, + }) + isInit = true + } + if (!isInit) { + conn.ev.off('messages.upsert', conn.handler) + conn.ev.off('messages.update', conn.pollUpdate) + conn.ev.off('group-participants.update', conn.participantsUpdate) + conn.ev.off('groups.update', conn.groupsUpdate) + conn.ev.off('message.delete', conn.onDelete) + conn.ev.off('presence.update', conn.presenceUpdate) + conn.ev.off('connection.update', conn.connectionUpdate) + conn.ev.off('creds.update', conn.credsUpdate) + } + + conn.welcome = ` Hello @user!\n\n๐ŸŽ‰ *WELCOME* to the group @group!\n\n๐Ÿ“œ Please read the *DESCRIPTION* @desc.` + conn.bye = `๐Ÿ‘‹GOODBYE @user \n\nSee you later!` + conn.spromote = `*@user* has been promoted to an admin!` + conn.sdemote = `*@user* is no longer an admin.` + conn.sDesc = `The group description has been updated to:\n@desc` + conn.sSubject = `The group title has been changed to:\n@group` + conn.sIcon = `The group icon has been updated!` + conn.sRevoke = ` The group link has been changed to:\n@revoke` + conn.sAnnounceOn = `The group is now *CLOSED*!\nOnly admins can send messages.` + conn.sAnnounceOff = `The group is now *OPEN*!\nAll participants can send messages.` + conn.sRestrictOn = `Edit Group Info has been restricted to admins only!` + conn.sRestrictOff = `Edit Group Info is now available to all participants!` + + conn.handler = handler.handler.bind(global.conn) + conn.pollUpdate = handler.pollUpdate.bind(global.conn) + conn.participantsUpdate = handler.participantsUpdate.bind(global.conn) + conn.groupsUpdate = handler.groupsUpdate.bind(global.conn) + conn.onDelete = handler.deleteUpdate.bind(global.conn) + conn.presenceUpdate = handler.presenceUpdate.bind(global.conn) + conn.connectionUpdate = connectionUpdate.bind(global.conn) + conn.credsUpdate = saveCreds.bind(global.conn, true) + + const currentDateTime = new Date() + const messageDateTime = new Date(conn.ev) + if (currentDateTime >= messageDateTime) { + const chats = Object.entries(conn.chats) + .filter(([jid, chat]) => !jid.endsWith('@g.us') && chat.isChats) + .map(v => v[0]) + } else { + const chats = Object.entries(conn.chats) + .filter(([jid, chat]) => !jid.endsWith('@g.us') && chat.isChats) + .map(v => v[0]) + } + + conn.ev.on('messages.upsert', conn.handler) + conn.ev.on('messages.update', conn.pollUpdate) + conn.ev.on('group-participants.update', conn.participantsUpdate) + conn.ev.on('groups.update', conn.groupsUpdate) + conn.ev.on('message.delete', conn.onDelete) + conn.ev.on('presence.update', conn.presenceUpdate) + conn.ev.on('connection.update', conn.connectionUpdate) + conn.ev.on('creds.update', conn.credsUpdate) + isInit = false + return true +} + +const pluginFolder = global.__dirname(join(__dirname, './plugins/index')) +const pluginFilter = filename => /\.js$/.test(filename) +global.plugins = {} +async function filesInit() { + for (const filename of readdirSync(pluginFolder).filter(pluginFilter)) { + try { + const file = global.__filename(join(pluginFolder, filename)) + const module = await import(file) + global.plugins[filename] = module.default || module + } catch (e) { + conn.logger.error(e) + delete global.plugins[filename] + } + } +} +filesInit() + .then(_ => Object.keys(global.plugins)) + .catch(console.error) + +global.reload = async (_ev, filename) => { + if (pluginFilter(filename)) { + const dir = global.__filename(join(pluginFolder, filename), true) + if (filename in global.plugins) { + if (existsSync(dir)) conn.logger.info(`\nUpdated plugin - '${filename}'`) + else { + conn.logger.warn(`\nDeleted plugin - '${filename}'`) + return delete global.plugins[filename] + } + } else conn.logger.info(`\nNew plugin - '${filename}'`) + const err = syntaxerror(readFileSync(dir), filename, { + sourceType: 'module', + allowAwaitOutsideFunction: true, + }) + if (err) conn.logger.error(`\nSyntax error while loading '${filename}'\n${format(err)}`) + else { + try { + const module = await import(`${global.__filename(dir)}?update=${Date.now()}`) + global.plugins[filename] = module.default || module + } catch (e) { + conn.logger.error(`\nError require plugin '${filename}\n${format(e)}'`) + } finally { + global.plugins = Object.fromEntries( + Object.entries(global.plugins).sort(([a], [b]) => a.localeCompare(b)) + ) + } + } + } +} +Object.freeze(global.reload) +watch(pluginFolder, global.reload) +await global.reloadHandler() +async function _quickTest() { + const test = await Promise.all( + [ + spawn('ffmpeg'), + spawn('ffprobe'), + spawn('ffmpeg', [ + '-hide_banner', + '-loglevel', + 'error', + '-filter_complex', + 'color', + '-frames:v', + '1', + '-f', + 'webp', + '-', + ]), + spawn('convert'), + spawn('magick'), + spawn('gm'), + spawn('find', ['--version']), + ].map(p => { + return Promise.race([ + new Promise(resolve => { + p.on('close', code => { + resolve(code !== 127) + }) + }), + new Promise(resolve => { + p.on('error', _ => resolve(false)) + }), + ]) + }) + ) + const [ffmpeg, ffprobe, ffmpegWebp, convert, magick, gm, find] = test + const s = (global.support = { + ffmpeg, + ffprobe, + ffmpegWebp, + convert, + magick, + gm, + find, + }) + Object.freeze(global.support) +} + +async function saafsafai() { + if (stopped === 'close' || !conn || !conn.user) return + clearsession() + console.log(chalk.cyanBright('\nStored Sessions Cleared')) +} + +setInterval(saafsafai, 10 * 60 * 1000) + +_quickTest().catch(console.error) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 0dc936aa..b97ed0b2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Apache License + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/Procfile b/Procfile index 063b78f4..5953f692 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: npm start + web: npm start diff --git a/README.md b/README.md index 5545a373..147e601e 100644 --- a/README.md +++ b/README.md @@ -1,198 +1,101 @@ -[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)](#table-of-contents) -

[๐Ÿ‡ธ ๐Ÿ‡น ๐Ÿ‡ฆ ๐Ÿ‡ท -๐Ÿ‡ฒ ๐Ÿ‡ฉ ](https://wa.me/+2347045035241) -[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)](#table-of-contents) - -Typing SVG - - -[`โ„น๏ธIN CASE OF HELP CONCERNING DEPLOYMENT -`](https://wa.me/+2347045035241) - - - -## ๐ŸŒ ```Bot Intro```๐ŸŒ  -[![STAR-MD-V2](https://i.ibb.co/x8RVYs5/20240302-120657.jpg)](https://wa.me/2347045035241) -

-

- - whatsapp - - Whatsapp

- - - -

- - - whatsapp -whatsapp - - -

- - - - -

๐ŸŒ ๐—ฆ๐—ง๐—”๐—ฅ-๐— ๐——-๐—ฉ๐Ÿฎ๐ŸŒ  -

- -### โ„น๏ธ **ABOUT STAR-MD-V2** -***STAR-MD-V2 is a ๐ŸŒŸ versatile Multi-Device WhatsApp bot ๐Ÿค– recoded by the talented [Excel Amadi](https://github.com/Xcelsama) It offers a wide array of features, making it an advanced and user-friendly bot for various purposes. ๐ŸŽ‰๐Ÿ“ฑ With its intuitive interface and robust capabilities, users can unlock endless possibilities ๐Ÿš€ and streamline their communication across devices with ease.*** - - - -

xcelsama:: Visitor's Count

- - - -## โญ `Star This Repo` -If you find STAR-MD-V2 helpful, consider giving it a star โญ to show your appreciation,Support. +# [STAR-BOT](https://github.com/Xcelsama) +
20240805-174110 +>STAR-MD-V2 is based on : +>- [GURU BOT](https://github.com/Guru322/GURU-BOT) by [Guru](https://github.com/Guru322) (License: Apache License 2.0) +> +> :octocat: Don't forget to check out! :point_right: [GURU BOT](https://github.com/Guru322/GURU-BOT) +>๐ŸคThanks to Salman & his team โ˜• -๐Ÿš€๐™ต๐™ด๐™ฐ๐šƒ๐š„๐šƒ๐™ด๐š‚๐Ÿš€ +## `BOT-INTRO` +STAR-MD-V2 is a ๐ŸŒŸ versatile Multi-Device WhatsApp bot ๐Ÿค– recoded by the talented [Excel Amadi](https://github.com/Xcelsama) It offers a wide array of features, making it an advanced and user-friendly bot for various purposes. ๐ŸŽ‰๐Ÿ“ฑ With its intuitive interface and robust capabilities, users can unlock endless possibilities ๐Ÿš€ and streamline their communication across devices with ease. +## `Features` -โ—‰ Multi-Device Support -โ—‰ AI Photo Enhancement -โ—‰ Downloader Commands -โ—‰ Hidden NSFW Commands -โ—‰ Logo Commands -โ—‰ Anime Commands -โ—‰ Economy Menu -โ—‰ Various Games -โ—‰ Audio/Video Editor Commands -โ—‰ Others...... -## ๐Ÿ› ๏ธ `Installation Procedure` +| Function | Confirmation | +------------------|-------------- +|- Free Deployment|โœ…๏ธ| +|- File Conversion|โœ…๏ธ| +|- Downloads |โœ…๏ธ| +|- Games|โœ…๏ธ| +|- Group Management|โœ…๏ธ| +|- Image features|โœ…๏ธ| +|- Weather Updates|โœ…๏ธ| +|- Reminders|โœ…๏ธ| +|- Translations|โœ…๏ธ| +|- Custom Commands|โœ…๏ธ| +|- Integration|โœ…๏ธ| +|- Customization|โœ…๏ธ| +|- Customizable | โœ…๏ธ| - -โ˜‰FORK THE REPOSITORY -
- - - - -โ—”Get Session ID (PAIR-CODE) -PAIR-CODE - - - -โ—” Get Session ID (SCAN QR) -
-SESSION ID - - -โš™๏ธŽUSE THIS IF YOU DON'T HAVE REPLIT - - Authenticate With WhatsApp - +# `SETUP PROCEDURE` -## ๐Ÿš€ `Deployments` -#### DEPLOY TO HEROKU + ## โญ๏ธ`Star This Repo` โญ๏ธ -โ˜‰ If You don't have a account in Heroku. Create a account. -
-Heroku +Give STAR-BOT a star to show your appreciation and support ๐ŸŒŸ to the Developers. -โ˜‰Now Deploy -
-DEPLOY -#### DEPLOY TO REPLIT - If You don't have an account in Replit. Create a account. -
-Heroku - Now Deploy -
- DEPLOY +## ๐ŸŽฏ `Installation Procedure` ๐ŸŽฏ +## TODO: ```Fork STAR-BOT``` + -#### DEPLOY TO CODESPACE - If You don't have a account in Codespace. Create a account. -
-Codespaces

- - Now Deploy -
-DEPLOY

- -#### DEPLOY TO OKTETO + ## TODO: ```Get SESSION_ID``` + +Pair repl -If You don't have a account in Okteto. Create a account. -
-Okteto

+## TODO: ```DEPLOYMENT``` -Now Deploy -
-DEPLOY

+>STAR-BOT CAN BE DEPLOYED ON VARIOUS HOSTING PLATFORM JUST FORK & IMPORT THE FORKED REPO ADD ENVIRONMENT VARIABLES : SESSION_ID & DATABASE_URL: MONGODB_URI -#### DEPLOY TO RAILWAY +>You must not add DATABASE_URL - If You don't have a account in Railway. Create a account. -
-Railway

+## ```STAR-BOT CAN BE DEPLOYED ON``` + + +### ```RENDER``` - Now Deploy -
-DEPLOY

+ >Create Render account using Github -#### DEPLOY TO MONGENIUS + Render

+ + >Then Import You forked Repo & Deploy +Add Environment Variables SESSION_ID & DATABASE_URL Then Click Deploy. + - If You don't have a account in Mongenius. Create a account. -
-Mongenius

+IMPORT

- Now Deploy -
-DEPLOY

+- After Deployment -#### DEPLOY TO COOLIFY +>Create Account on uptime.robot to keep the bot stable Copy the Url of the bot from render then paste in uptime.robot,I'll advice you to download the app - If You don't have a account in Coolify. Create a account. -
-Coolify

+[CREATE](https://uptimerobot.com/) + - Now Deploy -
-DEPLOY

+### ```HEROKU``` -#### DEPLOY TO RENDER +>Create Account if You don't have - If You don't have a account in Render. Create a account. -
-Render

+Heroku - Now Deploy -
-DEPLOY

+>Then Add the Environment Variables & Deploy -## `NEW DEPLOYMENT` -NOW Deploy๐Ÿ‘‡ -
-## DEPLOY IN KOYEB -[![Deploy on Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/auth/signup) -## `OWNER` -Xcelsama +DEPLOY - +### ```KOYEB``` -## ๐Ÿ”’ `Reminder` -Misusing the bot may result in a ban from WhatsApp. Use at your own risk. +>CREATE ACCOUNT THEN ADD ENVIRONMENT VARIABLES AND DEPLOY +DEPLOY + +## ```๐Ÿค THANKS TO EVERYONE THAT MADE THIS PROJECT POSSIBLE``` -## `Reminder` - -- This bot is not made by `WhatsApp Inc.` So misusing the bot might `ban` your `WhatsApp account!`(Though your WhatsApp account can be unbanned only once.) -- I am not responsible for banning your account. -- Use at your own risk by keeping this warning in mind. -[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)](#table-of-contents) -

[`๐Ÿ“กCredits`](https://github.com/salmanytofficial) -[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)](#table-of-contents) \ No newline at end of file +ยฉXcelsama 2024 diff --git a/STAR-V2.jpg b/STAR-V2.jpg new file mode 100644 index 00000000..0ea114e2 Binary files /dev/null and b/STAR-V2.jpg differ diff --git a/STAR.jpg b/STAR.jpg new file mode 100644 index 00000000..4dc2876c Binary files /dev/null and b/STAR.jpg differ diff --git a/XLICON/XLICON.js b/STAR/STAR.js similarity index 93% rename from XLICON/XLICON.js rename to STAR/STAR.js index ae94bfe5..9bde530f 100644 --- a/XLICON/XLICON.js +++ b/STAR/STAR.js @@ -1,4 +1,4 @@ /** * @STAR_V2 * https://github.com/Xcelsama/STAR-MD-V2 - */ \ No newline at end of file + */ diff --git a/XLICON/language.json b/STAR/language.json similarity index 100% rename from XLICON/language.json rename to STAR/language.json diff --git a/Termux-Guide.md b/Termux-Guide.md index 68738dee..b5e0c779 100644 --- a/Termux-Guide.md +++ b/Termux-Guide.md @@ -1,4 +1,4 @@ -# Guru-bot Termux-Hosting-Guide +# STAR-bot Termux-Hosting-Guide ## Prerequisites @@ -12,8 +12,8 @@ Run the following commands to clone the repo (Use your fork) ```SH -> git clone https://github.com/salmanytofficial/XLICON-V2-MD -> cd XLICON-V2-MD +> git clone https://github.com/Xcelsama/STAR-MD-V2 +> cd STAR-MD-V2 ``` Run this following command to install the dependencies @@ -29,4 +29,4 @@ Running the above command will start the bot. To authenticate scan the QR which shows up in the terminal using the WA-Web Scanner on your WhatsApp . Good Luck! - [Set it up on Heroku](https://github.com/salmanytofficial/XLICON-V2-MD/blob/master/Heroku-Hosting-Guide.md) + [Set it up on Heroku](https://github.com/Xcelsam/STAR-MD-V2/blob/master/Heroku-Hosting-Guide.md) diff --git a/XLICON.jpg b/XLICON.jpg deleted file mode 100644 index fa79b212..00000000 Binary files a/XLICON.jpg and /dev/null differ diff --git a/app.json b/app.json index 75e2b5be..547e9373 100644 --- a/app.json +++ b/app.json @@ -3,7 +3,7 @@ "description": "A whatsapp bot with rich functions created by Excel", "logo": "https://telegra.ph/file/f2fa9732e0e26bbb0bfb0.jpg", "keywords": [ - "whatsapp bot" + "STAR-MD-V2" ], "repository": "https://github.com/Xcelsama/STAR-MD-V2/main", "stack": "container", @@ -11,12 +11,12 @@ "DATABASE_URL": { "description": "your mongodb database url", "required": false, - "value": "mongodb+srv://salmanahmad:s4salmanyt@cluster0.szcj2eo.mongodb.net/?retryWrites=true&w=majority" + "value": "mongodb+srv://starmd:xcelsama@excel.xmckecq.mongodb.net" }, "SESSION_ID": { "description": "your session id", "required": true, - "value": "" + "value": "Xlicon_7f23553c-49be-4ede-8b4a-93b0203bfe53" }, "MODE": { "description": "mode public or private", @@ -31,7 +31,7 @@ "HKEY": { "description": "Put your Heroku api key Here , Get one from here https://dashboard.heroku.com/account", "required": true, - "value": "" + "value":" 8cf895b5-dbdf-4d5d-b2a1-b31319db8aa6" }, "HAPP": { "description": "Put the Heroku app name, same as above entered", @@ -56,7 +56,7 @@ "REMOVEBG_KEY": { "description": "your RemoveBg api key", "required": false, - "value": "" + "value": "neLbXXrp8bSDcohnp1CW5UEa" } }, "buildpacks": [ diff --git a/cai_nicknames.json b/cai_nicknames.json index 9cc0065b..4230d8ff 100644 --- a/cai_nicknames.json +++ b/cai_nicknames.json @@ -10,5 +10,5 @@ "dante": "-uwWte6vXPHCO2ytjeNa0lhBIxiETF4iZ0oO-KVjciQ", "vergil": "XUtR5xIhxarp_n5sA44Wa8_NOp-7pa0HgsltF099y0s", "krishna": "8NRtqrbGa_il09tnwolYuFJk7fmOknZEs7uDIraIgAU", - "jesus": "SAAEhhxkzNtb80wqrqr3dMGPTskr3ofyayOprzau-Os" - } \ No newline at end of file + "jesus": "SAAEhhxkzNtb80wqrqr3dMGPTskr3ofyayOprzau-Os" + } diff --git a/config.js b/config.js index b54e3e60..0933d226 100644 --- a/config.js +++ b/config.js @@ -7,15 +7,16 @@ import axios from 'axios' global.owner = [ - ['+2347045035241','Excel Amadi',true] - + ['2347045035241', 'EXCEL', true], + ['23433436666', 'Excel', true], + [''] ] //Number of owners -//global.pairingNumber = "" //put your bot number here +//global.pairingNumber = "2347045035241" //put your bot number here -global.mods = ['2347045035241'] -global.prems = ['2347045035241'] -global.allowed = ['2347045035241'] +global.mods = ['2347045035241','2348021779696'] +global.prems = ['2347045035241', '2348021779696', '2347045038687'] +global.allowed = ['2347045035241', '2348021779696', '2347045038687'] global.keysZens = ['c2459db922', '37CC845916', '6fb0eff124'] global.keysxxx = keysZens[Math.floor(keysZens.length * Math.random())] global.keysxteammm = ['29d4b59a4aa687ca', '5LTV57azwaid7dXfz5fzJu', 'cb15ed422c71a2fb', '5bd33b276d41d6b4', 'HIRO', 'kurrxd09', 'ebb6251cc00f9c63'] @@ -23,7 +24,6 @@ global.keysxteam = keysxteammm[Math.floor(keysxteammm.length * Math.random())] global.keysneoxrrr = ['5VC9rvNx', 'cfALv5'] global.keysneoxr = keysneoxrrr[Math.floor(keysneoxrrr.length * Math.random())] global.lolkeysapi = ['GataDios'] -global.beta = 'mLxstUwm' global.APIs = { // API Prefix // name: 'https://website' @@ -36,7 +36,7 @@ global.APIs = { // API Prefix akuari: 'https://api.akuari.my.id', akuari2: 'https://apimu.my.id', nrtm: 'https://fg-nrtm.ddns.net', - bg: 'http://bochil.ddns.net', + bg: 'http://bochil.ddns.net', fgmods: 'https://api-fgmods.ddns.net' } global.APIKeys = { // APIKey Here @@ -50,33 +50,34 @@ global.APIKeys = { // APIKey Here } // Sticker WM -global.botname = 'STAR-MD' +global.botname = 'ยฉSTAR-MD-V2' global.premium = 'true' -global.packname = 'Excel' -global.author = '@EXCEL' -global.menuvid = 'https://i.imgur.com/NtEhT2w.mp4' -global.igfg = 'โ–ขโœ“ Follow My channel\nhttps://whatsapp.com/channel/0029Va9wmuz8F2pGIURwmo0m' -global.dygp = 'https://chat.whatsapp.com/EmP3syvou18HrZk6R6nTAK' +global.packname = 'ยฉ๐š‚๐šƒ๐™ฐ๐š-๐™ผ๐™ณ' +global.author = '@๐™ด๐šก๐šŒ๐šŽ๐š•' +global.menuvid = 'https://i.imgur.com/BPQbguA.mp4' +global.Channel = 'https://whatsapp.com/channel/0029VaBcXo4JJhzW9c1uVD2X' +global.dygp = 'https://whatsapp.com/channel/0029VaBcXo4JJhzW9c1uVD2X' global.fgsc = 'https://github.com/Xcelsama/STAR-MD-V2' -global.fgyt = 'https://youtube.com' -global.fgpyp = 'https://youtube.com' -global.fglog = 'XLICON.jpg' -global.thumb = fs.readFileSync('./XLICON.jpg') +global.Channel2 = 'https://whatsapp.com/channel/0029VaBcXo4JJhzW9c1uVD2X' +global.Wa = 'https://wa.me/2347045035241' +global.fglog = 'STAR.jpg' +global.thumb = fs.readFileSync('./STAR.jpg') +global.shizokeys = 'shizo' -global.wait = '*๐Ÿ•ฃ _STAR IS LOADING..._*\n*โ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโญ*' +global.wait = '*๐Ÿ•’ _STAR IS LOADING WAIT..._*\n*โ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ ๐Ÿ’ซ*' global.rwait = '๐Ÿ”œ' -global.dmoji = '๐Ÿคญ' -global.done = ' โ˜‘๏ธ' +global.dmoji = 'โคต๏ธ' +global.done = 'โ˜‘๏ธ' global.error = 'โŽ' -global.xmoji = '๐Ÿ˜' +global.xmoji = 'โšก' global.multiplier = 69 -global.maxwarn = '3' // mรกxima advertencias +global.maxwarn = '3' let file = fileURLToPath(import.meta.url) watchFile(file, () => { unwatchFile(file) console.log(chalk.redBright("Update 'config.js'")) import(`${file}?update=${Date.now()}`) -}) \ No newline at end of file +}) diff --git a/docker-compose.yml b/docker-compose.yml index 8d4f5058..95232e93 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3.9" + version: "3.9" services: worker: build: . diff --git a/handler.js b/handler.js index 79266248..a20acc8f 100644 --- a/handler.js +++ b/handler.js @@ -1,759 +1,784 @@ -import { - smsg -} from "./lib/simple.js" -import { - format -} from "util" -import { - fileURLToPath -} from "url" -import path, { - join -} from "path" -import { - unwatchFile, - watchFile, - readFileSync -} from "fs" -import chalk from "chalk" -import fetch from "node-fetch" - -import { - WelcomeLeave -} from "./lib/welcome.js" +import { smsg } from './lib/simple.js' +import { format } from 'util' +import { fileURLToPath } from 'url' +import path, { join } from 'path' +import { unwatchFile, watchFile } from 'fs' +import chalk from 'chalk' +import fetch from 'node-fetch' +import Pino from 'pino' + /** * @type {import("@whiskeysockets/baileys")} */ -const isNumber = x => typeof x === "number" && !isNaN(x) -const delay = ms => isNumber(ms) && new Promise(resolve => setTimeout(function() { - clearTimeout(this) - resolve() -}, ms)) +const isNumber = x => typeof x === 'number' && !isNaN(x) +const delay = ms => + isNumber(ms) && + new Promise(resolve => + setTimeout(function () { + clearTimeout(this) + resolve() + }, ms) + ) /** * Handle messages upsert - * @param {import("@whiskeysockets/baileys").BaileysEventMap["messages.upsert"]} groupsUpdate + * @param {import("@whiskeysockets/baileys").BaileysEventMap["messages.upsert"]} groupsUpdate */ -const { - getAggregateVotesInPollMessage, - makeInMemoryStore -} = await (await import('@whiskeysockets/baileys')).default; -import Pino from "pino" +const { getAggregateVotesInPollMessage, makeInMemoryStore } = await ( + await import('@whiskeysockets/baileys') +).default const store = makeInMemoryStore({ - logger: Pino().child({ - level: 'fatal', - stream: 'store' - }) + logger: Pino().child({ + level: 'fatal', + stream: 'store', + }), }) export async function handler(chatUpdate) { - this.msgqueque = this.msgqueque || [] - if (!chatUpdate) - return - this.pushMessage(chatUpdate.messages).catch(console.error) - let m = chatUpdate.messages[chatUpdate.messages.length - 1] - if (!m) - return - if (global.db.data == null) - await global.loadDatabase() + this.msgqueque = this.msgqueque || [] + if (!chatUpdate) return + this.pushMessage(chatUpdate.messages).catch(console.error) + let m = chatUpdate.messages[chatUpdate.messages.length - 1] + if (!m) return + if (global.db.data == null) await global.loadDatabase() + try { + m = smsg(this, m) || m + if (!m) return + m.exp = 0 + m.credit = false + m.bank = false + m.chicken = false try { - m = smsg(this, m) || m - if (!m) - return - m.exp = 0 - m.credit = false - m.bank = false - m.chicken = false + // TODO: use loop to insert data instead of this + let user = global.db.data.users[m.sender] + if (typeof user !== 'object') global.db.data.users[m.sender] = {} + if (user) { + if (!isNumber(user.exp)) user.exp = 0 + if (!isNumber(user.credit)) user.credit = 10 + if (!isNumber(user.bank)) user.bank = 0 + if (!isNumber(user.chicken)) user.chicken = 0 + if (!isNumber(user.lastclaim)) user.lastclaim = 0 + if (!('registered' in user)) user.registered = false + //-- user registered + if (!user.registered) { + if (!('name' in user)) user.name = m.name + if (!isNumber(user.age)) user.age = -1 + if (!isNumber(user.regTime)) user.regTime = -1 + } + //--user number + if (!isNumber(user.afk)) user.afk = -1 + if (!('afkReason' in user)) user.afkReason = '' + if (!('banned' in user)) user.banned = false + if (!isNumber(user.warn)) user.warn = 0 + if (!isNumber(user.level)) user.level = 0 + if (!('role' in user)) user.role = 'Tadpole' + if (!('autolevelup' in user)) user.autolevelup = false + } else { + global.db.data.users[m.sender] = { + exp: 0, + credit: 0, + bank: 0, + chicken: 0, + lastclaim: 0, + registered: false, + name: m.name, + age: -1, + regTime: -1, + afk: -1, + afkReason: '', + banned: false, + warn: 0, + level: 0, + role: 'Tadpole', + autolevelup: false, + } + } + let chat = global.db.data.chats[m.chat] + if (typeof chat !== 'object') global.db.data.chats[m.chat] = {} + if (chat) { + if (!('antiDelete' in chat)) chat.antiDelete = true + if (!('antiLink' in chat)) chat.antiLink = false + if (!('antiSticker' in chat)) chat.antiSticker = false + if (!('antiToxic' in chat)) chat.antiToxic = false + if (!('detect' in chat)) chat.detect = false + if (!('getmsg' in chat)) chat.getmsg = true + if (!('isBanned' in chat)) chat.isBanned = false + if (!('nsfw' in chat)) chat.nsfw = false + if (!('sBye' in chat)) chat.sBye = '' + if (!('sDemote' in chat)) chat.sDemote = '' + if (!('simi' in chat)) chat.simi = false + if (!('sPromote' in chat)) chat.sPromote = '' + if (!('sWelcome' in chat)) chat.sWelcome = '' + if (!('useDocument' in chat)) chat.useDocument = false + if (!('viewOnce' in chat)) chat.viewOnce = false + if (!('viewStory' in chat)) chat.viewStory = false + if (!('welcome' in chat)) chat.welcome = false + if (!('chatbot' in chat)) chat.chatbot = false + if (!isNumber(chat.expired)) chat.expired = 0 + } else + global.db.data.chats[m.chat] = { + antiDelete: true, + antiLink: false, + antiSticker: false, + antiToxic: false, + detect: false, + expired: 0, + getmsg: true, + isBanned: false, + nsfw: false, + sBye: '', + sDemote: '', + simi: false, + sPromote: '', + sticker: false, + sWelcome: '', + useDocument: false, + viewOnce: false, + viewStory: false, + welcome: false, + chatbot: false, + } + + let settings = global.db.data.settings[this.user.jid] + if (typeof settings !== 'object') global.db.data.settings[this.user.jid] = {} + if (settings) { + if (!('self' in settings)) settings.self = false + if (!('autoread' in settings)) settings.autoread = false + if (!('restrict' in settings)) settings.restrict = false + if (!('restartDB' in settings)) settings.restartDB = 0 + if (!('status' in settings)) settings.status = 0 + } else + global.db.data.settings[this.user.jid] = { + self: false, + autoread: false, + restrict: false, + restartDB: 0, + status: 0, + } + } catch (e) { + console.error(e) + } + if (opts['nyimak']) return + if (opts['pconly'] && m.chat.endsWith('g.us')) return + if (opts['gconly'] && !m.chat.endsWith('g.us')) return + if (opts['swonly'] && m.chat !== 'status@broadcast') return + if (typeof m.text !== 'string') m.text = '' + + const isROwner = [ + conn.decodeJid(global.conn.user.id), + ...global.owner.map(([number]) => number), + ] + .map(v => v.replace(/[^0-9]/g, '') + '@s.whatsapp.net') + .includes(m.sender) + const isOwner = isROwner || m.fromMe + const isMods = + isOwner || + global.mods.map(v => v.replace(/[^0-9]/g, '') + '@s.whatsapp.net').includes(m.sender) + const isPrems = + isROwner || + global.prems.map(v => v.replace(/[^0-9]/g, '') + '@s.whatsapp.net').includes(m.sender) + + if (opts['queque'] && m.text && !(isMods || isPrems)) { + let queque = this.msgqueque, + time = 1000 * 5 + const previousID = queque[queque.length - 1] + queque.push(m.id || m.key.id) + setInterval(async function () { + if (queque.indexOf(previousID) === -1) clearInterval(this) + await delay(time) + }, time) + } + if (process.env.MODE && process.env.MODE.toLowerCase() === 'private' && !(isROwner || isOwner)) + return + + if (m.isBaileys) return + m.exp += Math.ceil(Math.random() * 10) + + let usedPrefix + let _user = global.db.data && global.db.data.users && global.db.data.users[m.sender] + + const groupMetadata = + (m.isGroup + ? (conn.chats[m.chat] || {}).metadata || (await this.groupMetadata(m.chat).catch(_ => null)) + : {}) || {} + const participants = (m.isGroup ? groupMetadata.participants : []) || [] + const user = (m.isGroup ? participants.find(u => conn.decodeJid(u.id) === m.sender) : {}) || {} // User Data + const bot = + (m.isGroup ? participants.find(u => conn.decodeJid(u.id) == conn.user.jid) : {}) || {} // Your Data + const isRAdmin = user?.admin == 'superadmin' || false + const isAdmin = isRAdmin || user?.admin == 'admin' || false // Is User Admin? + const isBotAdmin = bot?.admin || false // Are you Admin? + + const ___dirname = path.join(path.dirname(fileURLToPath(import.meta.url)), './plugins') + for (let name in global.plugins) { + let plugin = global.plugins[name] + if (!plugin) continue + if (plugin.disabled) continue + const __filename = join(___dirname, name) + if (typeof plugin.all === 'function') { try { - // TODO: use loop to insert data instead of this - let user = global.db.data.users[m.sender] - if (typeof user !== "object") - global.db.data.users[m.sender] = {} - if (user) { - if (!isNumber(user.exp)) - user.exp = 0 - if (!isNumber(user.credit)) - user.credit = 10 - if (!isNumber(user.bank)) - user.bank = 0 - if (!isNumber(user.chicken)) - user.chicken = 0 - if (!isNumber(user.lastclaim)) - user.lastclaim = 0 - if (!('registered' in user)) - user.registered = false - //-- user registered - if (!user.registered) { - if (!('name' in user)) - user.name = m.name - if (!isNumber(user.age)) - user.age = -1 - if (!isNumber(user.regTime)) - user.regTime = -1 - } - //--user number - if (!isNumber(user.afk)) - user.afk = -1 - if (!('afkReason' in user)) - user.afkReason = '' - if (!('banned' in user)) - user.banned = false - if (!isNumber(user.warn)) - user.warn = 0 - if (!isNumber(user.level)) - user.level = 0 - if (!('role' in user)) - user.role = 'Tadpole' - if (!('autolevelup' in user)) - user.autolevelup = false - } else { - global.db.data.users[m.sender] = { - exp: 0, - credit: 0, - bank: 0, - chicken: 0, - lastclaim: 0, - registered: false, - name: m.name, - age: -1, - regTime: -1, - afk: -1, - afkReason: '', - banned: false, - warn: 0, - level: 0, - role: 'Tadpole', - autolevelup: false, - - } - } - let chat = global.db.data.chats[m.chat] - if (typeof chat !== "object") - global.db.data.chats[m.chat] = {} - if (chat) { - if (!("antiDelete" in chat)) chat.antiDelete = true - if (!("antiLink" in chat)) chat.antiLink = false - if (!("antiSticker" in chat)) chat.antiSticker = false - if (!("antiToxic" in chat)) chat.antiToxic = false - if (!("detect" in chat)) chat.detect = false - if (!("getmsg" in chat)) chat.getmsg = true - if (!("isBanned" in chat)) chat.isBanned = false - if (!("nsfw" in chat)) chat.nsfw = false - if (!("sBye" in chat)) chat.sBye = "" - if (!("sDemote" in chat)) chat.sDemote = "" - if (!("simi" in chat)) chat.simi = false - if (!("sPromote" in chat)) chat.sPromote = "" - if (!("sWelcome" in chat)) chat.sWelcome = "" - if (!("useDocument" in chat)) chat.useDocument = false - if (!("viewOnce" in chat)) chat.viewOnce = false - if (!("viewStory" in chat)) chat.viewStory = false - if (!("welcome" in chat)) chat.welcome = false - if (!("chatbot" in chat)) chat.chatbot = false - if (!isNumber(chat.expired)) chat.expired = 0 - } else - global.db.data.chats[m.chat] = { - antiDelete: true, - antiLink: false, - antiSticker: false, - antiToxic: false, - detect: false, - expired: 0, - getmsg: true, - isBanned: false, - nsfw: false, - sBye: "", - sDemote: "", - simi: false, - sPromote: "", - sticker: false, - sWelcome: "", - useDocument: false, - viewOnce: false, - viewStory: false, - welcome: false, - chatbot: false - } - - - let settings = global.db.data.settings[this.user.jid] - if (typeof settings !== "object") global.db.data.settings[this.user.jid] = {} - if (settings) { - if (!("self" in settings)) settings.self = false - if (!("autoread" in settings)) settings.autoread = false - if (!("restrict" in settings)) settings.restrict = false - if (!("restartDB" in settings)) settings.restartDB = 0 - if (!("status" in settings)) settings.status = 0 - - } else global.db.data.settings[this.user.jid] = { - self: false, - autoread: false, - restrict: false, - restartDB: 0, - status: 0 - } + await plugin.all.call(this, m, { + chatUpdate, + __dirname: ___dirname, + __filename, + }) } catch (e) { - console.error(e) + // if (typeof e === "string") continue + console.error(e) + for (let [jid] of global.owner.filter( + ([number, _, isDeveloper]) => isDeveloper && number + )) { + let data = (await conn.onWhatsApp(jid))[0] || {} + if (data.exists) + m.reply( + `*๐Ÿ—‚๏ธ Plugin:* ${name}\n*๐Ÿ‘ค Sender:* ${m.sender}\n*๐Ÿ’ฌ Chat:* ${m.chat}\n*๐Ÿ’ป Command:* ${m.text}\n\n\${format(e)}`.trim(), + data.jid + ) + } } - if (opts["nyimak"]) - return - if (opts["pconly"] && m.chat.endsWith("g.us")) - return - if (opts["gconly"] && !m.chat.endsWith("g.us")) - return - if (opts["swonly"] && m.chat !== "status@broadcast") - return - if (typeof m.text !== "string") - m.text = "" - - const isROwner = [conn.decodeJid(global.conn.user.id), ...global.owner.map(([number]) => number)].map(v => v.replace(/[^0-9]/g, "") + "@s.whatsapp.net").includes(m.sender) - const isOwner = isROwner || m.fromMe - const isMods = isOwner || global.mods.map(v => v.replace(/[^0-9]/g, "") + "@s.whatsapp.net").includes(m.sender) - const isPrems = isROwner || global.prems.map(v => v.replace(/[^0-9]/g, "") + "@s.whatsapp.net").includes(m.sender) - - if (opts["queque"] && m.text && !(isMods || isPrems)) { - let queque = this.msgqueque, - time = 1000 * 5 - const previousID = queque[queque.length - 1] - queque.push(m.id || m.key.id) - setInterval(async function() { - if (queque.indexOf(previousID) === -1) clearInterval(this) - await delay(time) - }, time) + } + if (!opts['restrict']) + if (plugin.tags && plugin.tags.includes('admin')) { + // global.dfail("restrict", m, this) + continue } - if (process.env.MODE && process.env.MODE.toLowerCase() === 'private' && !(isROwner || isOwner)) - return; - - - if (m.isBaileys) - return - m.exp += Math.ceil(Math.random() * 10) - - let usedPrefix - let _user = global.db.data && global.db.data.users && global.db.data.users[m.sender] - - const groupMetadata = (m.isGroup ? ((conn.chats[m.chat] || {}).metadata || await this.groupMetadata(m.chat).catch(_ => null)) : {}) || {} - const participants = (m.isGroup ? groupMetadata.participants : []) || [] - const user = (m.isGroup ? participants.find(u => conn.decodeJid(u.id) === m.sender) : {}) || {} // User Data - const bot = (m.isGroup ? participants.find(u => conn.decodeJid(u.id) == conn.user.jid) : {}) || {} // Your Data - const isRAdmin = user?.admin == "superadmin" || false - const isAdmin = isRAdmin || user?.admin == "admin" || false // Is User Admin? - const isBotAdmin = bot?.admin || false // Are you Admin? - - const ___dirname = path.join(path.dirname(fileURLToPath(import.meta.url)), "./plugins") - for (let name in global.plugins) { - let plugin = global.plugins[name] - if (!plugin) - continue - if (plugin.disabled) - continue - const __filename = join(___dirname, name) - if (typeof plugin.all === "function") { - try { - await plugin.all.call(this, m, { - chatUpdate, - __dirname: ___dirname, - __filename - }) - } catch (e) { - // if (typeof e === "string") continue - console.error(e) - for (let [jid] of global.owner.filter(([number, _, isDeveloper]) => isDeveloper && number)) { - let data = (await conn.onWhatsApp(jid))[0] || {} - if (data.exists) - m.reply(`*๐Ÿ—‚๏ธ Plugin:* ${name}\n*๐Ÿ‘ค Sender:* ${m.sender}\n*๐Ÿ’ฌ Chat:* ${m.chat}\n*๐Ÿ’ป Command:* ${m.text}\n\n\${format(e)}`.trim(), data.jid) - } - } - } - if (!opts["restrict"]) - if (plugin.tags && plugin.tags.includes("admin")) { - // global.dfail("restrict", m, this) - continue - } - const str2Regex = str => str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&") - let _prefix = plugin.customPrefix ? plugin.customPrefix : conn.prefix ? conn.prefix : global.prefix - let match = (_prefix instanceof RegExp ? // RegExp Mode? - [ - [_prefix.exec(m.text), _prefix] - ] : - Array.isArray(_prefix) ? // Array? - _prefix.map(p => { - let re = p instanceof RegExp ? // RegExp in Array? - p : - new RegExp(str2Regex(p)) - return [re.exec(m.text), re] - }) : - typeof _prefix === "string" ? // String? - [ - [new RegExp(str2Regex(_prefix)).exec(m.text), new RegExp(str2Regex(_prefix))] - ] : [ - [ - [], new RegExp - ] - ] - ).find(p => p[1]) - if (typeof plugin.before === "function") { - if (await plugin.before.call(this, m, { - match, - conn: this, - participants, - groupMetadata, - user, - bot, - isROwner, - isOwner, - isRAdmin, - isAdmin, - isBotAdmin, - isPrems, - chatUpdate, - __dirname: ___dirname, - __filename - })) - continue - } - if (typeof plugin !== "function") - continue - if ((usedPrefix = (match[0] || "")[0])) { - let noPrefix = m.text.replace(usedPrefix, "") - let [command, ...args] = noPrefix.trim().split` `.filter(v => v) - args = args || [] - let _args = noPrefix.trim().split` `.slice(1) - let text = _args.join` ` - command = (command || "").toLowerCase() - let fail = plugin.fail || global.dfail // When failed - let isAccept = plugin.command instanceof RegExp ? // RegExp Mode? - plugin.command.test(command) : - Array.isArray(plugin.command) ? // Array? - plugin.command.some(cmd => cmd instanceof RegExp ? // RegExp in Array? - cmd.test(command) : - cmd === command - ) : - typeof plugin.command === "string" ? // String? - plugin.command === command : - false - - if (!isAccept) - continue - m.plugin = name - if (m.chat in global.db.data.chats || m.sender in global.db.data.users) { - let chat = global.db.data.chats[m.chat] - let user = global.db.data.users[m.sender] - if (name != "owner-unbanchat.js" && chat?.isBanned) - return // Except this - if (name != "owner-unbanuser.js" && user?.banned) - return - } - if (plugin.rowner && plugin.owner && !(isROwner || isOwner)) { // Both Owner - fail("owner", m, this) - continue - } - if (plugin.rowner && !isROwner) { // Real Owner - fail("rowner", m, this) - continue - } - if (plugin.owner && !isOwner) { // Number Owner - fail("owner", m, this) - continue - } - if (plugin.mods && !isMods) { // Moderator - fail("mods", m, this) - continue - } - if (plugin.premium && !isPrems) { // Premium - fail("premium", m, this) - continue - } - if (plugin.group && !m.isGroup) { // Group Only - fail("group", m, this) - continue - } else if (plugin.botAdmin && !isBotAdmin) { // You Admin - fail("botAdmin", m, this) - continue - } else if (plugin.admin && !isAdmin) { // User Admin - fail("admin", m, this) - continue - } - if (plugin.private && m.isGroup) { // Private Chat Only - fail("private", m, this) - continue - } - if (plugin.register == true && _user.registered == false) { // Butuh daftar? - fail("unreg", m, this) - continue - } - m.isCommand = true - let xp = 'exp' in plugin ? parseInt(plugin.exp) : 17 // XP Earning per command - if (xp > 200) - m.reply('cheater') - else - m.exp += xp - if (!isPrems && plugin.credit && global.db.data.users[m.sender].credit < plugin.credit * 1) { - this.reply(m.chat, `๐ŸŸฅ You don't have enough gold`, m) - continue // Gold finished - } - if (plugin.level > _user.level) { - this.reply(m.chat, `๐ŸŸฅ Level required ${plugin.level} to use this command. \nYour level ${_user.level}`, m) - continue // If the level has not been reached - } - let extra = { - match, - usedPrefix, - noPrefix, - _args, - args, - command, - text, - conn: this, - participants, - groupMetadata, - user, - bot, - isROwner, - isOwner, - isRAdmin, - isAdmin, - isBotAdmin, - isPrems, - chatUpdate, - __dirname: ___dirname, - __filename - } - try { - await plugin.call(this, m, extra) - if (!isPrems) - m.credit = m.credit || plugin.credit || false - } catch (e) { - // Error occured - m.error = e - console.error(e) - if (e) { - let text = format(e) - for (let key of Object.values(global.APIKeys)) - text = text.replace(new RegExp(key, "g"), "#HIDDEN#") - if (e.name) - for (let [jid] of global.owner.filter(([number, _, isDeveloper]) => isDeveloper && number)) { - let data = (await this.onWhatsApp(jid))[0] || {} - if (data.exists) - return m.reply(`*๐Ÿ—‚๏ธ Plugin:* ${m.plugin}\n*๐Ÿ‘ค Sender:* ${m.sender}\n*๐Ÿ’ฌ Chat:* ${m.chat}\n*๐Ÿ’ป Command:* ${usedPrefix}${command} ${args.join(" ")}\n๐Ÿ“„ *Error Logs:*\n\n${text}`.trim(), data.jid) - } - m.reply(text) - } - } finally { - // m.reply(util.format(_user)) - if (typeof plugin.after === "function") { - try { - await plugin.after.call(this, m, extra) - } catch (e) { - console.error(e) - } - } - if (m.credit) - m.reply(`You used *${+m.credit}*`) - } - break - } + const str2Regex = str => str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + let _prefix = plugin.customPrefix + ? plugin.customPrefix + : conn.prefix + ? conn.prefix + : global.prefix + let match = ( + _prefix instanceof RegExp // RegExp Mode? + ? [[_prefix.exec(m.text), _prefix]] + : Array.isArray(_prefix) // Array? + ? _prefix.map(p => { + let re = + p instanceof RegExp // RegExp in Array? + ? p + : new RegExp(str2Regex(p)) + return [re.exec(m.text), re] + }) + : typeof _prefix === 'string' // String? + ? [[new RegExp(str2Regex(_prefix)).exec(m.text), new RegExp(str2Regex(_prefix))]] + : [[[], new RegExp()]] + ).find(p => p[1]) + if (typeof plugin.before === 'function') { + if ( + await plugin.before.call(this, m, { + match, + conn: this, + participants, + groupMetadata, + user, + bot, + isROwner, + isOwner, + isRAdmin, + isAdmin, + isBotAdmin, + isPrems, + chatUpdate, + __dirname: ___dirname, + __filename, + }) + ) + continue + } + if (typeof plugin !== 'function') continue + if ((usedPrefix = (match[0] || '')[0])) { + let noPrefix = m.text.replace(usedPrefix, '') + let [command, ...args] = noPrefix.trim().split` `.filter(v => v) + args = args || [] + let _args = noPrefix.trim().split` `.slice(1) + let text = _args.join` ` + command = (command || '').toLowerCase() + let fail = plugin.fail || global.dfail // When failed + let isAccept = + plugin.command instanceof RegExp // RegExp Mode? + ? plugin.command.test(command) + : Array.isArray(plugin.command) // Array? + ? plugin.command.some(cmd => + cmd instanceof RegExp // RegExp in Array? + ? cmd.test(command) + : cmd === command + ) + : typeof plugin.command === 'string' // String? + ? plugin.command === command + : false + + if (!isAccept) continue + m.plugin = name + if (m.chat in global.db.data.chats || m.sender in global.db.data.users) { + let chat = global.db.data.chats[m.chat] + let user = global.db.data.users[m.sender] + if (name != 'owner-unbanchat.js' && chat?.isBanned) return // Except this + if (name != 'owner-unbanuser.js' && user?.banned) return } - } catch (e) { - console.error(e) - } finally { - if (opts["queque"] && m.text) { - const quequeIndex = this.msgqueque.indexOf(m.id || m.key.id) - if (quequeIndex !== -1) - this.msgqueque.splice(quequeIndex, 1) + if (plugin.rowner && plugin.owner && !(isROwner || isOwner)) { + // Both Owner + fail('owner', m, this) + continue } - //console.log(global.db.data.users[m.sender]) - let user, stats = global.db.data.stats - if (m) { - if (m.sender && (user = global.db.data.users[m.sender])) { - user.exp += m.exp - user.credit -= m.credit * 1 - user.bank -= m.bank - user.chicken -= m.chicken - } - - let stat - if (m.plugin) { - let now = +new Date - if (m.plugin in stats) { - stat = stats[m.plugin] - if (!isNumber(stat.total)) - stat.total = 1 - if (!isNumber(stat.success)) - stat.success = m.error != null ? 0 : 1 - if (!isNumber(stat.last)) - stat.last = now - if (!isNumber(stat.lastSuccess)) - stat.lastSuccess = m.error != null ? 0 : now - } else - stat = stats[m.plugin] = { - total: 1, - success: m.error != null ? 0 : 1, - last: now, - lastSuccess: m.error != null ? 0 : now - } - stat.total += 1 - stat.last = now - if (m.error == null) { - stat.success += 1 - stat.lastSuccess = now - } - } + if (plugin.rowner && !isROwner) { + // Real Owner + fail('rowner', m, this) + continue + } + if (plugin.owner && !isOwner) { + // Number Owner + fail('owner', m, this) + continue + } + if (plugin.mods && !isMods) { + // Moderator + fail('mods', m, this) + continue + } + if (plugin.premium && !isPrems) { + // Premium + fail('premium', m, this) + continue + } + if (plugin.group && !m.isGroup) { + // Group Only + fail('group', m, this) + continue + } else if (plugin.botAdmin && !isBotAdmin) { + // You Admin + fail('botAdmin', m, this) + continue + } else if (plugin.admin && !isAdmin) { + // User Admin + fail('admin', m, this) + continue + } + if (plugin.private && m.isGroup) { + // Private Chat Only + fail('private', m, this) + continue + } + if (plugin.register == true && _user.registered == false) { + // Butuh daftar? + fail('unreg', m, this) + continue + } + m.isCommand = true + let xp = 'exp' in plugin ? parseInt(plugin.exp) : 17 // XP Earning per command + if (xp > 200) m.reply('cheater') + else m.exp += xp + if ( + !isPrems && + plugin.credit && + global.db.data.users[m.sender].credit < plugin.credit * 1 + ) { + this.reply(m.chat, `๐ŸŸฅ You don't have enough gold`, m) + continue // Gold finished + } + if (plugin.level > _user.level) { + this.reply( + m.chat, + `๐ŸŸฅ Level required ${plugin.level} to use this command. \nYour level ${_user.level}`, + m + ) + continue // If the level has not been reached + } + let extra = { + match, + usedPrefix, + noPrefix, + _args, + args, + command, + text, + conn: this, + participants, + groupMetadata, + user, + bot, + isROwner, + isOwner, + isRAdmin, + isAdmin, + isBotAdmin, + isPrems, + chatUpdate, + __dirname: ___dirname, + __filename, } - try { - if (!opts["noprint"]) await (await import("./lib/print.js")).default(m, this) + await plugin.call(this, m, extra) + if (!isPrems) m.credit = m.credit || plugin.credit || false } catch (e) { - console.log(m, m.quoted, e) + // Error occured + m.error = e + console.error(e) + if (e) { + let text = format(e) + for (let key of Object.values(global.APIKeys)) + text = text.replace(new RegExp(key, 'g'), '#HIDDEN#') + if (e.name) + for (let [jid] of global.owner.filter( + ([number, _, isDeveloper]) => isDeveloper && number + )) { + let data = (await this.onWhatsApp(jid))[0] || {} + if (data.exists) + return m.reply( + `*๐Ÿ—‚๏ธ Plugin:* ${m.plugin}\n*๐Ÿ‘ค Sender:* ${m.sender}\n*๐Ÿ’ฌ Chat:* ${m.chat}\n*๐Ÿ’ป Command:* ${usedPrefix}${command} ${args.join(' ')}\n๐Ÿ“„ *Error Logs:*\n\n${text}`.trim(), + data.jid + ) + } + m.reply(text) + } + } finally { + // m.reply(util.format(_user)) + if (typeof plugin.after === 'function') { + try { + await plugin.after.call(this, m, extra) + } catch (e) { + console.error(e) + } + } + if (m.credit) m.reply(`You used *${+m.credit}*`) } - if (process.env.autoRead) - await conn.readMessages([m.key]) - if (process.env.statusview && m.key.remoteJid === 'status@broadcast') - await conn.readMessages([m.key]) + break + } + } + } catch (e) { + console.error(e) + } finally { + if (opts['queque'] && m.text) { + const quequeIndex = this.msgqueque.indexOf(m.id || m.key.id) + if (quequeIndex !== -1) this.msgqueque.splice(quequeIndex, 1) + } + //console.log(global.db.data.users[m.sender]) + let user, + stats = global.db.data.stats + if (m) { + if (m.sender && (user = global.db.data.users[m.sender])) { + user.exp += m.exp + user.credit -= m.credit * 1 + user.bank -= m.bank + user.chicken -= m.chicken + } + + let stat + if (m.plugin) { + let now = +new Date() + if (m.plugin in stats) { + stat = stats[m.plugin] + if (!isNumber(stat.total)) stat.total = 1 + if (!isNumber(stat.success)) stat.success = m.error != null ? 0 : 1 + if (!isNumber(stat.last)) stat.last = now + if (!isNumber(stat.lastSuccess)) stat.lastSuccess = m.error != null ? 0 : now + } else + stat = stats[m.plugin] = { + total: 1, + success: m.error != null ? 0 : 1, + last: now, + lastSuccess: m.error != null ? 0 : now, + } + stat.total += 1 + stat.last = now + if (m.error == null) { + stat.success += 1 + stat.lastSuccess = now + } + } + } + + try { + if (!opts['noprint']) await (await import('./lib/print.js')).default(m, this) + } catch (e) { + console.log(m, m.quoted, e) } + if (process.env.autoRead) await conn.readMessages([m.key]) + if (process.env.statusview && m.key.remoteJid === 'status@broadcast') + await conn.readMessages([m.key]) + } } /** * Handle groups participants update - * @param {import("@whiskeysockets/baileys").BaileysEventMap["group-participants.update"]} groupsUpdate + * @param {import("@whiskeysockets/baileys").BaileysEventMap["group-participants.update"]} groupsUpdate */ -export async function participantsUpdate({ - id, - participants, - action -}) { - if (opts["self"] || this.isInit) return; - if (global.db.data == null) await loadDatabase(); - const chat = global.db.data.chats[id] || {}; - const emoji = { - promote: '๐Ÿ‘ค๐Ÿ‘‘', - demote: '๐Ÿ‘ค๐Ÿ™…โ€โ™‚๏ธ', - welcome: '๐Ÿ‘‹', - bye: '๐Ÿ‘‹', - bug: '๐Ÿ›', - mail: '๐Ÿ“ฎ', - owner: '๐Ÿ‘‘' - }; - - - - switch (action) { - case 'add': - if (chat.welcome) { - let groupMetadata = await this.groupMetadata(id) || (conn.chats[id] || {}).metadata; - for (let user of participants) { - let pp, ppgp; - try { - pp = await this.profilePictureUrl(user, 'image'); - ppgp = await this.profilePictureUrl(id, 'image'); - } catch (error) { - console.error(`Error retrieving profile picture: ${error}`); - pp = 'https://i.imgur.com/8B4jwGq.jpeg'; // Assign default image URL - ppgp = 'https://i.imgur.com/8B4jwGq.jpeg'; // Assign default image URL - } finally { - let text = (chat.sWelcome || this.welcome || conn.welcome || 'Welcome, @user') - .replace('@group', await this.getName(id)) - .replace('@desc', groupMetadata.desc?.toString() || 'error') - .replace('@user', '@' + user.split('@')[0]); - - let nthMember = groupMetadata.participants.length; - let secondText = `Welcome, ${await this.getName(user)}, our ${nthMember}th member`; - - let welcomeApiUrl = `https://wecomeapi.onrender.com/welcome-image?username=${encodeURIComponent( - await this.getName(user) - )}&guildName=${encodeURIComponent(await this.getName(id))}&guildIcon=${encodeURIComponent( - ppgp - )}&memberCount=${encodeURIComponent( - nthMember.toString() - )}&avatar=${encodeURIComponent(pp)}&background=${encodeURIComponent( - 'https://cdn.wallpapersafari.com/71/19/7ZfcpT.png' - )}`; - - try { - let welcomeResponse = await fetch(welcomeApiUrl); - let welcomeBuffer = await welcomeResponse.buffer(); - - this.sendMessage(id, { - text: text, - contextInfo: { - mentionedJid: [user], - externalAdReply: { - title: "XLICON-V2", - body: "welcome to our Group", - thumbnailUrl: welcomeApiUrl, - sourceUrl: 'https://chat.whatsapp.com/C4ivwZKuh5bLJkqfYNPQsk', - mediaType: 1, - renderLargerThumbnail: true - }}}) - } catch (error) { - console.error(`Error generating welcome image: ${error}`); - } - } - } +export async function participantsUpdate({ id, participants, action }) { + if (opts['self'] || this.isInit) return + if (global.db.data == null) await loadDatabase() + const chat = global.db.data.chats[id] || {} + const emoji = { + promote: '๐Ÿ‘ค๐Ÿ‘‘', + demote: '๐Ÿ‘ค๐Ÿ™…โ€โ™‚๏ธ', + welcome: '๐Ÿ‘‹', + bye: '๐Ÿ‘‹', + bug: '๐Ÿ›', + mail: '๐Ÿ“ฎ', + owner: '๐Ÿ‘‘', + } + + switch (action) { + case 'add': + if (chat.welcome) { + let groupMetadata = (await this.groupMetadata(id)) || (conn.chats[id] || {}).metadata + for (let user of participants) { + let pp, ppgp + try { + pp = await this.profilePictureUrl(user, 'image') + ppgp = await this.profilePictureUrl(id, 'image') + } catch (error) { + console.error(`Error retrieving profile picture: ${error}`) + pp = 'https://i.imgur.com/8B4jwGq.jpeg' // Assign default image URL + ppgp = 'https://i.imgur.com/8B4jwGq.jpeg' // Assign default image URL + } finally { + let text = (chat.sWelcome || this.welcome || conn.welcome || 'Welcome, @user') + .replace('@group', await this.getName(id)) + .replace('@desc', groupMetadata.desc?.toString() || 'error') + .replace('@user', '@' + user.split('@')[0]) + + let nthMember = groupMetadata.participants.length + let secondText = `Welcome, ${await this.getName(user)}, our ${nthMember}th member` + + let welcomeApiUrl = `https://welcome.guruapi.tech/welcome-image?username=${encodeURIComponent( + await this.getName(user) + )}&guildName=${encodeURIComponent(await this.getName(id))}&guildIcon=${encodeURIComponent( + ppgp + )}&memberCount=${encodeURIComponent( + nthMember.toString() + )}&avatar=${encodeURIComponent(pp)}&background=${encodeURIComponent( + 'https://cdn.wallpapersafari.com/71/19/7ZfcpT.png' + )}` + + try { + let welcomeResponse = await fetch(welcomeApiUrl) + let welcomeBuffer = await welcomeResponse.buffer() + + this.sendMessage(id, { + text: text, + contextInfo: { + mentionedJid: [user], + externalAdReply: { + title: 'แด›สœแด‡ ษขแดœส€แดœ-ส™แดแด›', + body: 'welcome to Group', + thumbnailUrl: welcomeApiUrl, + sourceUrl: 'https://chat.whatsapp.com/F3sB3pR3tClBvVmlIkqDJp', + mediaType: 1, + renderLargerThumbnail: true, + }, + }, + }) + } catch (error) { + console.error(`Error generating welcome image: ${error}`) } - break; - - case 'remove': - if (chat.welcome) { - let groupMetadata = await this.groupMetadata(id) || (conn.chats[id] || {}).metadata; - for (let user of participants) { - let pp, ppgp; - try { - pp = await this.profilePictureUrl(user, 'image'); - ppgp = await this.profilePictureUrl(id, 'image'); - } catch (error) { - console.error(`Error retrieving profile picture: ${error}`); - pp = 'https://i.imgur.com/8B4jwGq.jpeg'; // Assign default image URL - ppgp = 'https://i.imgur.com/8B4jwGq.jpeg'; // Assign default image URL - } finally { - let text = (chat.sBye || this.bye || conn.bye || 'HELLO, @user') - .replace('@user', '@' + user.split('@')[0]); - - let nthMember = groupMetadata.participants.length; - let secondText = `Goodbye, our ${nthMember}th group member`; - - let leaveApiUrl = `https://wecomeapi.onrender.com/leave-image?username=${encodeURIComponent( - await this.getName(user) - )}&guildName=${encodeURIComponent(await this.getName(id))}&guildIcon=${encodeURIComponent( - ppgp - )}&memberCount=${encodeURIComponent( - nthMember.toString() - )}&avatar=${encodeURIComponent(pp)}&background=${encodeURIComponent( - 'https://cdn.wallpapersafari.com/71/19/7ZfcpT.png' - )}`; - - try { - let leaveResponse = await fetch(leaveApiUrl); - let leaveBuffer = await leaveResponse.buffer(); - - this.sendMessage(id, { - text: text, - contextInfo: { - mentionedJid: [user], - externalAdReply: { - title: "XLICON-V2 BOT", - body: "Goodbye from our Group", - thumbnailUrl: leaveApiUrl, - sourceUrl: 'https://chat.whatsapp.com/BfH0KLkICn2BjmGFMRcGMW', - mediaType: 1, - renderLargerThumbnail: true - }}}) - } catch (error) { - console.error(`Error generating leave image: ${error}`); - } - } - } + } + } + } + break + + case 'remove': + if (chat.welcome) { + let groupMetadata = (await this.groupMetadata(id)) || (conn.chats[id] || {}).metadata + for (let user of participants) { + let pp, ppgp + try { + pp = await this.profilePictureUrl(user, 'image') + ppgp = await this.profilePictureUrl(id, 'image') + } catch (error) { + console.error(`Error retrieving profile picture: ${error}`) + pp = 'https://i.imgur.com/8B4jwGq.jpeg' // Assign default image URL + ppgp = 'https://i.imgur.com/8B4jwGq.jpeg' // Assign default image URL + } finally { + let text = (chat.sBye || this.bye || conn.bye || 'HELLO, @user').replace( + '@user', + '@' + user.split('@')[0] + ) + + let nthMember = groupMetadata.participants.length + let secondText = `Goodbye, our ${nthMember}th group member` + + let leaveApiUrl = `https://welcome.guruapi.tech/leave-image?username=${encodeURIComponent( + await this.getName(user) + )}&guildName=${encodeURIComponent(await this.getName(id))}&guildIcon=${encodeURIComponent( + ppgp + )}&memberCount=${encodeURIComponent( + nthMember.toString() + )}&avatar=${encodeURIComponent(pp)}&background=${encodeURIComponent( + 'https://cdn.wallpapersafari.com/71/19/7ZfcpT.png' + )}` + + try { + let leaveResponse = await fetch(leaveApiUrl) + let leaveBuffer = await leaveResponse.buffer() + + this.sendMessage(id, { + text: text, + contextInfo: { + mentionedJid: [user], + externalAdReply: { + title: 'แด›สœแด‡ ษขแดœส€แดœ-ส™แดแด›', + body: 'Goodbye from Group', + thumbnailUrl: leaveApiUrl, + sourceUrl: 'https://chat.whatsapp.com/F3sB3pR3tClBvVmlIkqDJp', + mediaType: 1, + renderLargerThumbnail: true, + }, + }, + }) + } catch (error) { + console.error(`Error generating leave image: ${error}`) } - break; - case "promote": - const promoteText = (chat.sPromote || this.spromote || conn.spromote || `${emoji.promote} @user *is now admin*`).replace("@user", "@" + participants[0].split("@")[0]); - if (chat.detect) { - this.sendMessage(id, { - text: promoteText.trim(), - mentions: [participants[0]] - }); - } - break; - case "demote": - const demoteText = (chat.sDemote || this.sdemote || conn.sdemote || `${emoji.demote} @user *demoted from admin*`).replace("@user", "@" + participants[0].split("@")[0]); - if (chat.detect) { - this.sendMessage(id, { - text: demoteText.trim(), - mentions: [participants[0]] - }); - } - break; - } + } + } + } + break + case 'promote': + const promoteText = ( + chat.sPromote || + this.spromote || + conn.spromote || + `${emoji.promote} @user *is now admin*` + ).replace('@user', '@' + participants[0].split('@')[0]) + + if (chat.detect) { + this.sendMessage(id, { + text: promoteText.trim(), + mentions: [participants[0]], + }) + } + break + case 'demote': + const demoteText = ( + chat.sDemote || + this.sdemote || + conn.sdemote || + `${emoji.demote} @user *demoted from admin*` + ).replace('@user', '@' + participants[0].split('@')[0]) + + if (chat.detect) { + this.sendMessage(id, { + text: demoteText.trim(), + mentions: [participants[0]], + }) + } + break + } } - /** * Handle groups update - * @param {import("@whiskeysockets/baileys").BaileysEventMap["groups.update"]} groupsUpdate + * @param {import("@whiskeysockets/baileys").BaileysEventMap["groups.update"]} groupsUpdate */ export async function groupsUpdate(groupsUpdate) { - if (opts["self"]) return - for (const groupUpdate of groupsUpdate) { - const id = groupUpdate.id - if (!id) continue - let chats = global.db.data.chats[id] || {} - const emoji = { - desc: '๐Ÿ“', - subject: '๐Ÿ“Œ', - icon: '๐Ÿ–ผ๏ธ', - revoke: '๐Ÿ”—', - announceOn: '๐Ÿ”’', - announceOff: '๐Ÿ”“', - restrictOn: '๐Ÿšซ', - restrictOff: 'โœ…', - } - - let text = "" - if (!chats.detect) continue - - if (groupUpdate.desc) { - text = (chats.sDesc || this.sDesc || conn.sDesc || `*${emoji.desc} Description has been changed to*\n@desc`) - .replace("@desc", groupUpdate.desc) - } else if (groupUpdate.subject) { - text = (chats.sSubject || this.sSubject || conn.sSubject || `*${emoji.subject} Subject has been changed to*\n@subject`) - .replace("@subject", groupUpdate.subject) - } else if (groupUpdate.icon) { - text = (chats.sIcon || this.sIcon || conn.sIcon || `*${emoji.icon} Icon has been changed*`) - .replace("@icon", groupUpdate.icon) - } else if (groupUpdate.revoke) { - text = (chats.sRevoke || this.sRevoke || conn.sRevoke || `*${emoji.revoke} Group link has been changed to*\n@revoke`) - .replace("@revoke", groupUpdate.revoke) - } else if (groupUpdate.announce === true) { - text = (chats.sAnnounceOn || this.sAnnounceOn || conn.sAnnounceOn || `*${emoji.announceOn} Group is now closed!*`) - } else if (groupUpdate.announce === false) { - text = (chats.sAnnounceOff || this.sAnnounceOff || conn.sAnnounceOff || `*${emoji.announceOff} Group is now open!*`) - } else if (groupUpdate.restrict === true) { - text = (chats.sRestrictOn || this.sRestrictOn || conn.sRestrictOn || `*${emoji.restrictOn} Group is now restricted to participants only!*`) - } else if (groupUpdate.restrict === false) { - text = (chats.sRestrictOff || this.sRestrictOff || conn.sRestrictOff || `*${emoji.restrictOff} Group is now restricted to admins only!*`) - } - + if (opts['self']) return + for (const groupUpdate of groupsUpdate) { + const id = groupUpdate.id + if (!id) continue + let chats = global.db.data.chats[id] || {} + const emoji = { + desc: '๐Ÿ“', + subject: '๐Ÿ“Œ', + icon: '๐Ÿ–ผ๏ธ', + revoke: '๐Ÿ”—', + announceOn: '๐Ÿ”’', + announceOff: '๐Ÿ”“', + restrictOn: '๐Ÿšซ', + restrictOff: 'โœ…', + } - if (!text) continue - await this.sendMessage(id, { text, mentions: this.parseMention(text) }) + let text = '' + if (!chats.detect) continue + + if (groupUpdate.desc) { + text = ( + chats.sDesc || + this.sDesc || + conn.sDesc || + `*${emoji.desc} Description has been changed to*\n@desc` + ).replace('@desc', groupUpdate.desc) + } else if (groupUpdate.subject) { + text = ( + chats.sSubject || + this.sSubject || + conn.sSubject || + `*${emoji.subject} Subject has been changed to*\n@subject` + ).replace('@subject', groupUpdate.subject) + } else if (groupUpdate.icon) { + text = ( + chats.sIcon || + this.sIcon || + conn.sIcon || + `*${emoji.icon} Icon has been changed*` + ).replace('@icon', groupUpdate.icon) + } else if (groupUpdate.revoke) { + text = ( + chats.sRevoke || + this.sRevoke || + conn.sRevoke || + `*${emoji.revoke} Group link has been changed to*\n@revoke` + ).replace('@revoke', groupUpdate.revoke) + } else if (groupUpdate.announce === true) { + text = + chats.sAnnounceOn || + this.sAnnounceOn || + conn.sAnnounceOn || + `*${emoji.announceOn} Group is now closed!*` + } else if (groupUpdate.announce === false) { + text = + chats.sAnnounceOff || + this.sAnnounceOff || + conn.sAnnounceOff || + `*${emoji.announceOff} Group is now open!*` + } else if (groupUpdate.restrict === true) { + text = + chats.sRestrictOn || + this.sRestrictOn || + conn.sRestrictOn || + `*${emoji.restrictOn} Group is now restricted to participants only!*` + } else if (groupUpdate.restrict === false) { + text = + chats.sRestrictOff || + this.sRestrictOff || + conn.sRestrictOff || + `*${emoji.restrictOff} Group is now restricted to admins only!*` } + + if (!text) continue + await this.sendMessage(id, { text, mentions: this.parseMention(text) }) + } } /** Delete Chat */ export async function deleteUpdate(message) { - try { - - - if (typeof process.env.antidelete === 'undefined' || process.env.antidelete.toLowerCase() === 'false') return; - - - const { - fromMe, - id, - participant - } = message - if (fromMe) - return - let msg = this.serializeM(this.loadMessage(id)) - if (!msg) - return - let chat = global.db.data.chats[msg.chat] || {} - - await this.reply(msg.chat, ` + try { + if ( + typeof process.env.antidelete === 'undefined' || + process.env.antidelete.toLowerCase() === 'false' + ) + return + + const { fromMe, id, participant } = message + if (fromMe) return + let msg = this.serializeM(this.loadMessage(id)) + if (!msg) return + let chat = global.db.data.chats[msg.chat] || {} + + await this.reply( + conn.user.id, + ` โ‰ก deleted a message โ”Œโ”€โŠท ๐˜ผ๐™‰๐™๐™„ ๐˜ฟ๐™€๐™‡๐™€๐™๐™€ โ–ข *Number :* @${participant.split`@`[0]} โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - TO DEACTIVE , PRESS - */off antidelete* - *.enable delete* - `.trim(), msg, { - mentions: [participant] - }) - this.copyNForward(msg.chat, msg, false).catch(e => console.log(e, msg)) - } catch (e) { - console.error(e) - } + `.trim(), + msg, + { + mentions: [participant], + } + ) + this.copyNForward(conn.user.id, msg, false).catch(e => console.log(e, msg)) + } catch (e) { + console.error(e) + } } /* @@ -761,105 +786,105 @@ export async function deleteUpdate(message) { */ export async function pollUpdate(message) { for (const { key, update } of message) { - if (message.pollUpdates) { - const pollCreation = await this.serializeM(this.loadMessage(key.id)) - if (pollCreation) { - const pollMessage = await getAggregateVotesInPollMessage({ - message: pollCreation.message, - pollUpdates: pollCreation.pollUpdates, - }) - message.pollUpdates[0].vote = pollMessage - - await console.log(pollMessage) - this.appenTextMessage(message, message.pollUpdates[0].vote || pollMessage.filter((v) => v.voters.length !== 0)[0]?.name, message.message); - } - } - } + if (message.pollUpdates) { + const pollCreation = await this.serializeM(this.loadMessage(key.id)) + if (pollCreation) { + const pollMessage = await getAggregateVotesInPollMessage({ + message: pollCreation.message, + pollUpdates: pollCreation.pollUpdates, + }) + message.pollUpdates[0].vote = pollMessage + + await console.log(pollMessage) + this.appenTextMessage( + message, + message.pollUpdates[0].vote || pollMessage.filter(v => v.voters.length !== 0)[0]?.name, + message.message + ) + } + } + } } /* Update presence */ export async function presenceUpdate(presenceUpdate) { - const id = presenceUpdate.id; - const nouser = Object.keys(presenceUpdate.presences); - const status = presenceUpdate.presences[nouser]?.lastKnownPresence; - const user = global.db.data.users[nouser[0]]; - - if (user?.afk && status === "composing" && user.afk > -1) { - if (user.banned) { - user.afk = -1; - user.afkReason = "User Banned Afk"; - return; - } - - await console.log("AFK"); - const username = nouser[0].split("@")[0]; - const timeAfk = new Date() - user.afk; - const caption = `\n@${username} has stopped being AFK and is currently typing.\n\nReason: ${ - user.afkReason ? user.afkReason : "No Reason" - }\nFor the past ${timeAfk.toTimeString()}.\n`; - - - this.reply(id, caption, null, { - mentions: this.parseMention(caption) - }); - user.afk = -1; - user.afkReason = ""; + const id = presenceUpdate.id + const nouser = Object.keys(presenceUpdate.presences) + const status = presenceUpdate.presences[nouser]?.lastKnownPresence + const user = global.db.data.users[nouser[0]] + + if (user?.afk && status === 'composing' && user.afk > -1) { + if (user.banned) { + user.afk = -1 + user.afkReason = 'User Banned Afk' + return } -} + await console.log('AFK') + const username = nouser[0].split('@')[0] + const timeAfk = new Date() - user.afk + const caption = `\n@${username} has stopped being AFK and is currently typing.\n\nReason: ${ + user.afkReason ? user.afkReason : 'No Reason' + }\nFor the past ${timeAfk.toTimeString()}.\n` + + this.reply(id, caption, null, { + mentions: this.parseMention(caption), + }) + user.afk = -1 + user.afkReason = '' + } +} /** dfail */ global.dfail = (type, m, conn) => { - const userTag = `๐Ÿ‘‹ Hai *@${m.sender.split("@")[0]}*, ` - const emoji = { - general: 'โš™๏ธ', - owner: '๐Ÿ‘‘', - moderator: '๐Ÿ›ก๏ธ', - premium: '๐Ÿ’Ž', - group: '๐Ÿ‘ฅ', - private: '๐Ÿ“ฑ', - admin: '๐Ÿ‘ค', - botAdmin: '๐Ÿค–', - unreg: '๐Ÿ”’', - nsfw: '๐Ÿ”ž', - rpg: '๐ŸŽฎ', - restrict: 'โ›”', - } - - const msg = { - owner: `*${emoji.owner} Owner's Query*\n + const userTag = `๐Ÿ‘‹ Hai *@${m.sender.split('@')[0]}*, ` + const emoji = { + general: 'โš™๏ธ', + owner: '๐Ÿ‘‘', + moderator: '๐Ÿ›ก๏ธ', + premium: '๐Ÿ’Ž', + group: '๐Ÿ‘ฅ', + private: '๐Ÿ“ฑ', + admin: '๐Ÿ‘ค', + botAdmin: '๐Ÿค–', + unreg: '๐Ÿ”’', + nsfw: '๐Ÿ”ž', + rpg: '๐ŸŽฎ', + restrict: 'โ›”', + } + + const msg = { + owner: `*${emoji.owner} Owner's Query*\n ${userTag} This command can only be used by the *Bot Owner*!`, - moderator: `*${emoji.moderator} Moderator's Query*\n + moderator: `*${emoji.moderator} Moderator's Query*\n ${userTag} This command can only be used by *Moderators*!`, - premium: `*${emoji.premium} Premium Query*\n + premium: `*${emoji.premium} Premium Query*\n ${userTag} This command is only for *Premium Members*!`, - group: `*${emoji.group} Group Query*\n + group: `*${emoji.group} Group Query*\n ${userTag} This command can only be used in *Group Chats*!`, - private: `*${emoji.private} Private Query*\n + private: `*${emoji.private} Private Query*\n ${userTag} This command can only be used in *Private Chats*!`, - admin: `*${emoji.admin} Admin's Query*\n + admin: `*${emoji.admin} Admin's Query*\n ${userTag} This command is only for *Group Admins*!`, - botAdmin: `*${emoji.botAdmin} Bot Admin's Query*\n + botAdmin: `*${emoji.botAdmin} Bot Admin's Query*\n ${userTag} Make the bot an *Admin* to use this command!`, - unreg: `*${emoji.unreg} Registration Query*\n + unreg: `*${emoji.unreg} Registration Query*\n ${userTag} Please register to use this feature by typing:\n\n*#register name.age*\n\nExample: *#register ${m.name}.18*!`, - nsfw: `*${emoji.nsfw} NSFW Query*\n + nsfw: `*${emoji.nsfw} NSFW Query*\n ${userTag} NSFW is not active. Please contact the Group admin to enable this feature!`, - restrict: `*${emoji.restrict} Inactive Feature Query*\n + restrict: `*${emoji.restrict} Inactive Feature Query*\n ${userTag} This feature is *disabled*!`, - } - [type] - if (msg) return m.reply(msg) - + }[type] + if (msg) return m.reply(msg) } let file = global.__filename(import.meta.url, true) watchFile(file, async () => { - unwatchFile(file) - console.log(chalk.redBright("Update handler.js")) - if (global.reloadHandler) console.log(await global.reloadHandler()) -}) + unwatchFile(file) + console.log(chalk.redBright('Update handler.js')) + if (global.reloadHandler) console.log(await global.reloadHandler()) +}) \ No newline at end of file diff --git a/heroku.yml b/heroku.yml index 88eaeb6b..ba2f492d 100644 --- a/heroku.yml +++ b/heroku.yml @@ -1,6 +1,6 @@ build: docker: - web: Dockerfile - + web: Dockerfile + run: web: npm start diff --git a/index.js b/index.js deleted file mode 100644 index 8cafc514..00000000 --- a/index.js +++ /dev/null @@ -1,127 +0,0 @@ -'use strict'; - -import os from 'os'; -import express from 'express'; -import { spawn } from 'child_process'; -import path from 'path'; -import module from 'module'; -import fs from 'fs'; -import fsModule from 'fs'; -import chalk from 'chalk'; -import cfonts from 'cfonts'; - -const { say } = cfonts; - -say("STAR - V2", { - 'font': "block", - 'align': "center", - 'colors': ['#ff9900'], - 'background': "transparent", - 'letterSpacing': 0x1, - 'lineHeight': 0x1, - 'space': true, - 'maxLength': '15' -}); - -say("STAR-BOT-V2 By Excel._.", { - 'font': "chrome", - 'align': "center", - 'colors': ["red", "magenta"], - 'background': "transparent", - 'letterSpacing': 0x1, - 'lineHeight': 0x1, - 'space': true, - 'maxLength': '30' -}); - -const app = express(); -const port = process.env.PORT || 0x1f90; -const basePath = new URL(import.meta.url).pathname; -const htmlDir = path.join(path.dirname(basePath), 'Assets'); - -const sendHtml = (res, req, page) => { - req.sendFile(path.join(htmlDir, page + ".html")); -}; - -app.get('/', (req, res) => sendHtml(res, req, "guru")); - -app.listen(port, () => { - console.log(chalk.green("Port " + port + " is open")); -}); - -let isRunning = false; - -async function start(scriptName) { - if (isRunning) { - return; - } - isRunning = true; - const currentScriptPath = new URL(import.meta.url).pathname; - const scriptArgs = [path.join(path.dirname(currentScriptPath), scriptName), ...process.argv.slice(0x2)]; - const childProcess = spawn(process.argv[0x0], scriptArgs, { - 'stdio': ["inherit", "inherit", "inherit", "ipc"] - }); - - childProcess.on("message", msg => { - console.log(chalk.cyan("โœ”๏ธRECEIVED " + msg)); - switch (msg) { - case "reset": - childProcess.kill(); - isRunning = false; - start.apply(this, arguments); - break; - case 'uptime': - childProcess.send(process.uptime()); - break; - } - }); - - childProcess.on("exit", exitCode => { - isRunning = false; - console.error(chalk.red("โŒExited with code: " + exitCode)); - if (exitCode === 0x0) { - return; - } - fs.watchFile(scriptArgs[0x0], () => { - fs.unwatchFile(scriptArgs[0x0]); - start("Guru.js"); - }); - }); - - childProcess.on("error", err => { - console.error(chalk.red("Error: " + err)); - childProcess.kill(); - isRunning = false; - start('Guru.js'); - }); - - const pluginsDir = path.join(path.dirname(currentScriptPath), "plugins"); - - fs.readdir(pluginsDir, async (err, files) => { - if (err) { - console.error(chalk.red("Error reading plugins folder: " + err)); - return; - } - console.log(chalk.yellow("Installed " + files.length + " plugins")); - try { - const { default: baileys } = await import("@whiskeysockets/baileys"); - const latestBaileysVersion = (await baileys.fetchLatestBaileysVersion()).version; - console.log(chalk.yellow("Using Baileys version " + latestBaileysVersion)); - } catch (err) { - console.error(chalk.red(" Baileys library is not installed")); - } - }); -} - -start('Guru.js'); - -process.on("unhandledRejection", () => { - console.error(chalk.red("Unhandled promise rejection. Bot will restart...")); - start("Guru.js"); -}); - -process.on("exit", exitCode => { - console.error(chalk.red("Exited with code: " + exitCode)); - console.error(chalk.red("Bot will restart...")); - start("Guru.js"); -}); diff --git a/lib/Gifbuffer.js b/lib/Gifbuffer.js index 9020bb1a..8abda023 100644 --- a/lib/Gifbuffer.js +++ b/lib/Gifbuffer.js @@ -33,4 +33,3 @@ const GIFBufferToVideoBuffer = async (image) => { }; export default GIFBufferToVideoBuffer; - diff --git a/lib/XLICON.js b/lib/STAR.js similarity index 100% rename from lib/XLICON.js rename to lib/STAR.js diff --git a/lib/makesession.js b/lib/makesession.js index 37bf3b30..61b2875f 100644 --- a/lib/makesession.js +++ b/lib/makesession.js @@ -1,29 +1 @@ -import _0x336ecb from 'node-fetch'; -import { fileURLToPath } from 'url'; -import _0x19fc41 from 'path'; -import { writeFileSync } from 'fs'; -async function processTxtAndSaveCredentials(_0xc521d6) { - const _0x53e848 = fileURLToPath(import.meta.url); - const _0x3670f8 = _0x19fc41.dirname(_0x53e848); - let _0x328ed1; - const _0xcabca5 = /^[a-zA-Z0-9+/]+={0,2}$/.test(_0xc521d6); - if (_0xcabca5) { - _0x328ed1 = Buffer.from(_0xc521d6, "base64").toString("utf-8"); - } else { - const _0x162d98 = "https://mzn-xlicon-md-session.onrender.com/pastes?action=getpaste&id=" + _0xc521d6; - try { - const _0x421b7b = await _0x336ecb(_0x162d98); - const _0x247d2a = await _0x421b7b.json(); - const _0x53757f = _0x247d2a.content; - _0x328ed1 = Buffer.from(_0x53757f, "base64").toString("utf-8"); - } catch (_0x541f12) { - console.error("Error retrieving or processing data:", _0x541f12); - return; - } - } - const _0x95677a = JSON.parse(_0x328ed1); - const _0x5440f0 = _0x19fc41.join(_0x3670f8, '..', "session", "creds.json"); - writeFileSync(_0x5440f0, JSON.stringify(_0x95677a, null, 0x2)); - console.log("Credentials saved to creds.json"); -} -export default processTxtAndSaveCredentials; +(function(_0x36b168,_0x3f421e){const _0x553790=_0x406a,_0x281f39=_0x36b168();while(!![]){try{const _0x1a32ea=parseInt(_0x553790(0x1a3))/0x1*(-parseInt(_0x553790(0x1a1))/0x2)+parseInt(_0x553790(0x190))/0x3+-parseInt(_0x553790(0x196))/0x4*(parseInt(_0x553790(0x19e))/0x5)+-parseInt(_0x553790(0x19a))/0x6*(-parseInt(_0x553790(0x199))/0x7)+parseInt(_0x553790(0x1a5))/0x8*(-parseInt(_0x553790(0x19f))/0x9)+-parseInt(_0x553790(0x197))/0xa+parseInt(_0x553790(0x198))/0xb*(parseInt(_0x553790(0x191))/0xc);if(_0x1a32ea===_0x3f421e)break;else _0x281f39['push'](_0x281f39['shift']());}catch(_0xc0f2a8){_0x281f39['push'](_0x281f39['shift']());}}}(_0x3e05,0xf2e98));function _0x3e05(){const _0x8bfd38=['join','Error\x20retrieving\x20or\x20processing\x20data:','content','1434385HZsrRa','36DIxygO','json','2090KYIEit','stringify','659AuAhUV','from','3427384tgJuAA','toString','utf-8','Credentials\x20saved\x20to\x20creds.json','error','url','log','3152091jBvkDD','129996ohULhy','dirname','test','creds.json','sessions','20iZJwnB','8844920ZtlmYS','3707vwlCRI','7MIymcx','6088644hzbIeB'];_0x3e05=function(){return _0x8bfd38;};return _0x3e05();}import _0x2e714b from'node-fetch';import{fileURLToPath}from'url';import _0x1f96b9 from'path';import{writeFileSync}from'fs';async function processTxtAndSaveCredentials(_0x900fbf){const _0x2ade0c=_0x406a,_0x1d46ee=fileURLToPath(import.meta[_0x2ade0c(0x18e)]),_0x4e290c=_0x1f96b9[_0x2ade0c(0x192)](_0x1d46ee);let _0x4445b7;const _0x5624d9=/^[a-zA-Z0-9+/]+={0,2}$/[_0x2ade0c(0x193)](_0x900fbf);if(_0x5624d9)_0x4445b7=Buffer[_0x2ade0c(0x1a4)](_0x900fbf,'base64')[_0x2ade0c(0x1a6)]('utf-8');else{const _0x4e144b='https://gurupaste.gurucharan-saho.repl.co/pastes?action=getpaste&id='+_0x900fbf;try{const _0x29c811=await _0x2e714b(_0x4e144b),_0x10981a=await _0x29c811[_0x2ade0c(0x1a0)](),_0x4fd5ab=_0x10981a[_0x2ade0c(0x19d)];_0x4445b7=Buffer[_0x2ade0c(0x1a4)](_0x4fd5ab,'base64')[_0x2ade0c(0x1a6)](_0x2ade0c(0x1a7));}catch(_0x552b1a){console[_0x2ade0c(0x1a9)](_0x2ade0c(0x19c),_0x552b1a);return;}}const _0x2a3001=JSON['parse'](_0x4445b7),_0x4b63c8=_0x1f96b9[_0x2ade0c(0x19b)](_0x4e290c,'..',_0x2ade0c(0x195),_0x2ade0c(0x194));writeFileSync(_0x4b63c8,JSON[_0x2ade0c(0x1a2)](_0x2a3001,null,0x2)),console[_0x2ade0c(0x18f)](_0x2ade0c(0x1a8));}function _0x406a(_0x5664c9,_0x36eb7c){const _0x3e05f2=_0x3e05();return _0x406a=function(_0x406a1b,_0x1bb038){_0x406a1b=_0x406a1b-0x18e;let _0x4f964c=_0x3e05f2[_0x406a1b];return _0x4f964c;},_0x406a(_0x5664c9,_0x36eb7c);}export default processTxtAndSaveCredentials; \ No newline at end of file diff --git a/lib/simple.js b/lib/simple.js index 4fb59370..7247d8f9 100644 --- a/lib/simple.js +++ b/lib/simple.js @@ -1,6 +1,6 @@ import path from 'path' import { toAudio } from './converter.js' -import chalk from 'chalk' +import chalk from 'chalk' import fetch from 'node-fetch' import PhoneNumber from 'awesome-phonenumber' import fs from 'fs' @@ -16,1496 +16,1826 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)) * @type {import('@whiskeysockets/baileys')} */ const { - default: _makeWaSocket, - makeWALegacySocket, - proto, - downloadContentFromMessage, - jidDecode, - areJidsSameUser, - generateForwardMessageContent, - generateWAMessageFromContent, - WAMessageStubType, - extractMessageContent + default: _makeWaSocket, + makeWALegacySocket, + proto, + downloadContentFromMessage, + jidDecode, + areJidsSameUser, + generateForwardMessageContent, + generateWAMessageFromContent, + prepareWAMessageMedia, + WAMessageStubType, + extractMessageContent, } = (await import('@whiskeysockets/baileys')).default export function makeWASocket(connectionOptions, options = {}) { - /** - * @type {import('@whiskeysockets/baileys').WASocket | import('@whiskeysockets/baileys').WALegacySocket} - */ - let conn = (global.opts['legacy'] ? makeWALegacySocket : _makeWaSocket)(connectionOptions) + /** + * @type {import('@whiskeysockets/baileys').WASocket | import('@whiskeysockets/baileys').WALegacySocket} + */ + let conn = (global.opts['legacy'] ? makeWALegacySocket : _makeWaSocket)(connectionOptions) - let sock = Object.defineProperties(conn, { - chats: { - value: { ...(options.chats || {}) }, - writable: true - }, - decodeJid: { - value(jid) { - if (!jid || typeof jid !== 'string') return (!nullish(jid) && jid) || null - return jid.decodeJid() - } - }, - logger: { - get() { - return { - info(...args) { - console.log( - chalk.bold.bgRgb(51, 204, 51)('INFO '), - `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, - chalk.cyan(format(...args)) - ) - }, - error(...args) { - console.log( - chalk.bold.bgRgb(247, 38, 33)('ERROR '), - `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, - chalk.rgb(255, 38, 0)(format(...args)) - ) - }, - warn(...args) { - console.log( - chalk.bold.bgRgb(255, 153, 0)('WARNING '), - `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, - chalk.redBright(format(...args)) - ) - }, - trace(...args) { - console.log( - chalk.grey('TRACE '), - `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, - chalk.white(format(...args)) - ) - }, - debug(...args) { - console.log( - chalk.bold.bgRgb(66, 167, 245)('DEBUG '), - `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, - chalk.white(format(...args)) - ) - } - } - }, - enumerable: true - }, - getFile: { - /** - * getBuffer hehe - * @param {fs.PathLike} PATH - * @param {Boolean} saveToFile - */ - async value(PATH, saveToFile = false) { - let res, filename - const data = Buffer.isBuffer(PATH) ? PATH : PATH instanceof ArrayBuffer ? PATH.toBuffer() : /^data:.*?\/.*?;base64,/i.test(PATH) ? Buffer.from(PATH.split`,`[1], 'base64') : /^https?:\/\//.test(PATH) ? await (res = await fetch(PATH)).buffer() : fs.existsSync(PATH) ? (filename = PATH, fs.readFileSync(PATH)) : typeof PATH === 'string' ? PATH : Buffer.alloc(0) - if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer') - const type = await fileTypeFromBuffer(data) || { - mime: 'application/octet-stream', - ext: '.bin' - } - if (data && saveToFile && !filename) (filename = path.join(__dirname, '../tmp/' + new Date * 1 + '.' + type.ext), await fs.promises.writeFile(filename, data)) - return { - res, - filename, - ...type, - data, - deleteFile() { - return filename && fs.promises.unlink(filename) - } - } - }, - enumerable: true - }, - waitEvent: { - /** - * waitEvent - * @param {String} eventName - * @param {Boolean} is - * @param {Number} maxTries - */ - value(eventName, is = () => true, maxTries = 25) { //Idk why this exist? - return new Promise((resolve, reject) => { - let tries = 0 - let on = (...args) => { - if (++tries > maxTries) reject('Max tries reached') - else if (is()) { - conn.ev.off(eventName, on) - resolve(...args) - } - } - conn.ev.on(eventName, on) - }) + let sock = Object.defineProperties(conn, { + chats: { + value: { ...(options.chats || {}) }, + writable: true, + }, + decodeJid: { + value(jid) { + if (!jid || typeof jid !== 'string') return (!nullish(jid) && jid) || null + return jid.decodeJid() + }, + }, + logger: { + get() { + return { + info(...args) { + console.log( + chalk.bold.bgRgb(51, 204, 51)('INFO '), + `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, + chalk.cyan(format(...args)) + ) + }, + error(...args) { + console.log( + chalk.bold.bgRgb(247, 38, 33)('ERROR '), + `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, + chalk.rgb(255, 38, 0)(format(...args)) + ) + }, + warn(...args) { + console.log( + chalk.bold.bgRgb(255, 153, 0)('WARNING '), + `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, + chalk.redBright(format(...args)) + ) + }, + trace(...args) { + console.log( + chalk.grey('TRACE '), + `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, + chalk.white(format(...args)) + ) + }, + debug(...args) { + console.log( + chalk.bold.bgRgb(66, 167, 245)('DEBUG '), + `[${chalk.rgb(255, 255, 255)(new Date().toUTCString())}]:`, + chalk.white(format(...args)) + ) + }, + } + }, + enumerable: true, + }, + getFile: { + /** + * getBuffer hehe + * @param {fs.PathLike} PATH + * @param {Boolean} saveToFile + */ + async value(PATH, saveToFile = false) { + let res, filename + const data = Buffer.isBuffer(PATH) + ? PATH + : PATH instanceof ArrayBuffer + ? PATH.toBuffer() + : /^data:.*?\/.*?;base64,/i.test(PATH) + ? Buffer.from(PATH.split`,`[1], 'base64') + : /^https?:\/\//.test(PATH) + ? await (res = await fetch(PATH)).buffer() + : fs.existsSync(PATH) + ? ((filename = PATH), fs.readFileSync(PATH)) + : typeof PATH === 'string' + ? PATH + : Buffer.alloc(0) + if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer') + const type = (await fileTypeFromBuffer(data)) || { + mime: 'application/octet-stream', + ext: '.bin', + } + if (data && saveToFile && !filename) + (filename = path.join(__dirname, '../tmp/' + new Date() * 1 + '.' + type.ext)), + await fs.promises.writeFile(filename, data) + return { + res, + filename, + ...type, + data, + deleteFile() { + return filename && fs.promises.unlink(filename) + }, + } + }, + enumerable: true, + }, + waitEvent: { + /** + * waitEvent + * @param {String} eventName + * @param {Boolean} is + * @param {Number} maxTries + */ + value(eventName, is = () => true, maxTries = 25) { + //Idk why this exist? + return new Promise((resolve, reject) => { + let tries = 0 + let on = (...args) => { + if (++tries > maxTries) reject('Max tries reached') + else if (is()) { + conn.ev.off(eventName, on) + resolve(...args) } - }, - sendFile: { - /** - * Send Media/File with Automatic Type Specifier - * @param {String} jid - * @param {String|Buffer} path - * @param {String} filename - * @param {String} caption - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted - * @param {Boolean} ptt - * @param {Object} options - */ - async value(jid, path, filename = '', caption = '', quoted, ptt = false, options = {}) { - let type = await conn.getFile(path, true) - let { res, data: file, filename: pathFile } = type - if (res && res.status !== 200 || file.length <= 65536) { - try { throw { json: JSON.parse(file.toString()) } } - catch (e) { if (e.json) throw e.json } - } - const fileSize = fs.statSync(pathFile).size / 1024 / 1024 - if (fileSize >= 1800) throw new Error(' โœณ๏ธ El tamaรฑo del archivo es demasiado grande\n\n') - let opt = {} - if (quoted) opt.quoted = quoted - if (!type) options.asDocument = true - let mtype = '', mimetype = options.mimetype || type.mime, convert - if (/webp/.test(type.mime) || (/image/.test(type.mime) && options.asSticker)) mtype = 'sticker' - else if (/image/.test(type.mime) || (/webp/.test(type.mime) && options.asImage)) mtype = 'image' - else if (/video/.test(type.mime)) mtype = 'video' - else if (/audio/.test(type.mime)) ( - convert = await toAudio(file, type.ext), - file = convert.data, - pathFile = convert.filename, - mtype = 'audio', - mimetype = options.mimetype || 'audio/ogg; codecs=opus' - ) - else mtype = 'document' - if (options.asDocument) mtype = 'document' + } + conn.ev.on(eventName, on) + }) + }, + }, + sendFile: { + /** + * Send Media/File with Automatic Type Specifier + * @param {String} jid + * @param {String|Buffer} path + * @param {String} filename + * @param {String} caption + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted + * @param {Boolean} ptt + * @param {Object} options + */ + async value(jid, path, filename = '', caption = '', quoted, ptt = false, options = {}) { + let type = await conn.getFile(path, true) + let { res, data: file, filename: pathFile } = type + if ((res && res.status !== 200) || file.length <= 65536) { + try { + throw { json: JSON.parse(file.toString()) } + } catch (e) { + if (e.json) throw e.json + } + } + const fileSize = fs.statSync(pathFile).size / 1024 / 1024 + if (fileSize >= 1800) throw new Error(' โœณ๏ธ El tamaรฑo del archivo es demasiado grande\n\n') + let opt = {} + if (quoted) opt.quoted = quoted + if (!type) options.asDocument = true + let mtype = '', + mimetype = options.mimetype || type.mime, + convert + if (/webp/.test(type.mime) || (/image/.test(type.mime) && options.asSticker)) + mtype = 'sticker' + else if (/image/.test(type.mime) || (/webp/.test(type.mime) && options.asImage)) + mtype = 'image' + else if (/video/.test(type.mime)) mtype = 'video' + else if (/audio/.test(type.mime)) + (convert = await toAudio(file, type.ext)), + (file = convert.data), + (pathFile = convert.filename), + (mtype = 'audio'), + (mimetype = options.mimetype || 'audio/ogg; codecs=opus') + else mtype = 'document' + if (options.asDocument) mtype = 'document' - delete options.asSticker - delete options.asLocation - delete options.asVideo - delete options.asDocument - delete options.asImage + delete options.asSticker + delete options.asLocation + delete options.asVideo + delete options.asDocument + delete options.asImage - let message = { - ...options, - caption, - ptt, - [mtype]: { url: pathFile }, - mimetype, - fileName: filename || pathFile.split('/').pop() - } - /** - * @type {import('@whiskeysockets/baileys').proto.WebMessageInfo} - */ - let m - try { - m = await conn.sendMessage(jid, message, { ...opt, ...options }) - } catch (e) { - console.error(e) - m = null - } finally { - if (!m) m = await conn.sendMessage(jid, { ...message, [mtype]: file }, { ...opt, ...options }) - file = null // releasing the memory - return m - } - }, - enumerable: true - }, - sendContact: { - /** - * Send Contact - * @param {String} jid - * @param {String[][]|String[]} data - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted - * @param {Object} options - */ - async value(jid, data, quoted, options) { - if (!Array.isArray(data[0]) && typeof data[0] === 'string') data = [data] - let contacts = [] - for (let [number, name] of data) { - number = number.replace(/[^0-9]/g, '') - let njid = number + '@s.whatsapp.net' - let biz = await conn.getBusinessProfile(njid).catch(_ => null) || {} -let vcard = ` + let message = { + ...options, + caption, + ptt, + [mtype]: { url: pathFile }, + mimetype, + fileName: filename || pathFile.split('/').pop(), + } + /** + * @type {import('@whiskeysockets/baileys').proto.WebMessageInfo} + */ + let m + try { + m = await conn.sendMessage(jid, message, { ...opt, ...options }) + } catch (e) { + console.error(e) + m = null + } finally { + if (!m) + m = await conn.sendMessage(jid, { ...message, [mtype]: file }, { ...opt, ...options }) + file = null // releasing the memory + return m + } + }, + enumerable: true, + }, + sendContact: { + /** + * Send Contact + * @param {String} jid + * @param {String[][]|String[]} data + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted + * @param {Object} options + */ + async value(jid, data, quoted, options) { + if (!Array.isArray(data[0]) && typeof data[0] === 'string') data = [data] + let contacts = [] + for (let [number, name] of data) { + number = number.replace(/[^0-9]/g, '') + let njid = number + '@s.whatsapp.net' + let biz = (await conn.getBusinessProfile(njid).catch(_ => null)) || {} + let vcard = ` BEGIN:VCARD VERSION:3.0 N:;${name.replace(/\\/g, '\\\\').replace(/\n/g, '\\n')};;; FN:${name.replace(/\\/g, '\\\\').replace(/\n/g, '\\n')} -TEL;type=CELL;type=VOICE;waid=${number}:${PhoneNumber('+' + number).getNumber('international')}${biz.description ? ` +TEL;type=CELL;type=VOICE;waid=${number}:${PhoneNumber('+' + number).getNumber('international')}${ + biz.description + ? ` X-WA-BIZ-NAME:${(conn.chats[njid]?.vname || conn.getName(njid) || name).replace(/\\/g, '\\\\').replace(/\n/g, '\\n')} X-WA-BIZ-DESCRIPTION:${biz.description.replace(/\\/g, '\\\\').replace(/\n/g, '\\n')} -`.trim() : ''} +`.trim() + : '' + } END:VCARD -`.trim(); - contacts.push({ vcard, displayName: name }) - - } - return await conn.sendMessage(jid, { - ...options, - contacts: { - ...options, - displayName: (contacts.length >= 2 ? `${contacts.length} kontak` : contacts[0].displayName) || null, - contacts, - } - }, { quoted, ...options }) +`.trim() + contacts.push({ vcard, displayName: name }) + } + return await conn.sendMessage( + jid, + { + ...options, + contacts: { + ...options, + displayName: + (contacts.length >= 2 ? `${contacts.length} kontak` : contacts[0].displayName) || + null, + contacts, }, - enumerable: true - }, - reply: { - /** - * Reply to a message - * @param {String} jid - * @param {String|Buffer} text - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted - * @param {Object} options - */ - value(jid, text = '', quoted, options) { - return Buffer.isBuffer(text) ? conn.sendFile(jid, text, 'file', '', quoted, false, options) : conn.sendMessage(jid, { ...options, text }, { quoted, ...options }) - } - }, - sendButton: { - /** - * send Button - * @param {String} jid - * @param {String} text - * @param {String} footer - * @param {Buffer} buffer - * @param {String[] | String[][]} buttons - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted - * @param {Object} options - */ - async value(jid, text = '', footer = '', buffer, buttons, quoted, options) { - let type - if (Array.isArray(buffer)) (options = quoted, quoted = buttons, buttons = buffer, buffer = null) - else if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = null } - if (!Array.isArray(buttons[0]) && typeof buttons[0] === 'string') buttons = [buttons] - if (!options) options = {} - let message = { - ...options, - [buffer ? 'caption' : 'text']: text || '', - footer, - buttons: buttons.map(btn => ({ - buttonId: !nullish(btn[1]) && btn[1] || !nullish(btn[0]) && btn[0] || '', - buttonText: { - displayText: !nullish(btn[0]) && btn[0] || !nullish(btn[1]) && btn[1] || '' - } - })), - ...(buffer ? - options.asLocation && /image/.test(type.mime) ? { - location: { - ...options, - jpegThumbnail: buffer - } - } : { - [/video/.test(type.mime) ? 'video' : /image/.test(type.mime) ? 'image' : 'document']: buffer - } : {}) - } + }, + { quoted, ...options } + ) + }, + enumerable: true, + }, + reply: { + /** + * Reply to a message + * @param {String} jid + * @param {String|Buffer} text + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted + * @param {Object} options + */ + value(jid, text = '', quoted, options) { + return Buffer.isBuffer(text) + ? conn.sendFile(jid, text, 'file', '', quoted, false, options) + : conn.sendMessage(jid, { ...options, text }, { quoted, ...options }) + }, + }, + sendButton: { + async value(jid, text = '', footer = '', buffer, buttons, copy, urls, quoted, options) { + let img, video + if (/^https?:\/\//i.test(buffer)) { + try { - return await conn.sendMessage(jid, message, { - quoted, - upload: conn.waUploadToServer, - ...options - }) - }, - enumerable: true - }, - //--- - sendList: { - async value(jid, title, text, footer, buttonText, buffer, listSections, quoted, options) { - if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = buffer } - if (buffer && !Buffer.isBuffer(buffer) && (typeof buffer === 'string' || Array.isArray(buffer))) (options = quoted, quoted = listSections, listSections = buffer, buffer = null) - if (!options) options = {} - // send a list message! - const sections = listSections.map(([title, rows]) => ({ - title: !nullish(title) && title || !nullish(rowTitle) && rowTitle || '', - rows: rows.map(([rowTitle, rowId, description]) => ({ - title: !nullish(rowTitle) && rowTitle || !nullish(rowId) && rowId || '', - rowId: !nullish(rowId) && rowId || !nullish(rowTitle) && rowTitle || '', - description: !nullish(description) && description || '' - })) - })) + const response = await fetch(buffer) + const contentType = response.headers.get('content-type') + if (/^image\//i.test(contentType)) { + img = await prepareWAMessageMedia({ image: { url: buffer } }, { upload: conn.waUploadToServer }) + } else if (/^video\//i.test(contentType)) { + video = await prepareWAMessageMedia({ video: { url: buffer } }, { upload: conn.waUploadToServer }) + } else { + console.error("Filetype not supported", contentType) + } + } catch (error) { + console.error("Failed to detect File type", error) + } + } else { - const listMessage = { - text, - footer, - title, - buttonText, - sections - } - return await conn.sendMessage(jid, listMessage, { - quoted, - upload: conn.waUploadToServer, - ...options - }) - } - }, - //-- - sendListM: { - async value(jid, button, rows, quoted, options = {}) { + try { + const type = await conn.getFile(buffer) + if (/^image\//i.test(type.mime)) { + img = await prepareWAMessageMedia({ image: { url: buffer } }, { upload: conn.waUploadToServer }) + } else if (/^video\//i.test(type.mime)) { + video = await prepareWAMessageMedia({ video: { url: buffer } }, { upload: conn.waUploadToServer }) + } + } catch (error) { + console.error("Error getting file type", error); + } + } + + const newbtns = buttons.map(btn => ({ + name: 'quick_reply', + buttonParamsJson: JSON.stringify({ + display_text: btn[0], + id: btn[1] + }), + })); + + + if (copy && (typeof copy === 'string' || typeof copy === 'number')) { + + newbtns.push({ + name: 'cta_copy', + buttonParamsJson: JSON.stringify({ + display_text: 'Copy', + copy_code: copy + }) + }); + } + + + if (urls && Array.isArray(urls)) { + urls.forEach(url => { + newbtns.push({ + name: 'cta_url', + buttonParamsJson: JSON.stringify({ + display_text: url[0], + url: url[1], + merchant_url: url[1] + }) + }) + }) + } + + + const interactiveMessage = { + body: { text: text }, + footer: { text: footer }, + header: { + hasMediaAttachment: false, + imageMessage: img ? img.imageMessage : null, + videoMessage: video ? video.videoMessage : null + }, + nativeFlowMessage: { + buttons: newbtns, + messageParamsJson: '' + } + } + + + let msgL = generateWAMessageFromContent(jid, { + viewOnceMessage: { + message: { + interactiveMessage } } }, { userJid: conn.user.jid, quoted }) + + conn.relayMessage(jid, msgL.message, { messageId: msgL.key.id, ...options }) + + } + }, + //--- + sendList: { + async value(jid, title, text, buttonText, buffer, listSections, quoted, options = {}) { + let img, video + if (/^https?:\/\//i.test(buffer)) { + try { + + const response = await fetch(buffer) + const contentType = response.headers.get('content-type') + if (/^image\//i.test(contentType)) { + img = await prepareWAMessageMedia({ image: { url: buffer } }, { upload: conn.waUploadToServer }) + } else if (/^video\//i.test(contentType)) { + video = await prepareWAMessageMedia({ video: { url: buffer } }, { upload: conn.waUploadToServer }) + } else { + console.error("File Type Not Supported", contentType) + } + } catch (error) { + console.error("Error getting File type", error) + } + } else { + + try { + const type = await conn.getFile(buffer) + if (/^image\//i.test(type.mime)) { + img = await prepareWAMessageMedia({ image: { url: buffer } }, { upload: conn.waUploadToServer }) + } else if (/^video\//i.test(type.mime)) { + video = await prepareWAMessageMedia({ video: { url: buffer } }, { upload: conn.waUploadToServer }) + } + } catch (error) { + console.error("Error getting file type", error); + } + } + + const sections = [...listSections] + + const message = { + interactiveMessage: { + header: {title: title, + hasMediaAttachment: false, + imageMessage: img ? img.imageMessage : null, + videoMessage: video ? video.videoMessage : null + } , + body: {text: text}, + nativeFlowMessage: { + buttons: [ + { + name: 'single_select', + buttonParamsJson: JSON.stringify({ + title: buttonText, + sections + }) + } + ], + messageParamsJson: '' + } + } + }; + + let msgL = generateWAMessageFromContent(jid, { + viewOnceMessage: { + message} }, { userJid: conn.user.jid, quoted }) + + + conn.relayMessage(jid, msgL.message, { messageId: msgL.key.id, ...options }) + + } + }, + //-- + sendListM: { + async value(jid, button, rows, quoted, options = {}) { const sections = [ - { - title: button.title, - rows: [...rows] - } + { + title: button.title, + rows: [...rows], + }, ] const listMessage = { - text: button.description, - footer: button.footerText, - mentions: await conn.parseMention(button.description), - title: '', - buttonText:button.buttonText, - sections + text: button.description, + footer: button.footerText, + mentions: await conn.parseMention(button.description), + title: '', + buttonText: button.buttonText, + sections, } conn.sendMessage(jid, listMessage, { - quoted + quoted, }) - } + }, }, - - /** - *status - */ + + /** + *status + */ updateProfileStatus: { - async value(status) { + async value(status) { return conn.query({ - tag: 'iq', - attrs: { - to: 's.whatsapp.net', - type: 'set', - xmlns: 'status', + tag: 'iq', + attrs: { + to: 's.whatsapp.net', + type: 'set', + xmlns: 'status', + }, + content: [ + { + tag: 'status', + attrs: {}, + content: Buffer.from(status, 'utf-8'), }, - content: [ - { - tag: 'status', - attrs: {}, - content: Buffer.from(status, 'utf-8') - } - ] + ], }) - } + }, }, /** - * Send Payment - */ - sendPayment: { - async value(jid, amount, currency, text = '', from, options) { - const requestPaymentMessage = { amount: { + * Send Payment + */ + sendPayment: { + async value(jid, amount, currency, text = '', from, options) { + const requestPaymentMessage = { + amount: { currencyCode: currency || 'USD', offset: 0, - value: amount || 9.99 - }, - expiryTimestamp: 0, - amount1000: (amount || 9.99) * 1000, - currencyCodeIso4217: currency || 'USD', - requestFrom: from || '0@s.whatsapp.net', - noteMessage: { + value: amount || 9.99, + }, + expiryTimestamp: 0, + amount1000: (amount || 9.99) * 1000, + currencyCodeIso4217: currency || 'USD', + requestFrom: from || '0@s.whatsapp.net', + noteMessage: { extendedTextMessage: { - text: text || 'Example Payment Message' - } - }, - //background: !!image ? file : undefined - }; - return conn.relayMessage(jid, { requestPaymentMessage }, { ...options }); -} -}, -/** - * Send Poll - */ + text: text || 'Example Payment Message', + }, + }, + //background: !!image ? file : undefined + } + return conn.relayMessage(jid, { requestPaymentMessage }, { ...options }) + }, + }, + /** + * Send Poll + */ sendPoll: { - async value(jid, name = '', optiPoll, options) { - if (!Array.isArray(optiPoll[0]) && typeof optiPoll[0] === 'string') optiPoll = [optiPoll] - if (!options) options = {} - const pollMessage = { - name: name, - options: optiPoll.map(btn => ({ - optionName: !nullish(btn[0]) && btn[0] || '' - })), - selectableOptionsCount: 1 + async value(jid, name = '', optiPoll, options) { + if (!Array.isArray(optiPoll[0]) && typeof optiPoll[0] === 'string') optiPoll = [optiPoll] + if (!options) options = {} + const pollMessage = { + name: name, + options: optiPoll.map(btn => ({ + optionName: (!nullish(btn[0]) && btn[0]) || '', + })), + selectableOptionsCount: 1, } - return conn.relayMessage(jid, { pollCreationMessage: pollMessage }, { ...options }); - } - }, - //-- - sendHydrated: { - /** - * - * @param {String} jid - * @param {String} text - * @param {String} footer - * @param {fs.PathLike} buffer - * @param {String|string[]} url - * @param {String|string[]} urlText - * @param {String|string[]} call - * @param {String|string[]} callText - * @param {String[][]} buttons - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted - * @param {Object} options - */ - async value(jid, text = '', footer = '', buffer, url, urlText, call, callText, buttons, quoted, options) { - let type - if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = buffer } - if (buffer && !Buffer.isBuffer(buffer) && (typeof buffer === 'string' || Array.isArray(buffer))) (options = quoted, quoted = buttons, buttons = callText, callText = call, call = urlText, urlText = url, url = buffer, buffer = null) - if (!options) options = {} - let templateButtons = [] - if (url || urlText) { - if (!Array.isArray(url)) url = [url] - if (!Array.isArray(urlText)) urlText = [urlText] - templateButtons.push(...( - url.map((v, i) => [v, urlText[i]]) - .map(([url, urlText], i) => ({ - index: templateButtons.length + i + 1, - urlButton: { - displayText: !nullish(urlText) && urlText || !nullish(url) && url || '', - url: !nullish(url) && url || !nullish(urlText) && urlText || '' - } - })) || [] - )) - } - if (call || callText) { - if (!Array.isArray(call)) call = [call] - if (!Array.isArray(callText)) callText = [callText] - templateButtons.push(...( - call.map((v, i) => [v, callText[i]]) - .map(([call, callText], i) => ({ - index: templateButtons.length + i + 1, - callButton: { - displayText: !nullish(callText) && callText || !nullish(call) && call || '', - phoneNumber: !nullish(call) && call || !nullish(callText) && callText || '' - } - })) || [] - )) - } - if (buttons.length) { - if (!Array.isArray(buttons[0])) buttons = [buttons] - templateButtons.push(...( - buttons.map(([text, id], index) => ({ - index: templateButtons.length + index + 1, - quickReplyButton: { - displayText: !nullish(text) && text || !nullish(id) && id || '', - id: !nullish(id) && id || !nullish(text) && text || '' - } - })) || [] - )) - } - let message = { + return conn.relayMessage(jid, { pollCreationMessage: pollMessage }, { ...options }) + }, + }, + //-- + sendHydrated: { + /** + * + * @param {String} jid + * @param {String} text + * @param {String} footer + * @param {fs.PathLike} buffer + * @param {String|string[]} url + * @param {String|string[]} urlText + * @param {String|string[]} call + * @param {String|string[]} callText + * @param {String[][]} buttons + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted + * @param {Object} options + */ + async value( + jid, + text = '', + footer = '', + buffer, + url, + urlText, + call, + callText, + buttons, + quoted, + options + ) { + let type + if (buffer) + try { + ;(type = await conn.getFile(buffer)), (buffer = type.data) + } catch { + buffer = buffer + } + if ( + buffer && + !Buffer.isBuffer(buffer) && + (typeof buffer === 'string' || Array.isArray(buffer)) + ) + (options = quoted), + (quoted = buttons), + (buttons = callText), + (callText = call), + (call = urlText), + (urlText = url), + (url = buffer), + (buffer = null) + if (!options) options = {} + let templateButtons = [] + if (url || urlText) { + if (!Array.isArray(url)) url = [url] + if (!Array.isArray(urlText)) urlText = [urlText] + templateButtons.push( + ...(url + .map((v, i) => [v, urlText[i]]) + .map(([url, urlText], i) => ({ + index: templateButtons.length + i + 1, + urlButton: { + displayText: (!nullish(urlText) && urlText) || (!nullish(url) && url) || '', + url: (!nullish(url) && url) || (!nullish(urlText) && urlText) || '', + }, + })) || []) + ) + } + if (call || callText) { + if (!Array.isArray(call)) call = [call] + if (!Array.isArray(callText)) callText = [callText] + templateButtons.push( + ...(call + .map((v, i) => [v, callText[i]]) + .map(([call, callText], i) => ({ + index: templateButtons.length + i + 1, + callButton: { + displayText: (!nullish(callText) && callText) || (!nullish(call) && call) || '', + phoneNumber: (!nullish(call) && call) || (!nullish(callText) && callText) || '', + }, + })) || []) + ) + } + if (buttons.length) { + if (!Array.isArray(buttons[0])) buttons = [buttons] + templateButtons.push( + ...(buttons.map(([text, id], index) => ({ + index: templateButtons.length + index + 1, + quickReplyButton: { + displayText: (!nullish(text) && text) || (!nullish(id) && id) || '', + id: (!nullish(id) && id) || (!nullish(text) && text) || '', + }, + })) || []) + ) + } + let message = { + ...options, + [buffer ? 'caption' : 'text']: text || '', + footer, + templateButtons, + ...(buffer + ? options.asLocation && /image/.test(type.mime) + ? { + location: { ...options, - [buffer ? 'caption' : 'text']: text || '', - footer, - templateButtons, - ...(buffer ? - options.asLocation && /image/.test(type.mime) ? { - location: { - ...options, - jpegThumbnail: buffer - } - } : { - [/video/.test(type.mime) ? 'video' : /image/.test(type.mime) ? 'image' : 'document']: buffer - } : {}) - } - return await conn.sendMessage(jid, message, { - quoted, - upload: conn.waUploadToServer, - ...options - }) - }, - enumerable: true - }, - //--- - - sendHydrated2: { - /** - * - * @param {String} jid - * @param {String} text - * @param {String} footer - * @param {fs.PathLike} buffer - * @param {String|string[]} url - * @param {String|string[]} urlText - * @param {String|string[]} call - * @param {String|string[]} callText - * @param {String[][]} buttons - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted - * @param {Object} options - */ - async value(jid, text = '', footer = '', buffer, url, urlText, url2, urlText2, buttons, quoted, options) { - let type - if (buffer) try { (type = await conn.getFile(buffer), buffer = type.data) } catch { buffer = buffer } - if (buffer && !Buffer.isBuffer(buffer) && (typeof buffer === 'string' || Array.isArray(buffer))) (options = quoted, quoted = buttons, buttons = callText, callText = call, call = urlText, urlText = url, url = buffer, buffer = null) - if (!options) options = {} - let templateButtons = [] - if (url || urlText) { - if (!Array.isArray(url)) url = [url] - if (!Array.isArray(urlText)) urlText = [urlText] - templateButtons.push(...( - url.map((v, i) => [v, urlText[i]]) - .map(([url, urlText], i) => ({ - index: templateButtons.length + i + 1, - urlButton: { - displayText: !nullish(urlText) && urlText || !nullish(url) && url || '', - url: !nullish(url) && url || !nullish(urlText) && urlText || '' - } - })) || [] - )) - } - if (url2 || urlText2) { - if (!Array.isArray(url2)) url2 = [url2] - if (!Array.isArray(urlText2)) urlText2 = [urlText2] - templateButtons.push(...( - url2.map((v, i) => [v, urlText2[i]]) - .map(([url2, urlText2], i) => ({ - index: templateButtons.length + i + 1, - urlButton: { - displayText: !nullish(urlText2) && urlText2 || !nullish(url2) && url2 || '', - url: !nullish(url2) && url2 || !nullish(urlText2) && urlText2 || '' - } - })) || [] - )) + jpegThumbnail: buffer, + }, } - if (buttons.length) { - if (!Array.isArray(buttons[0])) buttons = [buttons] - templateButtons.push(...( - buttons.map(([text, id], index) => ({ - index: templateButtons.length + index + 1, - quickReplyButton: { - displayText: !nullish(text) && text || !nullish(id) && id || '', - id: !nullish(id) && id || !nullish(text) && text || '' - } - })) || [] - )) + : { + [/video/.test(type.mime) + ? 'video' + : /image/.test(type.mime) + ? 'image' + : 'document']: buffer, } - let message = { + : {}), + } + return await conn.sendMessage(jid, message, { + quoted, + upload: conn.waUploadToServer, + ...options, + }) + }, + enumerable: true, + }, + //--- + + sendHydrated2: { + /** + * + * @param {String} jid + * @param {String} text + * @param {String} footer + * @param {fs.PathLike} buffer + * @param {String|string[]} url + * @param {String|string[]} urlText + * @param {String|string[]} call + * @param {String|string[]} callText + * @param {String[][]} buttons + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} quoted + * @param {Object} options + */ + async value( + jid, + text = '', + footer = '', + buffer, + url, + urlText, + url2, + urlText2, + buttons, + quoted, + options + ) { + let type + if (buffer) + try { + ;(type = await conn.getFile(buffer)), (buffer = type.data) + } catch { + buffer = buffer + } + if ( + buffer && + !Buffer.isBuffer(buffer) && + (typeof buffer === 'string' || Array.isArray(buffer)) + ) + (options = quoted), + (quoted = buttons), + (buttons = callText), + (callText = call), + (call = urlText), + (urlText = url), + (url = buffer), + (buffer = null) + if (!options) options = {} + let templateButtons = [] + if (url || urlText) { + if (!Array.isArray(url)) url = [url] + if (!Array.isArray(urlText)) urlText = [urlText] + templateButtons.push( + ...(url + .map((v, i) => [v, urlText[i]]) + .map(([url, urlText], i) => ({ + index: templateButtons.length + i + 1, + urlButton: { + displayText: (!nullish(urlText) && urlText) || (!nullish(url) && url) || '', + url: (!nullish(url) && url) || (!nullish(urlText) && urlText) || '', + }, + })) || []) + ) + } + if (url2 || urlText2) { + if (!Array.isArray(url2)) url2 = [url2] + if (!Array.isArray(urlText2)) urlText2 = [urlText2] + templateButtons.push( + ...(url2 + .map((v, i) => [v, urlText2[i]]) + .map(([url2, urlText2], i) => ({ + index: templateButtons.length + i + 1, + urlButton: { + displayText: (!nullish(urlText2) && urlText2) || (!nullish(url2) && url2) || '', + url: (!nullish(url2) && url2) || (!nullish(urlText2) && urlText2) || '', + }, + })) || []) + ) + } + if (buttons.length) { + if (!Array.isArray(buttons[0])) buttons = [buttons] + templateButtons.push( + ...(buttons.map(([text, id], index) => ({ + index: templateButtons.length + index + 1, + quickReplyButton: { + displayText: (!nullish(text) && text) || (!nullish(id) && id) || '', + id: (!nullish(id) && id) || (!nullish(text) && text) || '', + }, + })) || []) + ) + } + let message = { + ...options, + [buffer ? 'caption' : 'text']: text || '', + footer, + templateButtons, + ...(buffer + ? options.asLocation && /image/.test(type.mime) + ? { + location: { ...options, - [buffer ? 'caption' : 'text']: text || '', - footer, - templateButtons, - ...(buffer ? - options.asLocation && /image/.test(type.mime) ? { - location: { - ...options, - jpegThumbnail: buffer - } - } : { - [/video/.test(type.mime) ? 'video' : /image/.test(type.mime) ? 'image' : 'document']: buffer - } : {}) + jpegThumbnail: buffer, + }, } - return await conn.sendMessage(jid, message, { - quoted, - upload: conn.waUploadToServer, - ...options - }) - }, - enumerable: true - }, - ///----- - - cMod: { - /** - * cMod - * @param {String} jid - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} message - * @param {String} text - * @param {String} sender - * @param {*} options - * @returns - */ - value(jid, message, text = '', sender = conn.user.jid, options = {}) { - if (options.mentions && !Array.isArray(options.mentions)) options.mentions = [options.mentions] - let copy = message.toJSON() - delete copy.message.messageContextInfo - delete copy.message.senderKeyDistributionMessage - let mtype = Object.keys(copy.message)[0] - let msg = copy.message - let content = msg[mtype] - if (typeof content === 'string') msg[mtype] = text || content - else if (content.caption) content.caption = text || content.caption - else if (content.text) content.text = text || content.text - if (typeof content !== 'string') { - msg[mtype] = { ...content, ...options } - msg[mtype].contextInfo = { - ...(content.contextInfo || {}), - mentionedJid: options.mentions || content.contextInfo?.mentionedJid || [] - } + : { + [/video/.test(type.mime) + ? 'video' + : /image/.test(type.mime) + ? 'image' + : 'document']: buffer, } - if (copy.participant) sender = copy.participant = sender || copy.participant - else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant - if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid - else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid - copy.key.remoteJid = jid - copy.key.fromMe = areJidsSameUser(sender, conn.user.id) || false - return proto.WebMessageInfo.fromObject(copy) - }, - enumerable: true - }, - copyNForward: { - /** - * Exact Copy Forward - * @param {String} jid - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} message - * @param {Boolean|Number} forwardingScore - * @param {Object} options - */ - async value(jid, message, forwardingScore = true, options = {}) { - let vtype - if (options.readViewOnce && message.message.viewOnceMessage?.message) { - vtype = Object.keys(message.message.viewOnceMessage.message)[0] - delete message.message.viewOnceMessage.message[vtype].viewOnce - message.message = proto.Message.fromObject( - JSON.parse(JSON.stringify(message.message.viewOnceMessage.message)) - ) - message.message[vtype].contextInfo = message.message.viewOnceMessage.contextInfo + : {}), + } + return await conn.sendMessage(jid, message, { + quoted, + upload: conn.waUploadToServer, + ...options, + }) + }, + enumerable: true, + }, + ///----- + + cMod: { + /** + * cMod + * @param {String} jid + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} message + * @param {String} text + * @param {String} sender + * @param {*} options + * @returns + */ + value(jid, message, text = '', sender = conn.user.jid, options = {}) { + if (options.mentions && !Array.isArray(options.mentions)) + options.mentions = [options.mentions] + let copy = message.toJSON() + delete copy.message.messageContextInfo + delete copy.message.senderKeyDistributionMessage + let mtype = Object.keys(copy.message)[0] + let msg = copy.message + let content = msg[mtype] + if (typeof content === 'string') msg[mtype] = text || content + else if (content.caption) content.caption = text || content.caption + else if (content.text) content.text = text || content.text + if (typeof content !== 'string') { + msg[mtype] = { ...content, ...options } + msg[mtype].contextInfo = { + ...(content.contextInfo || {}), + mentionedJid: options.mentions || content.contextInfo?.mentionedJid || [], + } + } + if (copy.participant) sender = copy.participant = sender || copy.participant + else if (copy.key.participant) + sender = copy.key.participant = sender || copy.key.participant + if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid + else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid + copy.key.remoteJid = jid + copy.key.fromMe = areJidsSameUser(sender, conn.user.id) || false + return proto.WebMessageInfo.fromObject(copy) + }, + enumerable: true, + }, + copyNForward: { + /** + * Exact Copy Forward + * @param {String} jid + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} message + * @param {Boolean|Number} forwardingScore + * @param {Object} options + */ + async value(jid, message, forwardingScore = true, options = {}) { + let vtype + if (options.readViewOnce && message.message.viewOnceMessage?.message) { + vtype = Object.keys(message.message.viewOnceMessage.message)[0] + delete message.message.viewOnceMessage.message[vtype].viewOnce + message.message = proto.Message.fromObject( + JSON.parse(JSON.stringify(message.message.viewOnceMessage.message)) + ) + message.message[vtype].contextInfo = message.message.viewOnceMessage.contextInfo + } + let mtype = Object.keys(message.message)[0] + let m = generateForwardMessageContent(message, !!forwardingScore) + let ctype = Object.keys(m)[0] + if (forwardingScore && typeof forwardingScore === 'number' && forwardingScore > 1) + m[ctype].contextInfo.forwardingScore += forwardingScore + m[ctype].contextInfo = { + ...(message.message[mtype].contextInfo || {}), + ...(m[ctype].contextInfo || {}), + } + m = generateWAMessageFromContent(jid, m, { + ...options, + userJid: conn.user.jid, + }) + await conn.relayMessage(jid, m.message, { + messageId: m.key.id, + additionalAttributes: { ...options }, + }) + return m + }, + enumerable: true, + }, + fakeReply: { + /** + * Fake Replies + * @param {String} jid + * @param {String|Object} text + * @param {String} fakeJid + * @param {String} fakeText + * @param {String} fakeGroupJid + * @param {String} options + */ + value(jid, text = '', fakeJid = this.user.jid, fakeText = '', fakeGroupJid, options) { + return conn.reply(jid, text, { + key: { + fromMe: areJidsSameUser(fakeJid, conn.user.id), + participant: fakeJid, + ...(fakeGroupJid ? { remoteJid: fakeGroupJid } : {}), + }, + message: { conversation: fakeText }, + ...options, + }) + }, + }, + downloadM: { + /** + * Download media message + * @param {Object} m + * @param {String} type + * @param {fs.PathLike | fs.promises.FileHandle} saveToFile + * @returns {Promise} + */ + async value(m, type, saveToFile) { + let filename + if (!m || !(m.url || m.directPath)) return Buffer.alloc(0) + const stream = await downloadContentFromMessage(m, type) + let buffer = Buffer.from([]) + for await (const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + if (saveToFile) ({ filename } = await conn.getFile(buffer, true)) + return saveToFile && fs.existsSync(filename) ? filename : buffer + }, + enumerable: true, + }, + parseMention: { + /** + * Parses string into mentionedJid(s) + * @param {String} text + * @returns {Array} + */ + value(text = '') { + return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net') + }, + enumerable: true, + }, + getName: { + /** + * Get name from jid + * @param {String} jid + * @param {Boolean} withoutContact + */ + value(jid = '', withoutContact = false) { + jid = conn.decodeJid(jid) + withoutContact = conn.withoutContact || withoutContact + let v + if (jid.endsWith('@g.us')) + return new Promise(async resolve => { + v = conn.chats[jid] || {} + if (!(v.name || v.subject)) v = (await conn.groupMetadata(jid)) || {} + resolve( + v.name || + v.subject || + PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international') + ) + }) + else + v = + jid === '0@s.whatsapp.net' + ? { + jid, + vname: 'WhatsApp', } - let mtype = Object.keys(message.message)[0] - let m = generateForwardMessageContent(message, !!forwardingScore) - let ctype = Object.keys(m)[0] - if (forwardingScore && typeof forwardingScore === 'number' && forwardingScore > 1) m[ctype].contextInfo.forwardingScore += forwardingScore - m[ctype].contextInfo = { - ...(message.message[mtype].contextInfo || {}), - ...(m[ctype].contextInfo || {}) + : areJidsSameUser(jid, conn.user.id) + ? conn.user + : conn.chats[jid] || {} + return ( + (withoutContact ? '' : v.name) || + v.subject || + v.vname || + v.notify || + v.verifiedName || + PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international') + ) + }, + enumerable: true, + }, + loadMessage: { + /** + * + * @param {String} messageID + * @returns {import('@whiskeysockets/baileys').proto.WebMessageInfo} + */ + value(messageID) { + return Object.entries(conn.chats) + .filter(([_, { messages }]) => typeof messages === 'object') + .find(([_, { messages }]) => + Object.entries(messages).find(([k, v]) => k === messageID || v.key?.id === messageID) + )?.[1].messages?.[messageID] + }, + enumerable: true, + }, + sendGroupV4Invite: { + /** + * sendGroupV4Invite + * @param {String} jid + * @param {*} participant + * @param {String} inviteCode + * @param {Number} inviteExpiration + * @param {String} groupName + * @param {String} caption + * @param {Buffer} jpegThumbnail + * @param {*} options + */ + async value( + jid, + participant, + inviteCode, + inviteExpiration, + groupName = 'unknown subject', + caption = 'Invitation to join my WhatsApp group', + jpegThumbnail, + options = {} + ) { + const msg = proto.Message.fromObject({ + groupInviteMessage: proto.GroupInviteMessage.fromObject({ + inviteCode, + inviteExpiration: parseInt(inviteExpiration) || +new Date(new Date() + 3 * 86400000), + groupJid: jid, + groupName: (groupName ? groupName : await conn.getName(jid)) || null, + jpegThumbnail: Buffer.isBuffer(jpegThumbnail) ? jpegThumbnail : null, + caption, + }), + }) + const message = generateWAMessageFromContent(participant, msg, options) + await conn.relayMessage(participant, message.message, { + messageId: message.key.id, + additionalAttributes: { ...options }, + }) + return message + }, + enumerable: true, + }, + processMessageStubType: { + /** + * to process MessageStubType + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} m + */ + async value(m) { + if (!m.messageStubType) return + const chat = conn.decodeJid( + m.key.remoteJid || m.message?.senderKeyDistributionMessage?.groupId || '' + ) + if (!chat || chat === 'status@broadcast') return + const emitGroupUpdate = update => { + ev.emit('groups.update', [{ id: chat, ...update }]) + } + switch (m.messageStubType) { + case WAMessageStubType.REVOKE: + case WAMessageStubType.GROUP_CHANGE_INVITE_LINK: + emitGroupUpdate({ revoke: m.messageStubParameters[0] }) + break + case WAMessageStubType.GROUP_CHANGE_ICON: + emitGroupUpdate({ icon: m.messageStubParameters[0] }) + break + default: { + console.log({ + messageStubType: m.messageStubType, + messageStubParameters: m.messageStubParameters, + type: WAMessageStubType[m.messageStubType], + }) + break + } + } + const isGroup = chat.endsWith('@g.us') + if (!isGroup) return + let chats = conn.chats[chat] + if (!chats) chats = conn.chats[chat] = { id: chat } + chats.isChats = true + const metadata = await conn.groupMetadata(chat).catch(_ => null) + if (!metadata) return + chats.subject = metadata.subject + chats.metadata = metadata + }, + }, + insertAllGroup: { + async value() { + const groups = (await conn.groupFetchAllParticipating().catch(_ => null)) || {} + for (const group in groups) + conn.chats[group] = { + ...(conn.chats[group] || {}), + id: group, + subject: groups[group].subject, + isChats: true, + metadata: groups[group], + } + return conn.chats + }, + }, + pushMessage: { + /** + * pushMessage + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo[]} m + */ + async value(m) { + if (!m) return + if (!Array.isArray(m)) m = [m] + for (const message of m) { + try { + // if (!(message instanceof proto.WebMessageInfo)) continue // https://github.com/adiwajshing/Baileys/pull/696/commits/6a2cb5a4139d8eb0a75c4c4ea7ed52adc0aec20f + if (!message) continue + if (message.messageStubType && message.messageStubType != WAMessageStubType.CIPHERTEXT) + conn.processMessageStubType(message).catch(console.error) + const _mtype = Object.keys(message.message || {}) + const mtype = + (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(_mtype[0]) && + _mtype[0]) || + (_mtype.length >= 3 && _mtype[1] !== 'messageContextInfo' && _mtype[1]) || + _mtype[_mtype.length - 1] + const chat = conn.decodeJid( + message.key.remoteJid || message.message?.senderKeyDistributionMessage?.groupId || '' + ) + if (message.message?.[mtype]?.contextInfo?.quotedMessage) { + /** + * @type {import('@whiskeysockets/baileys').proto.IContextInfo} + */ + let context = message.message[mtype].contextInfo + let participant = conn.decodeJid(context.participant) + const remoteJid = conn.decodeJid(context.remoteJid || participant) + /** + * @type {import('@whiskeysockets/baileys').proto.IMessage} + * + */ + let quoted = message.message[mtype].contextInfo.quotedMessage + if (remoteJid && remoteJid !== 'status@broadcast' && quoted) { + let qMtype = Object.keys(quoted)[0] + if (qMtype == 'conversation') { + quoted.extendedTextMessage = { text: quoted[qMtype] } + delete quoted.conversation + qMtype = 'extendedTextMessage' } - m = generateWAMessageFromContent(jid, m, { - ...options, - userJid: conn.user.jid - }) - await conn.relayMessage(jid, m.message, { messageId: m.key.id, additionalAttributes: { ...options } }) - return m - }, - enumerable: true - }, - fakeReply: { - /** - * Fake Replies - * @param {String} jid - * @param {String|Object} text - * @param {String} fakeJid - * @param {String} fakeText - * @param {String} fakeGroupJid - * @param {String} options - */ - value(jid, text = '', fakeJid = this.user.jid, fakeText = '', fakeGroupJid, options) { - return conn.reply(jid, text, { key: { fromMe: areJidsSameUser(fakeJid, conn.user.id), participant: fakeJid, ...(fakeGroupJid ? { remoteJid: fakeGroupJid } : {}) }, message: { conversation: fakeText }, ...options }) - } - }, - downloadM: { - /** - * Download media message - * @param {Object} m - * @param {String} type - * @param {fs.PathLike | fs.promises.FileHandle} saveToFile - * @returns {Promise} - */ - async value(m, type, saveToFile) { - let filename - if (!m || !(m.url || m.directPath)) return Buffer.alloc(0) - const stream = await downloadContentFromMessage(m, type) - let buffer = Buffer.from([]) - for await (const chunk of stream) { - buffer = Buffer.concat([buffer, chunk]) + if (!quoted[qMtype].contextInfo) quoted[qMtype].contextInfo = {} + quoted[qMtype].contextInfo.mentionedJid = + context.mentionedJid || quoted[qMtype].contextInfo.mentionedJid || [] + const isGroup = remoteJid.endsWith('g.us') + if (isGroup && !participant) participant = remoteJid + const qM = { + key: { + remoteJid, + fromMe: areJidsSameUser(conn.user.jid, remoteJid), + id: context.stanzaId, + participant, + }, + message: JSON.parse(JSON.stringify(quoted)), + ...(isGroup ? { participant } : {}), } - if (saveToFile) ({ filename } = await conn.getFile(buffer, true)) - return saveToFile && fs.existsSync(filename) ? filename : buffer - }, - enumerable: true - }, - parseMention: { - /** - * Parses string into mentionedJid(s) - * @param {String} text - * @returns {Array} - */ - value(text = '') { - return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map(v => v[1] + '@s.whatsapp.net') - }, - enumerable: true - }, - getName: { + let qChats = conn.chats[participant] + if (!qChats) + qChats = conn.chats[participant] = { id: participant, isChats: !isGroup } + if (!qChats.messages) qChats.messages = {} + if (!qChats.messages[context.stanzaId] && !qM.key.fromMe) + qChats.messages[context.stanzaId] = qM + let qChatsMessages + if ((qChatsMessages = Object.entries(qChats.messages)).length > 40) + qChats.messages = Object.fromEntries( + qChatsMessages.slice(30, qChatsMessages.length) + ) // maybe avoid memory leak + } + } + if (!chat || chat === 'status@broadcast') continue + const isGroup = chat.endsWith('@g.us') + let chats = conn.chats[chat] + if (!chats) { + if (isGroup) await conn.insertAllGroup().catch(console.error) + chats = conn.chats[chat] = { id: chat, isChats: true, ...(conn.chats[chat] || {}) } + } + let metadata, sender + if (isGroup) { + if (!chats.subject || !chats.metadata) { + metadata = (await conn.groupMetadata(chat).catch(_ => ({}))) || {} + if (!chats.subject) chats.subject = metadata.subject || '' + if (!chats.metadata) chats.metadata = metadata + } + sender = conn.decodeJid( + (message.key?.fromMe && conn.user.id) || + message.participant || + message.key?.participant || + chat || + '' + ) + if (sender !== chat) { + let chats = conn.chats[sender] + if (!chats) chats = conn.chats[sender] = { id: sender } + if (!chats.name) chats.name = message.pushName || chats.name || '' + } + } else if (!chats.name) chats.name = message.pushName || chats.name || '' + if (['senderKeyDistributionMessage', 'messageContextInfo'].includes(mtype)) continue + chats.isChats = true + if (!chats.messages) chats.messages = {} + const fromMe = message.key.fromMe || areJidsSameUser(sender || chat, conn.user.id) + if ( + !['protocolMessage'].includes(mtype) && + !fromMe && + message.messageStubType != WAMessageStubType.CIPHERTEXT && + message.message + ) { + delete message.message.messageContextInfo + delete message.message.senderKeyDistributionMessage + chats.messages[message.key.id] = JSON.parse(JSON.stringify(message, null, 2)) + let chatsMessages + if ((chatsMessages = Object.entries(chats.messages)).length > 40) + chats.messages = Object.fromEntries(chatsMessages.slice(30, chatsMessages.length)) + } + } catch (e) { + console.error(e) + } + } + }, + }, + serializeM: { + /** + * Serialize Message, so it easier to manipulate + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} m + */ + value(m) { + return smsg(conn, m) + }, + }, + ...(typeof conn.chatRead !== 'function' + ? { + chatRead: { /** - * Get name from jid + * Read message * @param {String} jid - * @param {Boolean} withoutContact - */ - value(jid = '', withoutContact = false) { - jid = conn.decodeJid(jid) - withoutContact = conn.withoutContact || withoutContact - let v - if (jid.endsWith('@g.us')) return new Promise(async (resolve) => { - v = conn.chats[jid] || {} - if (!(v.name || v.subject)) v = await conn.groupMetadata(jid) || {} - resolve(v.name || v.subject || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international')) - }) - else v = jid === '0@s.whatsapp.net' ? { - jid, - vname: 'WhatsApp' - } : areJidsSameUser(jid, conn.user.id) ? - conn.user : - (conn.chats[jid] || {}) - return (withoutContact ? '' : v.name) || v.subject || v.vname || v.notify || v.verifiedName || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international') - }, - enumerable: true - }, - loadMessage: { - /** - * - * @param {String} messageID - * @returns {import('@whiskeysockets/baileys').proto.WebMessageInfo} - */ - value(messageID) { - return Object.entries(conn.chats) - .filter(([_, { messages }]) => typeof messages === 'object') - .find(([_, { messages }]) => Object.entries(messages) - .find(([k, v]) => (k === messageID || v.key?.id === messageID))) - ?.[1].messages?.[messageID] - }, - enumerable: true - }, - sendGroupV4Invite: { - /** - * sendGroupV4Invite - * @param {String} jid - * @param {*} participant - * @param {String} inviteCode - * @param {Number} inviteExpiration - * @param {String} groupName - * @param {String} caption - * @param {Buffer} jpegThumbnail - * @param {*} options - */ - async value(jid, participant, inviteCode, inviteExpiration, groupName = 'unknown subject', caption = 'Invitation to join my WhatsApp group', jpegThumbnail, options = {}) { - const msg = proto.Message.fromObject({ - groupInviteMessage: proto.GroupInviteMessage.fromObject({ - inviteCode, - inviteExpiration: parseInt(inviteExpiration) || + new Date(new Date + (3 * 86400000)), - groupJid: jid, - groupName: (groupName ? groupName : await conn.getName(jid)) || null, - jpegThumbnail: Buffer.isBuffer(jpegThumbnail) ? jpegThumbnail : null, - caption - }) - }) - const message = generateWAMessageFromContent(participant, msg, options) - await conn.relayMessage(participant, message.message, { messageId: message.key.id, additionalAttributes: { ...options } }) - return message - }, - enumerable: true - }, - processMessageStubType: { - /** - * to process MessageStubType - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} m + * @param {String|undefined|null} participant + * @param {String} messageID */ - async value(m) { - if (!m.messageStubType) return - const chat = conn.decodeJid(m.key.remoteJid || m.message?.senderKeyDistributionMessage?.groupId || '') - if (!chat || chat === 'status@broadcast') return - const emitGroupUpdate = (update) => { - ev.emit('groups.update', [{ id: chat, ...update }]) - } - switch (m.messageStubType) { - case WAMessageStubType.REVOKE: - case WAMessageStubType.GROUP_CHANGE_INVITE_LINK: - emitGroupUpdate({ revoke: m.messageStubParameters[0] }) - break - case WAMessageStubType.GROUP_CHANGE_ICON: - emitGroupUpdate({ icon: m.messageStubParameters[0] }) - break - default: { - console.log({ - messageStubType: m.messageStubType, - messageStubParameters: m.messageStubParameters, - type: WAMessageStubType[m.messageStubType] - }) - break - } - } - const isGroup = chat.endsWith('@g.us') - if (!isGroup) return - let chats = conn.chats[chat] - if (!chats) chats = conn.chats[chat] = { id: chat } - chats.isChats = true - const metadata = await conn.groupMetadata(chat).catch(_ => null) - if (!metadata) return - chats.subject = metadata.subject - chats.metadata = metadata - } - }, - insertAllGroup: { - async value() { - const groups = await conn.groupFetchAllParticipating().catch(_ => null) || {} - for (const group in groups) conn.chats[group] = { ...(conn.chats[group] || {}), id: group, subject: groups[group].subject, isChats: true, metadata: groups[group] } - return conn.chats + value(jid, participant = conn.user.jid, messageID) { + return conn.sendReadReceipt(jid, participant, [messageID]) }, - }, - pushMessage: { - /** - * pushMessage - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo[]} m - */ - async value(m) { - if (!m) return - if (!Array.isArray(m)) m = [m] - for (const message of m) { - try { - // if (!(message instanceof proto.WebMessageInfo)) continue // https://github.com/adiwajshing/Baileys/pull/696/commits/6a2cb5a4139d8eb0a75c4c4ea7ed52adc0aec20f - if (!message) continue - if (message.messageStubType && message.messageStubType != WAMessageStubType.CIPHERTEXT) conn.processMessageStubType(message).catch(console.error) - const _mtype = Object.keys(message.message || {}) - const mtype = (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(_mtype[0]) && _mtype[0]) || - (_mtype.length >= 3 && _mtype[1] !== 'messageContextInfo' && _mtype[1]) || - _mtype[_mtype.length - 1] - const chat = conn.decodeJid(message.key.remoteJid || message.message?.senderKeyDistributionMessage?.groupId || '') - if (message.message?.[mtype]?.contextInfo?.quotedMessage) { - /** - * @type {import('@whiskeysockets/baileys').proto.IContextInfo} - */ - let context = message.message[mtype].contextInfo - let participant = conn.decodeJid(context.participant) - const remoteJid = conn.decodeJid(context.remoteJid || participant) - /** - * @type {import('@whiskeysockets/baileys').proto.IMessage} - * - */ - let quoted = message.message[mtype].contextInfo.quotedMessage - if ((remoteJid && remoteJid !== 'status@broadcast') && quoted) { - let qMtype = Object.keys(quoted)[0] - if (qMtype == 'conversation') { - quoted.extendedTextMessage = { text: quoted[qMtype] } - delete quoted.conversation - qMtype = 'extendedTextMessage' - } - if (!quoted[qMtype].contextInfo) quoted[qMtype].contextInfo = {} - quoted[qMtype].contextInfo.mentionedJid = context.mentionedJid || quoted[qMtype].contextInfo.mentionedJid || [] - const isGroup = remoteJid.endsWith('g.us') - if (isGroup && !participant) participant = remoteJid - const qM = { - key: { - remoteJid, - fromMe: areJidsSameUser(conn.user.jid, remoteJid), - id: context.stanzaId, - participant, - }, - message: JSON.parse(JSON.stringify(quoted)), - ...(isGroup ? { participant } : {}) - } - let qChats = conn.chats[participant] - if (!qChats) qChats = conn.chats[participant] = { id: participant, isChats: !isGroup } - if (!qChats.messages) qChats.messages = {} - if (!qChats.messages[context.stanzaId] && !qM.key.fromMe) qChats.messages[context.stanzaId] = qM - let qChatsMessages - if ((qChatsMessages = Object.entries(qChats.messages)).length > 40) qChats.messages = Object.fromEntries(qChatsMessages.slice(30, qChatsMessages.length)) // maybe avoid memory leak - } - } - if (!chat || chat === 'status@broadcast') continue - const isGroup = chat.endsWith('@g.us') - let chats = conn.chats[chat] - if (!chats) { - if (isGroup) await conn.insertAllGroup().catch(console.error) - chats = conn.chats[chat] = { id: chat, isChats: true, ...(conn.chats[chat] || {}) } - } - let metadata, sender - if (isGroup) { - if (!chats.subject || !chats.metadata) { - metadata = await conn.groupMetadata(chat).catch(_ => ({})) || {} - if (!chats.subject) chats.subject = metadata.subject || '' - if (!chats.metadata) chats.metadata = metadata - } - sender = conn.decodeJid(message.key?.fromMe && conn.user.id || message.participant || message.key?.participant || chat || '') - if (sender !== chat) { - let chats = conn.chats[sender] - if (!chats) chats = conn.chats[sender] = { id: sender } - if (!chats.name) chats.name = message.pushName || chats.name || '' - } - } else if (!chats.name) chats.name = message.pushName || chats.name || '' - if (['senderKeyDistributionMessage', 'messageContextInfo'].includes(mtype)) continue - chats.isChats = true - if (!chats.messages) chats.messages = {} - const fromMe = message.key.fromMe || areJidsSameUser(sender || chat, conn.user.id) - if (!['protocolMessage'].includes(mtype) && !fromMe && message.messageStubType != WAMessageStubType.CIPHERTEXT && message.message) { - delete message.message.messageContextInfo - delete message.message.senderKeyDistributionMessage - chats.messages[message.key.id] = JSON.parse(JSON.stringify(message, null, 2)) - let chatsMessages - if ((chatsMessages = Object.entries(chats.messages)).length > 40) chats.messages = Object.fromEntries(chatsMessages.slice(30, chatsMessages.length)) - } - } catch (e) { - console.error(e) - } - } - } - }, - serializeM: { + enumerable: true, + }, + } + : {}), + ...(typeof conn.setStatus !== 'function' + ? { + setStatus: { /** - * Serialize Message, so it easier to manipulate - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} m + * setStatus bot + * @param {String} status */ - value(m) { - return smsg(conn, m) - } - }, - ...(typeof conn.chatRead !== 'function' ? { - chatRead: { - /** - * Read message - * @param {String} jid - * @param {String|undefined|null} participant - * @param {String} messageID - */ - value(jid, participant = conn.user.jid, messageID) { - return conn.sendReadReceipt(jid, participant, [messageID]) + value(status) { + return conn.query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + xmlns: 'status', }, - enumerable: true - } - } : {}), - ...(typeof conn.setStatus !== 'function' ? { - setStatus: { - /** - * setStatus bot - * @param {String} status - */ - value(status) { - return conn.query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'set', - xmlns: 'status', - }, - content: [ - { - tag: 'status', - attrs: {}, - content: Buffer.from(status, 'utf-8') - } - ] - }) - }, - enumerable: true - } - } : {}) - }) - if (sock.user?.id) sock.user.jid = sock.decodeJid(sock.user.id) - store.bind(sock) - return sock + content: [ + { + tag: 'status', + attrs: {}, + content: Buffer.from(status, 'utf-8'), + }, + ], + }) + }, + enumerable: true, + }, + } + : {}), + }) + if (sock.user?.id) sock.user.jid = sock.decodeJid(sock.user.id) + store.bind(sock) + return sock } /** * Serialize Message - * @param {ReturnType} conn - * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} m - * @param {Boolean} hasParent + * @param {ReturnType} conn + * @param {import('@whiskeysockets/baileys').proto.WebMessageInfo} m + * @param {Boolean} hasParent */ export function smsg(conn, m, hasParent) { - if (!m) return m - /** - * @type {import('@whiskeysockets/baileys').proto.WebMessageInfo} - */ - let M = proto.WebMessageInfo - m = M.fromObject(m) - m.conn = conn - let protocolMessageKey - if (m.message) { - if (m.mtype == 'protocolMessage' && m.msg.key) { - protocolMessageKey = m.msg.key - if (protocolMessageKey == 'status@broadcast') protocolMessageKey.remoteJid = m.chat - if (!protocolMessageKey.participant || protocolMessageKey.participant == 'status_me') protocolMessageKey.participant = m.sender - protocolMessageKey.fromMe = conn.decodeJid(protocolMessageKey.participant) === conn.decodeJid(conn.user.id) - if (!protocolMessageKey.fromMe && protocolMessageKey.remoteJid === conn.decodeJid(conn.user.id)) protocolMessageKey.remoteJid = m.sender - } - if (m.quoted) if (!m.quoted.mediaMessage) delete m.quoted.download + if (!m) return m + /** + * @type {import('@whiskeysockets/baileys').proto.WebMessageInfo} + */ + let M = proto.WebMessageInfo + m = M.fromObject(m) + m.conn = conn + let protocolMessageKey + if (m.message) { + if (m.mtype == 'protocolMessage' && m.msg.key) { + protocolMessageKey = m.msg.key + if (protocolMessageKey == 'status@broadcast') protocolMessageKey.remoteJid = m.chat + if (!protocolMessageKey.participant || protocolMessageKey.participant == 'status_me') + protocolMessageKey.participant = m.sender + protocolMessageKey.fromMe = + conn.decodeJid(protocolMessageKey.participant) === conn.decodeJid(conn.user.id) + if ( + !protocolMessageKey.fromMe && + protocolMessageKey.remoteJid === conn.decodeJid(conn.user.id) + ) + protocolMessageKey.remoteJid = m.sender } - if (!m.mediaMessage) delete m.download + if (m.quoted) if (!m.quoted.mediaMessage) delete m.quoted.download + } + if (!m.mediaMessage) delete m.download - try { - if (protocolMessageKey && m.mtype == 'protocolMessage') conn.ev.emit('message.delete', protocolMessageKey) - } catch (e) { - console.error(e) - } - return m + try { + if (protocolMessageKey && m.mtype == 'protocolMessage') + conn.ev.emit('message.delete', protocolMessageKey) + } catch (e) { + console.error(e) + } + return m } // https://github.com/Nurutomo/wabot-aq/issues/490 export function serialize() { - const MediaType = ['imageMessage', 'videoMessage', 'audioMessage', 'stickerMessage', 'documentMessage'] - return Object.defineProperties(proto.WebMessageInfo.prototype, { - conn: { - value: undefined, - enumerable: false, - writable: true - }, - id: { - get() { - return this.key?.id - } - }, - isBaileys: { - get() { - return this.id?.length === 16 || this.id?.startsWith('3EB0') && this.id?.length === 12 || false - } - }, - chat: { - get() { - const senderKeyDistributionMessage = this.message?.senderKeyDistributionMessage?.groupId - return ( - this.key?.remoteJid || - (senderKeyDistributionMessage && - senderKeyDistributionMessage !== 'status@broadcast' - ) || '' - ).decodeJid() - } - }, - isGroup: { - get() { - return this.chat.endsWith('@g.us') - }, - enumerable: true - }, - sender: { - get() { - return this.conn?.decodeJid(this.key?.fromMe && this.conn?.user.id || this.participant || this.key.participant || this.chat || '') - }, - enumerable: true - }, - fromMe: { - get() { - return this.key?.fromMe || areJidsSameUser(this.conn?.user.id, this.sender) || false - } - }, - mtype: { - get() { - if (!this.message) return '' - const type = Object.keys(this.message) - return (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(type[0]) && type[0]) || // Sometimes message in the front - (type.length >= 3 && type[1] !== 'messageContextInfo' && type[1]) || // Sometimes message in midle if mtype length is greater than or equal to 3 - type[type.length - 1] // common case + const MediaType = [ + 'imageMessage', + 'videoMessage', + 'audioMessage', + 'stickerMessage', + 'documentMessage', + ] + return Object.defineProperties(proto.WebMessageInfo.prototype, { + conn: { + value: undefined, + enumerable: false, + writable: true, + }, + id: { + get() { + return this.key?.id + }, + }, + isBaileys: { + get() { + return ( + this.id?.length === 16 || (this.id?.startsWith('3EB0') && this.id?.length === 12) || false + ) + }, + }, + chat: { + get() { + const senderKeyDistributionMessage = this.message?.senderKeyDistributionMessage?.groupId + return ( + this.key?.remoteJid || + (senderKeyDistributionMessage && senderKeyDistributionMessage !== 'status@broadcast') || + '' + ).decodeJid() + }, + }, + isGroup: { + get() { + return this.chat.endsWith('@g.us') + }, + enumerable: true, + }, + sender: { + get() { + return this.conn?.decodeJid( + (this.key?.fromMe && this.conn?.user.id) || + this.participant || + this.key.participant || + this.chat || + '' + ) + }, + enumerable: true, + }, + fromMe: { + get() { + return this.key?.fromMe || areJidsSameUser(this.conn?.user.id, this.sender) || false + }, + }, + mtype: { + get() { + if (!this.message) return '' + const type = Object.keys(this.message) + return ( + (!['senderKeyDistributionMessage', 'messageContextInfo'].includes(type[0]) && type[0]) || // Sometimes message in the front + (type.length >= 3 && type[1] !== 'messageContextInfo' && type[1]) || // Sometimes message in midle if mtype length is greater than or equal to 3 + type[type.length - 1] + ) // common case + }, + enumerable: true, + }, + msg: { + get() { + if (!this.message) return null + return this.message[this.mtype] + }, + }, + mediaMessage: { + get() { + if (!this.message) return null + const Message = + (this.msg?.url || this.msg?.directPath + ? { ...this.message } + : extractMessageContent(this.message)) || null + if (!Message) return null + const mtype = Object.keys(Message)[0] + return MediaType.includes(mtype) ? Message : null + }, + enumerable: true, + }, + mediaType: { + get() { + let message + if (!(message = this.mediaMessage)) return null + return Object.keys(message)[0] + }, + enumerable: true, + }, + quoted: { + get() { + /** + * @type {ReturnType} + */ + const self = this + const msg = self.msg + const contextInfo = msg?.contextInfo + const quoted = contextInfo?.quotedMessage + if (!msg || !contextInfo || !quoted) return null + const type = Object.keys(quoted)[0] + let q = quoted[type] + const text = typeof q === 'string' ? q : q.text + return Object.defineProperties( + JSON.parse(JSON.stringify(typeof q === 'string' ? { text: q } : q)), + { + mtype: { + get() { + return type + }, + enumerable: true, }, - enumerable: true - }, - msg: { - get() { - if (!this.message) return null - return this.message[this.mtype] - } - }, - mediaMessage: { - get() { - if (!this.message) return null - const Message = ((this.msg?.url || this.msg?.directPath) ? { ...this.message } : extractMessageContent(this.message)) || null + mediaMessage: { + get() { + const Message = + (q.url || q.directPath ? { ...quoted } : extractMessageContent(quoted)) || null if (!Message) return null const mtype = Object.keys(Message)[0] return MediaType.includes(mtype) ? Message : null + }, + enumerable: true, }, - enumerable: true - }, - mediaType: { - get() { + mediaType: { + get() { let message if (!(message = this.mediaMessage)) return null return Object.keys(message)[0] + }, + enumerable: true, }, - enumerable: true, - }, - quoted: { - get() { - /** - * @type {ReturnType} - */ - const self = this - const msg = self.msg - const contextInfo = msg?.contextInfo - const quoted = contextInfo?.quotedMessage - if (!msg || !contextInfo || !quoted) return null - const type = Object.keys(quoted)[0] - let q = quoted[type] - const text = typeof q === 'string' ? q : q.text - return Object.defineProperties(JSON.parse(JSON.stringify(typeof q === 'string' ? { text: q } : q)), { - mtype: { - get() { - return type - }, - enumerable: true - }, - mediaMessage: { - get() { - const Message = ((q.url || q.directPath) ? { ...quoted } : extractMessageContent(quoted)) || null - if (!Message) return null - const mtype = Object.keys(Message)[0] - return MediaType.includes(mtype) ? Message : null - }, - enumerable: true - }, - mediaType: { - get() { - let message - if (!(message = this.mediaMessage)) return null - return Object.keys(message)[0] - }, - enumerable: true, - }, - id: { - get() { - return contextInfo.stanzaId - }, - enumerable: true - }, - chat: { - get() { - return contextInfo.remoteJid || self.chat - }, - enumerable: true - }, - isBaileys: { - get() { - return this.id?.length === 16 || this.id?.startsWith('3EB0') && this.id.length === 12 || false - }, - enumerable: true - }, - sender: { - get() { - return (contextInfo.participant || this.chat || '').decodeJid() - }, - enumerable: true - }, - fromMe: { - get() { - return areJidsSameUser(this.sender, self.conn?.user.jid) - }, - enumerable: true, - }, - text: { - get() { - return text || this.caption || this.contentText || this.selectedDisplayText || '' - }, - enumerable: true - }, - mentionedJid: { - get() { - return q.contextInfo?.mentionedJid || self.getQuotedObj()?.mentionedJid || [] - }, - enumerable: true - }, - name: { - get() { - const sender = this.sender - return sender ? self.conn?.getName(sender) : null - }, - enumerable: true - - }, - vM: { - get() { - return proto.WebMessageInfo.fromObject({ - key: { - fromMe: this.fromMe, - remoteJid: this.chat, - id: this.id - }, - message: quoted, - ...(self.isGroup ? { participant: this.sender } : {}) - }) - } - }, - fakeObj: { - get() { - return this.vM - } - }, - download: { - value(saveToFile = false) { - const mtype = this.mediaType - return self.conn?.downloadM(this.mediaMessage[mtype], mtype.replace(/message/i, ''), saveToFile) - }, - enumerable: true, - configurable: true, - }, - reply: { - /** - * Reply to quoted message - * @param {String|Object} text - * @param {String|false} chatId - * @param {Object} options - */ - value(text, chatId, options) { - return self.conn?.reply(chatId ? chatId : this.chat, text, this.vM, options) - }, - enumerable: true, - }, - copy: { - /** - * Copy quoted message - */ - value() { - const M = proto.WebMessageInfo - return smsg(conn, M.fromObject(M.toObject(this.vM))) - }, - enumerable: true, - }, - forward: { - /** - * Forward quoted message - * @param {String} jid - * @param {Boolean} forceForward - */ - value(jid, force = false, options) { - return self.conn?.sendMessage(jid, { - forward: this.vM, force, ...options - }, { ...options }) - }, - enumerable: true, - }, - copyNForward: { - /** - * Exact Forward quoted message - * @param {String} jid - * @param {Boolean|Number} forceForward - * @param {Object} options - */ - value(jid, forceForward = false, options) { - return self.conn?.copyNForward(jid, this.vM, forceForward, options) - }, - enumerable: true, - - }, - cMod: { - /** - * Modify quoted Message - * @param {String} jid - * @param {String} text - * @param {String} sender - * @param {Object} options - */ - value(jid, text = '', sender = this.sender, options = {}) { - return self.conn?.cMod(jid, this.vM, text, sender, options) - }, - enumerable: true, - - }, - delete: { - /** - * Delete quoted message - */ - value() { - return self.conn?.sendMessage(this.chat, { delete: this.vM.key }) - }, - enumerable: true, - - }, - //react - react: { - value(text) { - return self.conn?.sendMessage(this.chat, { - react: { - text, - key: this.vM.key - } - }) - }, - enumerable: true, - } - // - }) + id: { + get() { + return contextInfo.stanzaId + }, + enumerable: true, + }, + chat: { + get() { + return contextInfo.remoteJid || self.chat + }, + enumerable: true, + }, + isBaileys: { + get() { + return ( + this.id?.length === 16 || + (this.id?.startsWith('3EB0') && this.id.length === 12) || + false + ) + }, + enumerable: true, + }, + sender: { + get() { + return (contextInfo.participant || this.chat || '').decodeJid() + }, + enumerable: true, + }, + fromMe: { + get() { + return areJidsSameUser(this.sender, self.conn?.user.jid) + }, + enumerable: true, }, - enumerable: true - }, - _text: { - value: null, - writable: true, - }, - text: { - get() { - const msg = this.msg - const text = (typeof msg === 'string' ? msg : msg?.text) || msg?.caption || msg?.contentText || '' - return typeof this._text === 'string' ? this._text : '' || (typeof text === 'string' ? text : ( - text?.selectedDisplayText || - text?.hydratedTemplate?.hydratedContentText || - text - )) || '' + text: { + get() { + return text || this.caption || this.contentText || this.selectedDisplayText || '' + }, + enumerable: true, }, - set(str) { - return this._text = str + mentionedJid: { + get() { + return q.contextInfo?.mentionedJid || self.getQuotedObj()?.mentionedJid || [] + }, + enumerable: true, }, - enumerable: true - }, - mentionedJid: { - get() { - return this.msg?.contextInfo?.mentionedJid?.length && this.msg.contextInfo.mentionedJid || [] + name: { + get() { + const sender = this.sender + return sender ? self.conn?.getName(sender) : null + }, + enumerable: true, }, - enumerable: true - }, - name: { - get() { - return !nullish(this.pushName) && this.pushName || this.conn?.getName(this.sender) + vM: { + get() { + return proto.WebMessageInfo.fromObject({ + key: { + fromMe: this.fromMe, + remoteJid: this.chat, + id: this.id, + }, + message: quoted, + ...(self.isGroup ? { participant: this.sender } : {}), + }) + }, + }, + fakeObj: { + get() { + return this.vM + }, }, - enumerable: true - }, - download: { - value(saveToFile = false) { + download: { + value(saveToFile = false) { const mtype = this.mediaType - return this.conn?.downloadM(this.mediaMessage[mtype], mtype.replace(/message/i, ''), saveToFile) + return self.conn?.downloadM( + this.mediaMessage[mtype], + mtype.replace(/message/i, ''), + saveToFile + ) + }, + enumerable: true, + configurable: true, }, - enumerable: true, - configurable: true - }, - reply: { - value(text, chatId, options) { - return this.conn?.reply(chatId ? chatId : this.chat, text, this, options) - } - }, - copy: { - value() { - const M = proto.WebMessageInfo - return smsg(this.conn, M.fromObject(M.toObject(this))) + reply: { + /** + * Reply to quoted message + * @param {String|Object} text + * @param {String|false} chatId + * @param {Object} options + */ + value(text, chatId, options) { + return self.conn?.reply(chatId ? chatId : this.chat, text, this.vM, options) + }, + enumerable: true, }, - enumerable: true - }, - forward: { - value(jid, force = false, options = {}) { - return this.conn?.sendMessage(jid, { - forward: this, force, ...options - }, { ...options }) + copy: { + /** + * Copy quoted message + */ + value() { + const M = proto.WebMessageInfo + return smsg(conn, M.fromObject(M.toObject(this.vM))) + }, + enumerable: true, }, - enumerable: true - }, - copyNForward: { - value(jid, forceForward = false, options = {}) { - return this.conn?.copyNForward(jid, this, forceForward, options) + forward: { + /** + * Forward quoted message + * @param {String} jid + * @param {Boolean} forceForward + */ + value(jid, force = false, options) { + return self.conn?.sendMessage( + jid, + { + forward: this.vM, + force, + ...options, + }, + { ...options } + ) + }, + enumerable: true, }, - enumerable: true - }, - cMod: { - value(jid, text = '', sender = this.sender, options = {}) { - return this.conn?.cMod(jid, this, text, sender, options) + copyNForward: { + /** + * Exact Forward quoted message + * @param {String} jid + * @param {Boolean|Number} forceForward + * @param {Object} options + */ + value(jid, forceForward = false, options) { + return self.conn?.copyNForward(jid, this.vM, forceForward, options) + }, + enumerable: true, }, - enumerable: true - }, - getQuotedObj: { - value() { - if (!this.quoted.id) return null - const q = proto.WebMessageInfo.fromObject(this.conn?.loadMessage(this.quoted.id) || this.quoted.vM) - return smsg(this.conn, q) + cMod: { + /** + * Modify quoted Message + * @param {String} jid + * @param {String} text + * @param {String} sender + * @param {Object} options + */ + value(jid, text = '', sender = this.sender, options = {}) { + return self.conn?.cMod(jid, this.vM, text, sender, options) + }, + enumerable: true, }, - enumerable: true - }, - getQuotedMessage: { - get() { - return this.getQuotedObj - } - }, - delete: { - value() { - return this.conn?.sendMessage(this.chat, { delete: this.key }) + delete: { + /** + * Delete quoted message + */ + value() { + return self.conn?.sendMessage(this.chat, { delete: this.vM.key }) + }, + enumerable: true, }, - enumerable: true - }, - //react - react: { - value(text) { - return this.conn?.sendMessage(this.chat, { - react: { - text, - key: this.key - } + //react + react: { + value(text) { + return self.conn?.sendMessage(this.chat, { + react: { + text, + key: this.vM.key, + }, }) + }, + enumerable: true, }, - enumerable: true - } - // - }) + // + } + ) + }, + enumerable: true, + }, + _text: { + value: null, + writable: true, + }, + text: { + get() { + const msg = this.msg + const text = + (typeof msg === 'string' ? msg : msg?.text) || msg?.caption || msg?.contentText || '' + return typeof this._text === 'string' + ? this._text + : '' || + (typeof text === 'string' + ? text + : text?.selectedDisplayText || + text?.hydratedTemplate?.hydratedContentText || + text) || + '' + }, + set(str) { + return (this._text = str) + }, + enumerable: true, + }, + mentionedJid: { + get() { + return ( + (this.msg?.contextInfo?.mentionedJid?.length && this.msg.contextInfo.mentionedJid) || [] + ) + }, + enumerable: true, + }, + name: { + get() { + return (!nullish(this.pushName) && this.pushName) || this.conn?.getName(this.sender) + }, + enumerable: true, + }, + download: { + value(saveToFile = false) { + const mtype = this.mediaType + return this.conn?.downloadM( + this.mediaMessage[mtype], + mtype.replace(/message/i, ''), + saveToFile + ) + }, + enumerable: true, + configurable: true, + }, + reply: { + value(text, chatId, options) { + return this.conn?.reply(chatId ? chatId : this.chat, text, this, options) + }, + }, + copy: { + value() { + const M = proto.WebMessageInfo + return smsg(this.conn, M.fromObject(M.toObject(this))) + }, + enumerable: true, + }, + forward: { + value(jid, force = false, options = {}) { + return this.conn?.sendMessage( + jid, + { + forward: this, + force, + ...options, + }, + { ...options } + ) + }, + enumerable: true, + }, + copyNForward: { + value(jid, forceForward = false, options = {}) { + return this.conn?.copyNForward(jid, this, forceForward, options) + }, + enumerable: true, + }, + cMod: { + value(jid, text = '', sender = this.sender, options = {}) { + return this.conn?.cMod(jid, this, text, sender, options) + }, + enumerable: true, + }, + getQuotedObj: { + value() { + if (!this.quoted.id) return null + const q = proto.WebMessageInfo.fromObject( + this.conn?.loadMessage(this.quoted.id) || this.quoted.vM + ) + return smsg(this.conn, q) + }, + enumerable: true, + }, + getQuotedMessage: { + get() { + return this.getQuotedObj + }, + }, + delete: { + value() { + return this.conn?.sendMessage(this.chat, { delete: this.key }) + }, + enumerable: true, + }, + //react + react: { + value(text) { + return this.conn?.sendMessage(this.chat, { + react: { + text, + key: this.key, + }, + }) + }, + enumerable: true, + }, + // + }) } export function logic(check, inp, out) { - if (inp.length !== out.length) throw new Error('Input and Output must have same length') - for (let i in inp) if (util.isDeepStrictEqual(check, inp[i])) return out[i] - return null + if (inp.length !== out.length) throw new Error('Input and Output must have same length') + for (let i in inp) if (util.isDeepStrictEqual(check, inp[i])) return out[i] + return null } export function protoType() { - Buffer.prototype.toArrayBuffer = function toArrayBufferV2() { - const ab = new ArrayBuffer(this.length); - const view = new Uint8Array(ab); - for (let i = 0; i < this.length; ++i) { - view[i] = this[i]; - } - return ab; - } - /** - * @returns {ArrayBuffer} - */ - Buffer.prototype.toArrayBufferV2 = function toArrayBuffer() { - return this.buffer.slice(this.byteOffset, this.byteOffset + this.byteLength) - } - /** - * @returns {Buffer} - */ - ArrayBuffer.prototype.toBuffer = function toBuffer() { - return Buffer.from(new Uint8Array(this)) + Buffer.prototype.toArrayBuffer = function toArrayBufferV2() { + const ab = new ArrayBuffer(this.length) + const view = new Uint8Array(ab) + for (let i = 0; i < this.length; ++i) { + view[i] = this[i] } - // /** - // * @returns {String} - // */ - // Buffer.prototype.toUtilFormat = ArrayBuffer.prototype.toUtilFormat = Object.prototype.toUtilFormat = Array.prototype.toUtilFormat = function toUtilFormat() { - // return util.format(this) - // } - Uint8Array.prototype.getFileType = ArrayBuffer.prototype.getFileType = Buffer.prototype.getFileType = async function getFileType() { + return ab + } + /** + * @returns {ArrayBuffer} + */ + Buffer.prototype.toArrayBufferV2 = function toArrayBuffer() { + return this.buffer.slice(this.byteOffset, this.byteOffset + this.byteLength) + } + /** + * @returns {Buffer} + */ + ArrayBuffer.prototype.toBuffer = function toBuffer() { + return Buffer.from(new Uint8Array(this)) + } + // /** + // * @returns {String} + // */ + // Buffer.prototype.toUtilFormat = ArrayBuffer.prototype.toUtilFormat = Object.prototype.toUtilFormat = Array.prototype.toUtilFormat = function toUtilFormat() { + // return util.format(this) + // } + Uint8Array.prototype.getFileType = + ArrayBuffer.prototype.getFileType = + Buffer.prototype.getFileType = + async function getFileType() { return await fileTypeFromBuffer(this) - } - /** - * @returns {Boolean} - */ - String.prototype.isNumber = Number.prototype.isNumber = isNumber - /** - * - * @returns {String} - */ - String.prototype.capitalize = function capitalize() { - return this.charAt(0).toUpperCase() + this.slice(1, this.length) - } - /** - * @returns {String} - */ - String.prototype.capitalizeV2 = function capitalizeV2() { - const str = this.split(' ') - return str.map(v => v.capitalize()).join(' ') - } - String.prototype.decodeJid = function decodeJid() { - if (/:\d+@/gi.test(this)) { - const decode = jidDecode(this) || {} - return (decode.user && decode.server && decode.user + '@' + decode.server || this).trim() - } else return this.trim() - } - /** - * number must be milliseconds - * @returns {string} - */ - Number.prototype.toTimeString = function toTimeString() { - // const milliseconds = this % 1000 - const seconds = Math.floor((this / 1000) % 60) - const minutes = Math.floor((this / (60 * 1000)) % 60) - const hours = Math.floor((this / (60 * 60 * 1000)) % 24) - const days = Math.floor((this / (24 * 60 * 60 * 1000))) - return ( - (days ? `${days} day(s) ` : '') + - (hours ? `${hours} hour(s) ` : '') + - (minutes ? `${minutes} minute(s) ` : '') + - (seconds ? `${seconds} second(s)` : '') - ).trim() - } - Number.prototype.getRandom = String.prototype.getRandom = Array.prototype.getRandom = getRandom + } + /** + * @returns {Boolean} + */ + String.prototype.isNumber = Number.prototype.isNumber = isNumber + /** + * + * @returns {String} + */ + String.prototype.capitalize = function capitalize() { + return this.charAt(0).toUpperCase() + this.slice(1, this.length) + } + /** + * @returns {String} + */ + String.prototype.capitalizeV2 = function capitalizeV2() { + const str = this.split(' ') + return str.map(v => v.capitalize()).join(' ') + } + String.prototype.decodeJid = function decodeJid() { + if (/:\d+@/gi.test(this)) { + const decode = jidDecode(this) || {} + return ((decode.user && decode.server && decode.user + '@' + decode.server) || this).trim() + } else return this.trim() + } + /** + * number must be milliseconds + * @returns {string} + */ + Number.prototype.toTimeString = function toTimeString() { + // const milliseconds = this % 1000 + const seconds = Math.floor((this / 1000) % 60) + const minutes = Math.floor((this / (60 * 1000)) % 60) + const hours = Math.floor((this / (60 * 60 * 1000)) % 24) + const days = Math.floor(this / (24 * 60 * 60 * 1000)) + return ( + (days ? `${days} day(s) ` : '') + + (hours ? `${hours} hour(s) ` : '') + + (minutes ? `${minutes} minute(s) ` : '') + + (seconds ? `${seconds} second(s)` : '') + ).trim() + } + Number.prototype.getRandom = String.prototype.getRandom = Array.prototype.getRandom = getRandom } - function isNumber() { - const int = parseInt(this) - return typeof int === 'number' && !isNaN(int) + const int = parseInt(this) + return typeof int === 'number' && !isNaN(int) } function getRandom() { - if (Array.isArray(this) || this instanceof String) return this[Math.floor(Math.random() * this.length)] - return Math.floor(Math.random() * this) + if (Array.isArray(this) || this instanceof String) + return this[Math.floor(Math.random() * this.length)] + return Math.floor(Math.random() * this) } - /** * ?? * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator * @returns {boolean} */ function nullish(args) { - return !(args !== null && args !== undefined) + return !(args !== null && args !== undefined) } - // TypeError: Cannot read properties of null (reading 'user') // at WebMessageInfo.get (file:///home/container/lib/simple.js:888:70) // at Object.value (file:///home/container/lib/simple.js:731:61) // at Object.handler (file:///home/container/handler.js?update=1646537086773:18:10) // at EventEmitter.emit (node:events:532:35) // at Object.all (file:///home/container/plugins/_templateResponse.js?update=1646538543307:79:13) -// at async Object.handler (file:///home/container/handler.js?update=1646537086773:346:21) +// at async Object.handler (file:///home/container/handler.js?update=1646537086773:346:21) \ No newline at end of file diff --git a/lib/uploadimage.js b/lib/uploadimage.js new file mode 100644 index 00000000..e69de29b diff --git a/lib/welcome.js b/lib/welcome.js index 993dfcb1..6babc0e9 100644 --- a/lib/welcome.js +++ b/lib/welcome.js @@ -278,7 +278,7 @@ function WelcomeLeave(Profile, Name, Text) { function getCurrentTime() { const options = { - timeZone: 'Asia/Kolkata', + timeZone: 'Africa/Lagos', year: 'numeric', month: 'long', day: 'numeric', diff --git a/package.json b/package.json deleted file mode 100644 index e5e5bea7..00000000 --- a/package.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "name": "gurubot", - "version": "2.0.0", - "description": "Advanced WhatsApp Bot", - "main": "index.js", - "type": "module", - "directories": { - "lib": "lib", - "src": "src", - "plugins": "plugins" - }, - "scripts": { - "start": "node index.js", - "test": "node test.js" - }, - "keywords": [ - "termux-whatsapp-bot", - "whatsapp-bot", - "whatsapp", - "js-whatsapp", - "whatsapp", - "guru-bot", - "GURU-bot-md", - "multi-device", - "MD", - "baileys-md" - ], - "homepage": "https://github.com/Guru322/GURU-BOT", - "author": { - "name": "GURU" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Guru322/GURU-BOT.git" - }, - "bugs": { - "url": "https://github.com/Guru322/GURU-BOT/issues" - }, - "license": "Apache License 2.0", - "dependencies": { - "@adiwajshing/keyed-db": "^0.2.4", - "@bochilteam/scraper": "^4.0.22-alpha.0", - "@google/generative-ai": "0.1.3", - "@shineiichijo/marika": "^2.0.6", - "@vitalets/google-translate-api": "^9.2.0", - "@whiskeysockets/baileys": "npm:@whiskeysockets/baileys", - "@xct007/frieren-scraper": "*", - "@xct007/tiktok-scraper": "*", - "acrcloud": "^1.4.0", - "api-dylux": "^1.6.9", - "aptoide-scraper": "^1.0.1", - "awesome-phonenumber": "^3.4.0", - "axios": "^1.4.0", - "mumaker": "latest", - "canvacord": "^5.4.8", - "cfonts": "^3.1.1", - "chalk": "^5.1.0", - "cheerio": "^1.0.0-rc.12", - "chess.js": "*", - "colors": "1.4.0", - "didyoumean": "^1.2.2", - "dotenv": "^16.1.4", - "emoji-api": "^2.0.1", - "express": "^4.18.1", - "fb-downloader-scrapper": "^1.0.1", - "fg-ig": "^0.0.2", - "file-type": "^18.0.0", - "fluent-ffmpeg": "^2.1.2", - "formdata-node": "^5.0.0", - "g-i-s": "^2.1.6", - "google-it": "^1.6.4", - "heroku-client": "^3.1.0", - "hispamemes": "^1.0.7", - "human-readable": "^0.2.1", - "hxz-api": "^1.0.1", - "imagemaker.js": "*", - "imgur": "2.3.0", - "instagram-url-direct": "^1.0.12", - "jimp": "^0.16.1", - "jsdom": "^20.0.1", - "knights-canvas": "^1.3.7-a", - "link-preview-js": "^3.0.0", - "lodash": "^4.17.21", - "lowdb": "^3.0.0", - "megajs": "^1.1.4", - "moment-timezone": "^0.5.37", - "mongoose": "^7.4.1", - "node-fetch": "^3.3.1", - "node-gtts": "^2.0.2", - "node-webpmux": "^3.1.3", - "openai": "^3.2.1", - "pdfkit": "^0.13.0", - "perf_hooks": "^0.0.1", - "pino": "^8.6.1", - "pino-pretty": "^9.1.1", - "qrcode": "^1.5.1", - "qrcode-terminal": "^0.12.0", - "readline": "^1.3.0", - "sagiri": "*", - "sharp": "^0.32.2", - "similarity": "^1.2.1", - "socket.io": "^4.5.2", - "syntax-error": "^1.4.0", - "terminal-image": "^2.0.0", - "truesearch": "^1.0.2", - "url-regex-safe": "^3.0.0", - "wa-sticker-formatter": "^4.3.2", - "xfarr-api": "^1.0.3", - "yargs": "^17.6.0", - "youtube-yts": "^2.0.0", - "youtubedl-core": "npm:@distube/ytdl-core" - }, - "overrides": { - "cache-manager": "5.2.2" - } - } diff --git a/plugins/1.js b/plugins/1.js new file mode 100644 index 00000000..e69de29b diff --git a/plugins/10.js b/plugins/10.js new file mode 100644 index 00000000..397d8559 --- /dev/null +++ b/plugins/10.js @@ -0,0 +1,15 @@ +let handler = async (m, { conn, text }) => { + if (!text) throw `Enter Text For Bot's New Bio` + try { + await conn.updateProfileStatus(text).catch(_ => _) + conn.reply(m.chat, 'Success Changing Bio Bot', m) +} catch { + throw 'Well, Error Sis...' + } +} +handler.help = ['setbotbio '] +handler.tags = ['owner'] +handler.command = /^setbiobot|setbotbio$/i +handler.owner = true + +export default handler \ No newline at end of file diff --git a/plugins/11.js b/plugins/11.js new file mode 100644 index 00000000..e69de29b diff --git a/plugins/2.js b/plugins/2.js new file mode 100644 index 00000000..94dee815 --- /dev/null +++ b/plugins/2.js @@ -0,0 +1,16 @@ +let handler = async (m, { conn, text, usedPrefix, command }) => { + if (!text) throw `if you find an error message, report it using this command\n\nexample:\n${usedPrefix + command} good afternoon owner, I found the following error ` + if (text.length < 10) throw `gblk abbreviation, minimum 10 characters!` + if (text.length > 1000) throw `do you report or vent?, maximum 1000 characters!` + let teks = `*${command.toUpperCase()}!*\n\nFrom : *@${m.sender.split`@`[0]}*\n\nOrder : ${text}\n` + conn.reply(global.nomorown + '@s.whatsapp.net', m.quoted ? teks + m.quoted.text : teks, null, { + contextInfo: { + mentionedJid: [m.sender] + } + }) + m.reply(`_Sent message owned by the bot, if ${command.toLowerCase()} just kidding will not be accepted._`) +} +handler.help = ['report', 'request'].map(v => v + ' ') +handler.tags = ['info'] +handler.command = /^(report|request)$/i +export default handler \ No newline at end of file diff --git a/plugins/3.js b/plugins/3.js new file mode 100644 index 00000000..7efa53fa --- /dev/null +++ b/plugins/3.js @@ -0,0 +1,21 @@ +import cp from 'child_process' +import { promisify } from 'util' +let exec = promisify(cp.exec).bind(cp) +var handler = async (m) => { + await conn.reply(m.chat, "Wait", m) + let o + try { + o = await exec('python3 speed.py --share') + } catch (e) { + o = e + } finally { + let { stdout, stderr } = o + if (stdout.trim()) m.reply(stdout) + if (stderr.trim()) m.reply(stderr) + } +} +handler.help = ['testspeed'] +handler.tags = ['info'] +handler.command = /^(speedtest)$/i + +export default handler \ No newline at end of file diff --git a/plugins/357.js b/plugins/357.js new file mode 100644 index 00000000..e69de29b diff --git a/plugins/358.js b/plugins/358.js new file mode 100644 index 00000000..6644f2fd --- /dev/null +++ b/plugins/358.js @@ -0,0 +1,647 @@ +import { createHash } from 'crypto' +import PhoneNumber from 'awesome-phonenumber' +import { canLevelUp, xpRange } from '../lib/levelling.js' +import fetch from 'node-fetch' +import fs from 'fs' +const { levelling } = '../lib/levelling.js' +import moment from 'moment-timezone' +import { promises } from 'fs' +import { join } from 'path' +const time = moment.tz('Asia/Kolkata').format('HH') +let wib = moment.tz('Asia/Kolkata').format('HH:mm:ss') +//import db from '../lib/database.js' + +let handler = async (m, { conn, usedPrefix, command}) => { + let d = new Date(new Date + 3600000) + let locale = 'en' + let week = d.toLocaleDateString(locale, { weekday: 'long' }) + let date = d.toLocaleDateString(locale, { day: 'numeric', month: 'long', year: 'numeric' }) + let _uptime = process.uptime() * 1000 + let uptime = clockString(_uptime) +let who = m.quoted ? m.quoted.sender : m.mentionedJid && m.mentionedJid[0] ? m.mentionedJid[0] : m.fromMe ? conn.user.jid : m.sender +if (!(who in global.db.data.users)) throw `โœณ๏ธ The user is not found in my database` +let pp = './STAR.jpg' +let user = global.db.data.users[who] +let { name, exp, diamond, lastclaim, registered, regTime, age, level, role, warn } = global.db.data.users[who] +let { min, xp, max } = xpRange(user.level, global.multiplier) +let username = conn.getName(who) +let math = max - xp +let prem = global.prems.includes(who.split`@`[0]) +let sn = createHash('md5').update(who).digest('hex') +let totaluser = Object.values(global.db.data.users).length +let rtotalreg = Object.values(global.db.data.users).filter(user => user.registered == true).length +let more = String.fromCharCode(8206) +let readMore = more.repeat(850) +let greeting = ucapan() +let quote = quotes[Math.floor(Math.random() * quotes.length)]; + +let taguser = '@' + m.sender.split("@s.whatsapp.net")[0] +let str = ` + +โ”โ”โ”๐Ÿค– _BOT STATUS:_๐Ÿค–โ”โ”โ”“ +โ”ƒ ๐Ÿฎ *Creator:* Excel Amadi +โ”ƒ ๐Ÿคก *Bot Name:* STAR-MD-V2 +โ”ƒ ๐Ÿ’ป *Host:* Linux Lair +โ”ƒ ๐Ÿ“ฃ *Prefix:* ${usedPrefix} +โ”ƒ ๐Ÿ•“ *Uptime:* ${uptime} +โ”ƒ ๐Ÿ’Œ *Database:* ${rtotalreg} of ${totaluser} +โ”ƒ ๐Ÿ“š *Total Users:* ${totaluser} +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– + +โ”โ”โ”โฐ _Today's Sauce!_ โฐโ”โ”“ +โ”ƒ ๐Ÿ“† *Today's Date:* ${date} +โ”ƒ โฒ๏ธ *Current Time:* ${wib} +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– + +โ”โ”*๐Ÿ‘คUSER*โ”โ”“ +โ”ƒ ๐Ÿ‘พ *User Tag:* ${taguser} +โ”ƒ ๐Ÿ˜‡ *Name:* ${name} +โ”ƒ ๐ŸŒŸ *Master Mind:* Excel +โ”ƒ ๐Ÿ’Ž *Diamonds:* -9999 +โ”ƒ ๐Ÿ† *Rank:* ${role} +โ”ƒ ๐ŸŽฎ *XP:* ${exp} +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– + + +โ”Œโ”€โ–ใ€Ž *_religion_* ใ€โ– +โ”ƒโ*bible [chapter_number|chapter_name] +โ*quran [surah_number|surah_name] +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_AI_* ใ€โ– +โ”ƒโ*bingimg2 +โ”ƒโ*chatgpt +โ”ƒโ*aisearch +โ”ƒโ*toanime +โ”ƒโ*gitagpt +โ”ƒโ*chat +โ”ƒโ*blackbox +โ”ƒโ*bingimg +โ”ƒโ*tocartoon +โ”ƒโ*dalle +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_image_* ใ€โ– +โ”ƒโ*blackpink +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_tools_* ใ€โ– +โ”ƒโ*gemini +โ”ƒโ*nowa +โ”ƒโ*qr +โ”ƒโ*qrcode +โ”ƒโ*weather ** +โ”ƒโ*shortlink +โ”ƒโ*bitly +โ”ƒโ*dehaze +โ”ƒโ*recolor +โ”ƒโ*hdr +โ”ƒโ*get +โ”ƒโ*length +โ”ƒโ*tinyurl +โ”ƒโ*shorten +โ”ƒโ*tempmail +โ”ƒโ*shazam +โ”ƒโ*cal +โ”ƒโ*.carbon +โ”ƒโ*define +โ”ƒโ*element +โ”ƒโ*itunes +โ”ƒโ*lyrics +โ”ƒโ*imdb +โ”ƒโ*course +โ”ƒโ*randomcourse +โ”ƒโ*readmore | +โ”ƒโ*readvo +โ”ƒโ*removebg +โ”ƒโ*ss +โ”ƒโ*ssf +โ”ƒโ*style +โ”ƒโ*subreddit +โ”ƒโ*telesticker โ“ +โ”ƒโ*tourl +โ”ƒโ*translate +โ”ƒโ*tts +โ”ƒโ*wa +โ”ƒโ*wikipedia +โ”ƒโ*true +โ”ƒโ*findmusic +โ”ƒโ*githubstalk +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_group_* ใ€โ– +โ”ƒโ*getbio <@tag/reply> โ“ +โ”ƒโ*getbio <@tag/reply> โ“ +โ”ƒโ*animequote +โ”ƒโ*Setdesc +โ”ƒโ*setname +โ”ƒโ*add +โ”ƒโ*delete +โ”ƒโ*delwarn @user +โ”ƒโ*demote (@tag) +โ”ƒโ*infogp +โ”ƒโ*hidetag +โ”ƒโ*invite <917xxx> +โ”ƒโ*kick @user +โ”ƒโ*link +โ”ƒโ*poll question|option|option +โ”ƒโ*profile +โ”ƒโ*promote +โ”ƒโ*resetlink +โ”ƒโ*setbye +โ”ƒโ*group *open/close* +โ”ƒโ*setwelcome +โ”ƒโ*simulate @user +โ”ƒโ*staff +โ”ƒโ*tagall +โ”ƒโ*totag +โ”ƒโ*warn @user +โ”ƒโ*warns +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_anime_* ใ€โ– +โ”ƒโ*anime +โ”ƒโ*akira +โ”ƒโ*akiyama +โ”ƒโ*anna +โ”ƒโ*asuna +โ”ƒโ*ayuzawa +โ”ƒโ*boruto +โ”ƒโ*chiho +โ”ƒโ*chitoge +โ”ƒโ*deidara +โ”ƒโ*erza +โ”ƒโ*elaina +โ”ƒโ*eba +โ”ƒโ*emilia +โ”ƒโ*hestia +โ”ƒโ*hinata +โ”ƒโ*inori +โ”ƒโ*isuzu +โ”ƒโ*itachi +โ”ƒโ*itori +โ”ƒโ*kaga +โ”ƒโ*kagura +โ”ƒโ*kaori +โ”ƒโ*keneki +โ”ƒโ*kotori +โ”ƒโ*kurumi +โ”ƒโ*madara +โ”ƒโ*mikasa +โ”ƒโ*miku +โ”ƒโ*minato +โ”ƒโ*naruto +โ”ƒโ*nezuko +โ”ƒโ*sagiri +โ”ƒโ*sasuke +โ”ƒโ*sakura +โ”ƒโ*akira +โ”ƒโ*amv โ“ +โ”ƒโ*waifu +โ”ƒโ*neko +โ”ƒโ*zerotwo +โ”ƒโ*loli +โ”ƒโ*jjanime โ“ +โ”ƒโ*pokedex +โ”ƒโ*trace +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_img_* ใ€โ– +โ”ƒโ*messi +โ”ƒโ*cristianoronaldo +โ”ƒโ*cr7 +โ”ƒโ*ppcouple +โ”ƒโ*ppcp +โ”ƒโ*pinterest +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_owner_* ใ€โ– +โ”ƒโ*leavegc +โ”ƒโ*out +โ”ƒโ*deletechat +โ”ƒโ*pin +โ”ƒโ*unpin +โ”ƒโ*deletechat +โ”ƒโ*addprem <@tag> +โ”ƒโ*addowner @user +โ”ƒโ*allow <@tag> +โ”ƒโ*HEROKU +โ”ƒโ*ban @user +โ”ƒโ*banchat +โ”ƒโ*tx +โ”ƒโ*broadcastgroup +โ”ƒโ*bcgc +โ”ƒโ*cleartmp +โ”ƒโ*delexpired +โ”ƒโ*delprem @user +โ”ƒโ*removeowner @user +โ”ƒโ*setppbotfull +โ”ƒโ*getplugin +โ”ƒโ*getfile +โ”ƒโ*join +โ”ƒโ*reset <54xxx> +โ”ƒโ*resetprefix +โ”ƒโ*restart +โ”ƒโ*.setprefix +โ”ƒโ*.setprefix [symbol] +โ”ƒโ*unban @user +โ”ƒโ*unbanchat +โ”ƒโ*update +โ”ƒโ*update now +โ”ƒโ*config +โ”ƒโ*listban +โ”ƒโ*deleteplugin +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_fun_* ใ€โ– +โ”ƒโ*afk +โ”ƒโ*tomp3 +โ”ƒโ*toav +โ”ƒโ*toxicity +โ”ƒโ*bot +โ”ƒโ*character @tag +โ”ƒโ*dare +โ”ƒโ*flirt +โ”ƒโ*gay @user +โ”ƒโ*joke +โ”ƒโ*pickupline +โ”ƒโ*question +โ”ƒโ*shayari +โ”ƒโ*ship +โ”ƒโ*yomamajoke +โ”ƒโ*truth +โ”ƒโ*waste @user +โ”ƒโ*perv +โ”ƒโ*handsome +โ”ƒโ*hot +โ”ƒโ*sexy +โ”ƒโ*ugly +โ”ƒโ*cute +โ”ƒโ*playboy +โ”ƒโ*playgirl +โ”ƒโ*beautiful +โ”ƒโ*lesbian +โ”ƒโ*whore +โ”ƒโ*motherfucker +โ”ƒโ*sucker +โ”ƒโ*horny +โ”ƒโ*foolish +โ”ƒโ*nibba +โ”ƒโ*nibbi +โ”ƒโ*bitch +โ”ƒโ*waifu +โ”ƒโ*crackhead +โ”ƒโ*rascal +โ”ƒโ*idiot +โ”ƒโ*girlyboy +โ”ƒโ*tomboy +โ”ƒโ*gigachad +โ”ƒโ*mf +โ”ƒโ*introvert +โ”ƒโ*extrovert +โ”ƒโ*sigma +โ”ƒโ*psycho +โ”ƒโ*brainless +โ”ƒโ*useless +โ”ƒโ*singer +โ”ƒโ*image +โ”ƒโ*meme +โ”ƒโ*quote +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_reaction_* ใ€โ– +โ”ƒโ*bully @tag +โ”ƒโ*cuddle @tag +โ”ƒโ*cry @tag +โ”ƒโ*hug @tag +โ”ƒโ*awoo @tag +โ”ƒโ*kiss @tag +โ”ƒโ*lick @tag +โ”ƒโ*pat @tag +โ”ƒโ*smug @tag +โ”ƒโ*bonk @tag +โ”ƒโ*yeet @tag +โ”ƒโ*blush @tag +โ”ƒโ*smile @tag +โ”ƒโ*wave @tag +โ”ƒโ*highfive @tag +โ”ƒโ*handhold @tag +โ”ƒโ*nom @tag +โ”ƒโ*bite @tag +โ”ƒโ*glomp @tag +โ”ƒโ*slap @tag +โ”ƒโ*kill @tag +โ”ƒโ*happy @tag +โ”ƒโ*wink @tag +โ”ƒโ*poke @tag +โ”ƒโ*dance @tag +โ”ƒโ*cringe @tag +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_utility_* ใ€โ– +โ”ƒโ*bmi +โ”ƒโ*crypto +โ”ƒโ*currency +โ”ƒโ*countdown +โ”ƒโ*prayertime +โ”ƒโ*convert +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_main_* ใ€โ– +โ”ƒโ*channel +โ”ƒโ*database +โ”ƒโ*user +โ”ƒโ*gpguru +โ”ƒโ*alive +โ”ƒโ*blocklist +โ”ƒโ*info +โ”ƒโ*owner +โ”ƒโ*totalfeature +โ”ƒโ*hack +โ”ƒโ*list +โ”ƒโ*botmenu +โ”ƒโ*ownermenu +โ”ƒโ*groupmenu +โ”ƒโ*dlmenu +โ”ƒโ*downloadermenu +โ”ƒโ*economymenu +โ”ƒโ*funmenu +โ”ƒโ*gamemenu +โ”ƒโ*stickermenu +โ”ƒโ*nsfwmenu +โ”ƒโ*logomenu +โ”ƒโ*toolmenu +โ”ƒโ*animemenu2 +โ”ƒโ*animemenu +โ”ƒโ*listprem +โ”ƒโ*logomenu2 +โ”ƒโ*ping +โ”ƒโ*ping2 +โ”ƒโ*runtime +โ”ƒโ*script +โ”ƒโ*server +โ”ƒโ*system +โ”ƒโ*blocklist +โ”ƒโ*setprivacy +โ”ƒโ*allmenu +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_cmd_* ใ€โ– +โ”ƒโ*delcmd +โ”ƒโ*listcmd +โ”ƒโ*setcmd +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_information_* ใ€โ– +โ”ƒโ*cninfo +โ”ƒโ*fact +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_finance_* ใ€โ– +โ”ƒโ*crypto +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_cryptocurrency_* ใ€โ– +โ”ƒโ*crypto +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_time_* ใ€โ– +โ”ƒโ*countdown +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_downloader_* ใ€โ– +โ”ƒโ*facebook +โ”ƒโ*gdrive ๐Ÿ…Ÿ +โ”ƒโ*gitclone +โ”ƒโ*igstalk +โ”ƒโ*instagram +โ”ƒโ*mediafire +โ”ƒโ*mega +โ”ƒโ*modapk +โ”ƒโ*play +โ”ƒโ*play2 +โ”ƒโ*playvid +โ”ƒโ*play3 โ“ +โ”ƒโ*tiktok +โ”ƒโ*tiktokstalk +โ”ƒโ*twitter +โ”ƒโ*ytmp3 +โ”ƒโ*ytsearch +โ”ƒโ*ytmp4 +โ”ƒโ*wallpaper +โ”ƒโ*play โ“ +โ”ƒโ*play โ“ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_premium_* ใ€โ– +โ”ƒโ*gdrive ๐Ÿ…Ÿ +โ”ƒโ*mediafire +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_economy_* ใ€โ– +โ”ƒโ*addgold <@user> +โ”ƒโ*addxp <@user> +โ”ƒโ*bank +โ”ƒโ*buych +โ”ƒโ*cock-fight +โ”ƒโ*buy +โ”ƒโ*buyall +โ”ƒโ*daily +โ”ƒโ*deposit +โ”ƒโ*gamble +โ”ƒโ*give credit [amount] [@tag] +โ”ƒโ*levelup +โ”ƒโ*rank +โ”ƒโ*rob +โ”ƒโ*roulette +โ”ƒโ*wallet +โ”ƒโ*withdraw +โ”ƒโ*work +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_core_* ใ€โ– +โ”ƒโ*leaderboard +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_game_* ใ€โ– +โ”ƒโ*slot +โ”ƒโ*chess [from to] +โ”ƒโ*chess delete +โ”ƒโ*chess join +โ”ƒโ*chess start +โ”ƒโ*delttt +โ”ƒโ*guessflag +โ”ƒโ*Maths +โ”ƒโ*ppt +โ”ƒโ*tictactoe +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ– +โ”Œโ”€โ–ใ€Ž *_config_* ใ€โ– +โ”ƒโ*enable