satanic-release 0.0.0-stage → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/RUN NODE 20 - 21 +0 -0
  2. package/assets/fishing/LICENSE.txt +1 -0
  3. package/assets/fishing/SOURCES.md +8 -0
  4. package/assets/fishing/angler.svg +16 -0
  5. package/assets/fishing/background.svg +1 -0
  6. package/assets/fishing/bait.svg +1 -0
  7. package/assets/fishing/birds.svg +1 -0
  8. package/assets/fishing/boat.svg +1 -0
  9. package/assets/fishing/bobber.svg +1 -0
  10. package/assets/fishing/cloud.svg +1 -0
  11. package/assets/fishing/coin.svg +1 -0
  12. package/assets/fishing/coral.svg +1 -0
  13. package/assets/fishing/crate.svg +1 -0
  14. package/assets/fishing/fish-bass.svg +1 -0
  15. package/assets/fishing/fish-catfish.svg +1 -0
  16. package/assets/fishing/fish-koi.svg +1 -0
  17. package/assets/fishing/fish-perch.svg +1 -0
  18. package/assets/fishing/fish-trout.svg +1 -0
  19. package/assets/fishing/hook.svg +1 -0
  20. package/assets/fishing/lilypad.svg +1 -0
  21. package/assets/fishing/manifest.json +48 -0
  22. package/assets/fishing/net.svg +1 -0
  23. package/assets/fishing/reeds.svg +1 -0
  24. package/assets/fishing/rod.svg +1 -0
  25. package/assets/fishing/spark.svg +1 -0
  26. package/assets/fishing/splash.svg +5 -0
  27. package/assets/fishing/watergrass.svg +1 -0
  28. package/assets/fonts/qiro-nulis.ttf +0 -0
  29. package/assets/rpg/CC0_SOURCES.txt +23 -0
  30. package/assets/rpg/cc0/SOURCES.md +18 -0
  31. package/assets/rpg/items/antidote.svg +1 -0
  32. package/assets/rpg/items/armor.svg +1 -0
  33. package/assets/rpg/items/axe.svg +1 -0
  34. package/assets/rpg/items/bag.svg +1 -0
  35. package/assets/rpg/items/bear.svg +1 -0
  36. package/assets/rpg/items/boar.svg +1 -0
  37. package/assets/rpg/items/book.svg +1 -0
  38. package/assets/rpg/items/bow.svg +1 -0
  39. package/assets/rpg/items/car.svg +1 -0
  40. package/assets/rpg/items/cherry.svg +1 -0
  41. package/assets/rpg/items/chest.svg +1 -0
  42. package/assets/rpg/items/coal.svg +1 -0
  43. package/assets/rpg/items/coin.svg +1 -0
  44. package/assets/rpg/items/compass.svg +1 -0
  45. package/assets/rpg/items/crate.svg +1 -0
  46. package/assets/rpg/items/deer.svg +1 -0
  47. package/assets/rpg/items/demon.svg +1 -0
  48. package/assets/rpg/items/diamond.svg +5 -0
  49. package/assets/rpg/items/diamondchest.svg +1 -0
  50. package/assets/rpg/items/dice.svg +1 -0
  51. package/assets/rpg/items/dice1.svg +1 -0
  52. package/assets/rpg/items/dice2.svg +1 -0
  53. package/assets/rpg/items/dice3.svg +1 -0
  54. package/assets/rpg/items/dice4.svg +1 -0
  55. package/assets/rpg/items/dice5.svg +1 -0
  56. package/assets/rpg/items/dice6.svg +1 -0
  57. package/assets/rpg/items/dragon.svg +1 -0
  58. package/assets/rpg/items/dumbbell.svg +1 -0
  59. package/assets/rpg/items/egg.svg +1 -0
  60. package/assets/rpg/items/elixir.svg +1 -0
  61. package/assets/rpg/items/emerald.svg +1 -0
  62. package/assets/rpg/items/fish.svg +1 -0
  63. package/assets/rpg/items/fishingrod.svg +1 -0
  64. package/assets/rpg/items/flower.svg +1 -0
  65. package/assets/rpg/items/food.svg +1 -0
  66. package/assets/rpg/items/fox.svg +1 -0
  67. package/assets/rpg/items/frost.svg +1 -0
  68. package/assets/rpg/items/gold.svg +1 -0
  69. package/assets/rpg/items/goldchest.svg +1 -0
  70. package/assets/rpg/items/grape.svg +1 -0
  71. package/assets/rpg/items/hammer.svg +1 -0
  72. package/assets/rpg/items/helmet.svg +1 -0
  73. package/assets/rpg/items/herb.svg +1 -0
  74. package/assets/rpg/items/house.svg +1 -0
  75. package/assets/rpg/items/iron.svg +1 -0
  76. package/assets/rpg/items/key.svg +1 -0
  77. package/assets/rpg/items/kraken.svg +1 -0
  78. package/assets/rpg/items/kunai.svg +1 -0
  79. package/assets/rpg/items/leather.svg +1 -0
  80. package/assets/rpg/items/lemon.svg +1 -0
  81. package/assets/rpg/items/lion.svg +1 -0
  82. package/assets/rpg/items/map.svg +1 -0
  83. package/assets/rpg/items/meat.svg +1 -0
  84. package/assets/rpg/items/mpotion.svg +1 -0
  85. package/assets/rpg/items/octopus.svg +1 -0
  86. package/assets/rpg/items/orange.svg +1 -0
  87. package/assets/rpg/items/ore.svg +1 -0
  88. package/assets/rpg/items/parking.svg +1 -0
  89. package/assets/rpg/items/pearl.svg +1 -0
  90. package/assets/rpg/items/pet.svg +1 -0
  91. package/assets/rpg/items/pickaxe.svg +1 -0
  92. package/assets/rpg/items/potion.svg +1 -0
  93. package/assets/rpg/items/prawn.svg +1 -0
  94. package/assets/rpg/items/rabbit.svg +1 -0
  95. package/assets/rpg/items/ramen.svg +1 -0
  96. package/assets/rpg/items/rice.svg +1 -0
  97. package/assets/rpg/items/rock.svg +1 -0
  98. package/assets/rpg/items/scroll.svg +1 -0
  99. package/assets/rpg/items/seven.svg +1 -0
  100. package/assets/rpg/items/shark.svg +1 -0
  101. package/assets/rpg/items/shield.svg +1 -0
  102. package/assets/rpg/items/shuriken.svg +1 -0
  103. package/assets/rpg/items/slot.svg +1 -0
  104. package/assets/rpg/items/staminapotion.svg +1 -0
  105. package/assets/rpg/items/sword.svg +1 -0
  106. package/assets/rpg/items/tent.svg +1 -0
  107. package/assets/rpg/items/thunder.svg +1 -0
  108. package/assets/rpg/items/titan.svg +1 -0
  109. package/assets/rpg/items/trash.svg +1 -0
  110. package/assets/rpg/items/undead.svg +1 -0
  111. package/assets/rpg/items/whale.svg +1 -0
  112. package/assets/rpg/items/wheat.svg +1 -0
  113. package/assets/rpg/items/wood.svg +1 -0
  114. package/assets/rpg/ui/SOURCES.md +12 -0
  115. package/assets/rpg/ui/compass.svg +1 -0
  116. package/assets/rpg/ui/diamond.svg +1 -0
  117. package/assets/rpg/ui/soft-frame.svg +6 -0
  118. package/buypanel.js +37 -0
  119. package/cara ambil apikey.js +26 -0
  120. package/data/assets/Caveat-Bold.ttf +0 -0
  121. package/data/assets/FontsFree-Net-SFProDisplay-Bold.ttf +0 -0
  122. package/data/assets/FontsFree-Net-SFProDisplay-Regular.ttf +0 -0
  123. package/data/assets/Indie-Flower.ttf +0 -0
  124. package/database/absen.json +1 -0
  125. package/database/absen_status.json +1 -0
  126. package/database/admin.json +1 -0
  127. package/database/adminvip.json +1 -0
  128. package/database/afk.json +1 -0
  129. package/database/antiaudio.json +1 -0
  130. package/database/antibadword.json +1 -0
  131. package/database/antibot-settings.json +1 -0
  132. package/database/antibot.json +1 -0
  133. package/database/antidelete.json +3 -0
  134. package/database/antiig.json +1 -0
  135. package/database/antiimage.json +1 -0
  136. package/database/antilink.json +1 -0
  137. package/database/antilinkall.json +1 -0
  138. package/database/antilinkkick.json +1 -0
  139. package/database/antirvo.json +1 -0
  140. package/database/antispam-counter.json +1 -0
  141. package/database/antispam-groups.json +1 -0
  142. package/database/antispam-warn.json +1 -0
  143. package/database/antisticker.json +1 -0
  144. package/database/antiswgc.json +1 -0
  145. package/database/antitagsw.json +1 -0
  146. package/database/antitoxic.json +1 -0
  147. package/database/antitt.json +1 -0
  148. package/database/antivideo.json +1 -0
  149. package/database/antiyt.json +1 -0
  150. package/database/autojoingc.json +1 -0
  151. package/database/autosholat.json +3 -0
  152. package/database/bad.json +73 -0
  153. package/database/badword.json +7 -0
  154. package/database/banchat.json +1 -0
  155. package/database/bannedfitur.json +1 -0
  156. package/database/banuser.json +1 -0
  157. package/database/blacklist.json +1 -0
  158. package/database/blacklistgroup.json +1 -0
  159. package/database/broadcast.json +3 -0
  160. package/database/chatsNotif.json +1 -0
  161. package/database/config.json +1 -0
  162. package/database/database.json +1 -0
  163. package/database/expiredpanel.json +1 -0
  164. package/database/expiredpanel2.json +1 -0
  165. package/database/fiturmember.json +1 -0
  166. package/database/groupadd.json +1 -0
  167. package/database/groups.json +6 -0
  168. package/database/gruplist.json +5 -0
  169. package/database/idgrup.json +1 -0
  170. package/database/jpmgroup.json +1 -0
  171. package/database/kata-kata.json +28309 -0
  172. package/database/left.json +1 -0
  173. package/database/list-message.json +51 -0
  174. package/database/maintenance.json +4 -0
  175. package/database/mutegc.json +1 -0
  176. package/database/nilai.json +3 -0
  177. package/database/onlyadmin.json +1 -0
  178. package/database/onlygc.json +6 -0
  179. package/database/onlyprivate.json +3 -0
  180. package/database/openaigc.json +3 -0
  181. package/database/owner.json +1 -0
  182. package/database/panelexpired2.json +1 -0
  183. package/database/payment.json +1 -0
  184. package/database/pending.json +1 -0
  185. package/database/pendingSewa.json +1 -0
  186. package/database/prefix.json +4 -0
  187. package/database/premium.json +1 -0
  188. package/database/qris.json +3 -0
  189. package/database/registered.json +2 -0
  190. package/database/schedule.json +1 -0
  191. package/database/set_done.json +1 -0
  192. package/database/set_left.json +1 -0
  193. package/database/set_proses.json +1 -0
  194. package/database/set_welcome.json +1 -0
  195. package/database/setting.json +1 -0
  196. package/database/sewa.json +1 -0
  197. package/database/sewabot.json +3 -0
  198. package/database/transaksi.json +1 -0
  199. package/database/uservip.json +1 -0
  200. package/database/warning.json +2 -0
  201. package/database/welcome.json +1 -0
  202. package/helper.js +461 -0
  203. package/index.js +19 -0
  204. package/lib/AGENCYB.TTF +0 -0
  205. package/lib/CallDur.ttf +0 -0
  206. package/lib/CallName.ttf +0 -0
  207. package/lib/DanaFont.otf +0 -0
  208. package/lib/DevFont.ttf +0 -0
  209. package/lib/antidelete.js +196 -0
  210. package/lib/arialnarrow.ttf +0 -0
  211. package/lib/cekban.js +14 -0
  212. package/lib/color.js +19 -0
  213. package/lib/connection.js +12 -0
  214. package/lib/converter.js +85 -0
  215. package/lib/exif.js +171 -0
  216. package/lib/function.js +407 -0
  217. package/lib/gemmy.js +433 -0
  218. package/lib/groupManager.js +75 -0
  219. package/lib/helper-bails.js +19 -0
  220. package/lib/myfunction.js +384 -0
  221. package/lib/respon-list.js +95 -0
  222. package/lib/sambungkata.js +117 -0
  223. package/lib/savetube.js +1 -0
  224. package/lib/setwelcome.js +66 -0
  225. package/lib/sewa.js +109 -0
  226. package/lib/sewabot.js +40 -0
  227. package/lib/store.js +94 -0
  228. package/lib/surprisedeal.js +120 -0
  229. package/lib/thumb.jpg +0 -0
  230. package/lib/tictactoe.js +94 -0
  231. package/lib/tiktoksearch.js +83 -0
  232. package/lib/uploader.js +324 -0
  233. package/lib/videothumb.mp4 +0 -0
  234. package/lib/welcome.js +129 -0
  235. package/license.md +17 -0
  236. package/no developer.js +2 -0
  237. package/package.json +61 -5
  238. package/plugins/crm.js +309 -0
  239. package/plugins/douyinsearch.js +166 -0
  240. package/plugins/runcrm.js +124 -0
  241. package/plugins/spotifylirik.js +130 -0
  242. package/satanic.js +37922 -0
  243. package/settings.js +173 -0
  244. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,51 @@
1
+ [
2
+ {
3
+ "id": "120363407122703972@g.us",
4
+ "key": "p",
5
+ "response": "puki",
6
+ "isImage": false,
7
+ "image_url": "-"
8
+ },
9
+ {
10
+ "id": "120363410997590630@g.us",
11
+ "key": "puki",
12
+ "response": "memek",
13
+ "isImage": false,
14
+ "image_url": "-"
15
+ },
16
+ {
17
+ "id": "120363427226061348@g.us",
18
+ "key": "puki",
19
+ "response": "tempe",
20
+ "isImage": false,
21
+ "image_url": "-"
22
+ },
23
+ {
24
+ "id": "120363409380129225@g.us",
25
+ "key": "tempe",
26
+ "response": " tape",
27
+ "isImage": false,
28
+ "image_url": "-"
29
+ },
30
+ {
31
+ "id": "120363410997590630@g.us",
32
+ "key": "tempee",
33
+ "response": "mmk",
34
+ "isImage": false,
35
+ "image_url": "-"
36
+ },
37
+ {
38
+ "id": "120363407122703972@g.us",
39
+ "key": "tempee",
40
+ "response": "asu",
41
+ "isImage": false,
42
+ "image_url": "-"
43
+ },
44
+ {
45
+ "id": "120363407122703972@g.us",
46
+ "key": "puki",
47
+ "response": "asu",
48
+ "isImage": false,
49
+ "image_url": "-"
50
+ }
51
+ ]
@@ -0,0 +1,4 @@
1
+ {
2
+ "active": false,
3
+ "reason": ""
4
+ }
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,3 @@
1
+ {
2
+ "_lastSendDate": "2026-09-18"
3
+ }
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,6 @@
1
+ {
2
+ "status": false,
3
+ "groups": [
4
+ "120363430208357736@g.us"
5
+ ]
6
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "status": true
3
+ }
@@ -0,0 +1,3 @@
1
+ [
2
+ "120363428031975181@g.us"
3
+ ]
@@ -0,0 +1 @@
1
+ ["6282173070713@s.whatsapp.net"]
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,4 @@
1
+ {
2
+ "mode": "single",
3
+ "symbol": "."
4
+ }
@@ -0,0 +1 @@
1
+ ["6282173070713@s.whatsapp.net", "6282179131605@s.whatsapp.net", "6283168758640@s.whatsapp.net"]
@@ -0,0 +1,3 @@
1
+ {
2
+ "url": "https://u.pone.rs/jgsurxon.jpg"
3
+ }
@@ -0,0 +1,2 @@
1
+
2
+ []
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,3 @@
1
+ {
2
+ "groups": {}
3
+ }
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ ["6285165503130@s.whatsapp.net","6283132240763@s.whatsapp.net","6283132240763@s.whatsapp.net"]
@@ -0,0 +1,2 @@
1
+ {}
2
+ []
@@ -0,0 +1 @@
1
+ []
package/helper.js ADDED
@@ -0,0 +1,461 @@
1
+ const { prepareWAMessageMedia, delay, generateWAMessageFromContent, generateWAMessage, getAggregateVotesInPollMessage, downloadContentFromMessage, generateForwardMessageContent, jidDecode } = require("@whiskeysockets/baileys");
2
+ const FileType = require('file-type');
3
+ const fs = require('fs');
4
+ const crypto = require("crypto");
5
+ const { getBuffer } = require('./lib/myfunction');
6
+ const { writeExifImg, writeExifVid, addExif, videoToWebp } = require('./lib/exif');
7
+ module.exports = function(satanic, store) {
8
+ satanic.decodeJid = (jid) => {
9
+ if (!jid) return jid;
10
+ if (/:\d+@/gi.test(jid)) {
11
+ let decode = jidDecode(jid) || {};
12
+ return decode.user && decode.server && decode.user + '@' + decode.server || jid;
13
+ } else return jid;
14
+ };
15
+ satanic.getName = async (jid) => {
16
+ try {
17
+ const id = satanic.decodeJid(jid);
18
+ if (id.endsWith("@g.us")) {
19
+ try {
20
+ const meta = await satanic.groupMetadata(id);
21
+ return meta.subject || meta.name || id.split('@')[0];
22
+ } catch (e) { return id.split('@')[0]; }
23
+ }
24
+ let name = null;
25
+ try {
26
+ if (global.store?.contacts?.[id]) {
27
+ const contact = global.store.contacts[id];
28
+ name = contact.name || contact.pushname || contact.notify;
29
+ }
30
+ } catch (e) {}
31
+ if (!name && satanic.contacts?.[id]) {
32
+ const contact = satanic.contacts[id];
33
+ name = contact.name || contact.pushname || contact.notify;
34
+ }
35
+ if (!name) {
36
+ try {
37
+ const messages = await satanic.loadMessages(id, 5);
38
+ if (messages && messages.length > 0) {
39
+ for (let msg of messages) {
40
+ if (msg.pushName) { name = msg.pushName; break; }
41
+ if (msg.notifyName) { name = msg.notifyName; break; }
42
+ if (msg.verifiedName) { name = msg.verifiedName; break; }
43
+ }
44
+ }
45
+ } catch (e) {}
46
+ }
47
+ if (!name && satanic.user) {
48
+ const botId = satanic.decodeJid(satanic.user.id);
49
+ if (id === botId) name = satanic.user.name || satanic.user.pushname;
50
+ }
51
+ if (!name) name = id.split('@')[0];
52
+ return name;
53
+ } catch (e) {
54
+ console.error('Error in getName:', e);
55
+ return jid.split('@')[0];
56
+ }
57
+ };
58
+ satanic.setWelcome = '```Welcome To @subject```\n─────────────────\n```Name : @user```\n```Date : @date```\n```jangan lupa intro ya kak, ketik .intro untuk mengambil card intro```\n─────────────────\n@desc';
59
+ satanic.setLeft = '```Goodbye ``` 👋\n─────────────────\n```Name : @user```\n```Date : @date```\n\nLeaving From @subject';
60
+ satanic.setPromote = '```🎉 PROMOTE```\n─────────────────\n```Admin : @admin```\n```User : @user```\n```Date : @date```\n\n@admin telah mempromosikan @user jadi admin di @subject 🎊\n─────────────────\n@desc';
61
+ satanic.setDemote = '```📉 DEMOTE```\n─────────────────\n```Admin : @admin```\n```User : @user```\n```Date : @date```\n\n@admin telah mencabut admin @user di @subject\n─────────────────\n@desc';
62
+ function tanggal(date) {
63
+ return date.toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })
64
+ }
65
+ satanic.ev.on('group-participants.update', async (anu) => {
66
+ console.log(anu);
67
+ let chat = global.db.chats[anu.id] || {};
68
+ try {
69
+ let metadata = await satanic.groupMetadata(anu.id);
70
+ let participants = anu.participants;
71
+ let author = anu.author || (anu.participants && anu.participants[0]);
72
+ for (let num of participants) {
73
+ let mediaUrl, isVideo = false;
74
+ if (anu.action == 'add') {
75
+ if (chat.blacklist && global.db.blacklistUser && global.db.blacklistUser[anu.id] && global.db.blacklistUser[anu.id][num]) {
76
+ let data = global.db.blacklistUser[anu.id][num];
77
+ data.count = (data.count || 0) + 1;
78
+ let maxKick = chat.blacklistLimit || 3;
79
+ if (chat.blacklistWarn && data.count < maxKick) {
80
+ let teksWarn = `⚠️ *BLACKLIST WARNING* ⚠️\n\n@${num.split('@')[0]} terdeteksi keluar-masuk grup.\nKamu sudah keluar ${data.count}x dari grup ini.\nBatas maksimal: ${maxKick}x\n\nJika melebihi batas, kamu akan di-kick otomatis!`;
81
+ await satanic.sendMessage(anu.id, { text: teksWarn, mentions: [num] });
82
+ } else if (data.count >= maxKick) {
83
+ let teksKick = `*Kamu sudah pernah bergabung di dalam group dan berada di dalam data blacklist\n\n@${num.split('@')[0]} sudah keluar ${data.count}x dari grup.\nMelebihi batas maksimal (${maxKick}x), kamu di-kick!`;
84
+ await satanic.sendMessage(anu.id, { text: teksKick, mentions: [num] });
85
+ await satanic.groupParticipantsUpdate(anu.id, [num], 'remove');
86
+ delete global.db.blacklistUser[anu.id][num];
87
+ continue;
88
+ } else {
89
+ let teksKick = `🚫 *BLACKLIST KICK* 🚫\n\n@${num.split('@')[0]} terdeteksi keluar-masuk grup, langsung di-kick!`;
90
+ await satanic.sendMessage(anu.id, { text: teksKick, mentions: [num] });
91
+ await satanic.groupParticipantsUpdate(anu.id, [num], 'remove');
92
+ delete global.db.blacklistUser[anu.id][num];
93
+ continue;
94
+ }
95
+ }
96
+ if (!chat.welcome) continue;
97
+ let setting = chat.welcomeSetting || {};
98
+ if (setting.type === 'video') {
99
+ mediaUrl = setting.url || global.welcomeVideo || 'https://c.termai.cc/i191/zZjmX.png';
100
+ isVideo = true;
101
+ } else {
102
+ mediaUrl = setting.url || global.welcomeImage || 'https://c.termai.cc/i191/zZjmX.png';
103
+ isVideo = false;
104
+ }
105
+ let teks = (chat.setWelcome || satanic.setWelcome || 'Welcome @user')
106
+ .replace(/@subject/g, `${metadata.subject}`)
107
+ .replace(/@admin/g, author ? `@${author.split('@')[0]}` : 'Admin')
108
+ .replace(/@user/g, `@${num.split('@')[0]}`)
109
+ .replace(/\u2068/g, '')
110
+ .replace(/\u2069/g, '')
111
+ .replace(/@date/g, `${tanggal(new Date())}`)
112
+ .replace(/@desc/g, `${metadata.desc ? metadata.desc.toString() : 'No description'}`);
113
+ if (isVideo) {
114
+ satanic.sendMessage(anu.id, { video: { url: mediaUrl }, caption: teks, mentions: [num, author].filter(Boolean) });
115
+ } else {
116
+ satanic.sendMessage(anu.id, { image: { url: mediaUrl }, caption: teks, mentions: [num, author].filter(Boolean) });
117
+ }
118
+ } else if (anu.action == 'remove') {
119
+ if (chat.blacklist) {
120
+ let isSelfLeave = !anu.author || anu.author === num;
121
+ if (isSelfLeave) {
122
+ if (!global.db.blacklistUser) global.db.blacklistUser = {};
123
+ if (!global.db.blacklistUser[anu.id]) global.db.blacklistUser[anu.id] = {};
124
+ if (!global.db.blacklistUser[anu.id][num]) {
125
+ global.db.blacklistUser[anu.id][num] = { count: 1, firstLeave: Date.now() };
126
+ } else {
127
+ global.db.blacklistUser[anu.id][num].count = (global.db.blacklistUser[anu.id][num].count || 0) + 1;
128
+ }
129
+ }
130
+ }
131
+ if (!chat.left) continue;
132
+ let setting = chat.leftSetting || {};
133
+ if (setting.type === 'video') {
134
+ mediaUrl = setting.url || global.leftVideo || 'https://c.termai.cc/i191/zZjmX.png';
135
+ isVideo = true;
136
+ } else {
137
+ mediaUrl = setting.url || global.leftImage || 'https://c.termai.cc/i191/zZjmX.png';
138
+ isVideo = false;
139
+ }
140
+ let teks = (chat.setLeft || satanic.setLeft || 'Goodbye @user')
141
+ .replace(/@subject/g, `${metadata.subject}`)
142
+ .replace(/@admin/g, author ? `@${author.split('@')[0]}` : 'Admin')
143
+ .replace(/@user/g, `@${num.split('@')[0]}`)
144
+ .replace(/@date/g, `${tanggal(new Date())}`)
145
+ .replace(/@desc/g, `${metadata.desc ? metadata.desc.toString() : 'No description'}`);
146
+ if (isVideo) {
147
+ satanic.sendMessage(anu.id, { video: { url: mediaUrl }, caption: teks, mentions: [num, author].filter(Boolean) });
148
+ } else {
149
+ satanic.sendMessage(anu.id, { image: { url: mediaUrl }, caption: teks, mentions: [num, author].filter(Boolean) });
150
+ }
151
+ } else if (anu.action == 'promote') {
152
+ if (!chat.notifpromote) continue;
153
+ let teks = (chat.setPromote || satanic.setPromote || 'Promote @user')
154
+ .replace(/@subject/g, `${metadata.subject}`)
155
+ .replace(/@admin/g, author ? `@${author.split('@')[0]}` : 'Admin')
156
+ .replace(/@user/g, `@${num.split('@')[0]}`)
157
+ .replace(/@date/g, `${tanggal(new Date())}`)
158
+ .replace(/@desc/g, `${metadata.desc ? metadata.desc.toString() : 'No description'}`);
159
+ satanic.sendMessage(anu.id, { text: teks, mentions: [num, author].filter(Boolean) });
160
+ } else if (anu.action == 'demote') {
161
+ if (!chat.notifdemote) continue;
162
+ let teks = (chat.setDemote || satanic.setDemote || 'Demote @user')
163
+ .replace(/@subject/g, `${metadata.subject}`)
164
+ .replace(/@admin/g, author ? `@${author.split('@')[0]}` : 'Admin')
165
+ .replace(/@user/g, `@${num.split('@')[0]}`)
166
+ .replace(/@date/g, `${tanggal(new Date())}`)
167
+ .replace(/@desc/g, `${metadata.desc ? metadata.desc.toString() : 'No description'}`);
168
+ satanic.sendMessage(anu.id, { text: teks, mentions: [num, author].filter(Boolean) });
169
+ }
170
+ }
171
+ } catch (err) {
172
+ console.log(err);
173
+ }
174
+ });
175
+ satanic.sendFile = async (jid, path, filename = '', caption = '', quoted = null, options = {}) => {
176
+ try {
177
+ let buffer;
178
+ if (Buffer.isBuffer(path)) buffer = path;
179
+ else if (typeof path === 'string') {
180
+ if (/^data:.*?\/.*?;base64,/i.test(path)) buffer = Buffer.from(path.split`,`[1], 'base64');
181
+ else if (/^https?:\/\//.test(path)) buffer = await getBuffer(path);
182
+ else if (fs.existsSync(path)) buffer = fs.readFileSync(path);
183
+ else throw new Error('Invalid file path');
184
+ } else throw new Error('Invalid input');
185
+ let fileType = await FileType.fromBuffer(buffer);
186
+ let mime = fileType ? fileType.mime : 'application/octet-stream';
187
+ let extension = fileType ? fileType.ext : 'bin';
188
+ if (!filename) {
189
+ if (typeof path === 'string' && !/^(data:|https?:\/\/)/.test(path)) filename = path.split('/').pop().split('\\').pop();
190
+ else filename = `file_${Date.now()}.${extension}`;
191
+ }
192
+ let messageType, messageContent = {};
193
+ if (mime.startsWith('image/')) {
194
+ messageType = 'imageMessage';
195
+ messageContent = { image: buffer, caption: caption || '', fileName: filename, mimetype: mime, ...options };
196
+ } else if (mime.startsWith('video/')) {
197
+ messageType = 'videoMessage';
198
+ messageContent = { video: buffer, caption: caption || '', fileName: filename, mimetype: mime, ...options };
199
+ } else if (mime.startsWith('audio/')) {
200
+ messageType = 'audioMessage';
201
+ messageContent = { audio: buffer, mimetype: mime, fileName: filename, ...options };
202
+ } else {
203
+ messageType = 'documentMessage';
204
+ messageContent = { document: buffer, fileName: filename, mimetype: mime, caption: caption || '', ...options };
205
+ }
206
+ const media = await prepareWAMessageMedia(messageContent, {
207
+ upload: satanic.waUploadToServer,
208
+ mediaType: messageType.replace('Message', '').toLowerCase()
209
+ });
210
+ return await satanic.sendMessage(jid, media, { quoted });
211
+ } catch (err) {
212
+ console.error('Error in sendFile:', err);
213
+ throw err;
214
+ }
215
+ };
216
+ satanic.getFile = async (message, returnBuffer = true, savePath = '') => {
217
+ try {
218
+ if (!message || (!message.msg && !message.message)) throw new Error('Invalid message');
219
+ const m = message.msg || message.message;
220
+ let mime, messageType, filename;
221
+ if (m.imageMessage) { mime = m.imageMessage.mimetype; messageType = 'image'; filename = m.imageMessage.fileName || `image_${Date.now()}`; }
222
+ else if (m.videoMessage) { mime = m.videoMessage.mimetype; messageType = 'video'; filename = m.videoMessage.fileName || `video_${Date.now()}`; }
223
+ else if (m.audioMessage) { mime = m.audioMessage.mimetype; messageType = 'audio'; filename = m.audioMessage.fileName || `audio_${Date.now()}`; }
224
+ else if (m.documentMessage) { mime = m.documentMessage.mimetype; messageType = 'document'; filename = m.documentMessage.fileName || `document_${Date.now()}`; }
225
+ else if (m.stickerMessage) { mime = m.stickerMessage.mimetype; messageType = 'sticker'; filename = `sticker_${Date.now()}`; }
226
+ else throw new Error('Unsupported message type');
227
+ const stream = await downloadContentFromMessage(m, messageType);
228
+ let buffer = Buffer.from([]);
229
+ for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
230
+ const fileType = await FileType.fromBuffer(buffer);
231
+ let extension = 'bin';
232
+ if (fileType) extension = fileType.ext;
233
+ else if (mime) extension = mime.split('/')[1]?.split(';')[0] || 'bin';
234
+ if (filename && !filename.includes('.')) filename = `${filename}.${extension}`;
235
+ if (savePath) {
236
+ const fullPath = savePath.endsWith('/') ? savePath + filename : savePath;
237
+ fs.writeFileSync(fullPath, buffer);
238
+ console.log(`File saved to: ${fullPath}`);
239
+ }
240
+ if (returnBuffer) return { buffer, filename, mime, extension, size: buffer.length };
241
+ return { path: savePath ? (savePath.endsWith('/') ? savePath + filename : savePath) : null, filename, mime, extension, size: buffer.length };
242
+ } catch (err) {
243
+ console.error('Error in getFile:', err);
244
+ throw err;
245
+ }
246
+ };
247
+ satanic.copyNForward = async (jid, message, forceForward = false, options = {}) => {
248
+ let vtype
249
+ if (options.readViewOnce) {
250
+ message.message = message.message && message.message.ephemeralMessage && message.message.ephemeralMessage.message ? message.message.ephemeralMessage.message : (message.message || undefined)
251
+ vtype = Object.keys(message.message.viewOnceMessage.message)[0]
252
+ delete(message.message && message.message.ignore ? message.message.ignore : (message.message || undefined))
253
+ delete message.message.viewOnceMessage.message[vtype].viewOnce
254
+ message.message = { ...message.message.viewOnceMessage.message }
255
+ }
256
+ let mtype = Object.keys(message.message)[0]
257
+ let content = await generateForwardMessageContent(message, forceForward)
258
+ let ctype = Object.keys(content)[0]
259
+ let context = {}
260
+ if (mtype != "conversation") context = message.message[mtype].contextInfo
261
+ content[ctype].contextInfo = { ...context, ...content[ctype].contextInfo }
262
+ const waMessage = await generateWAMessageFromContent(jid, content, options ? {
263
+ ...content[ctype], ...options,
264
+ ...(options.contextInfo ? { contextInfo: { ...content[ctype].contextInfo, ...options.contextInfo } } : {})
265
+ } : {})
266
+ await satanic.relayMessage(jid, waMessage.message, { messageId: waMessage.key.id })
267
+ return waMessage
268
+ }
269
+ satanic.sendText = async (jid, text, quoted = '', options) => {
270
+ satanic.sendMessage(jid, { text: text, ...options }, { quoted });
271
+ }
272
+ satanic.sendTextWithMentions = async (jid, text, quoted, options = {}) => satanic.sendMessage(jid, {
273
+ text: text,
274
+ mentions: [...text.matchAll(/@(\d{0,16})/g)].map(v => v[1] + '@s.whatsapp.net'),
275
+ ...options
276
+ }, { quoted })
277
+ satanic.downloadMediaMessage = async (message) => {
278
+ let mime = (message.msg || message).mimetype || ''
279
+ let messageType = message.mtype ? message.mtype.replace(/Message/gi, '') : mime.split('/')[0]
280
+ const stream = await downloadContentFromMessage(message, messageType)
281
+ let buffer = Buffer.from([])
282
+ for await(const chunk of stream) buffer = Buffer.concat([buffer, chunk])
283
+ return buffer
284
+ }
285
+ satanic.sendImageAsSticker = async (jid, path, quoted, options = {}) => {
286
+ let buff = Buffer.isBuffer(path) ? path :
287
+ /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`, `[1], 'base64') :
288
+ /^https?:\/\//.test(path) ? await (await getBuffer(path)) :
289
+ fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0);
290
+ let buffer;
291
+ if (options && (options.packname || options.author)) buffer = await writeExifImg(buff, options);
292
+ else buffer = await addExif(buff);
293
+ await satanic.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted });
294
+ return buffer;
295
+ };
296
+ satanic.sendVideoAsSticker = async (jid, path, quoted, options = {}) => {
297
+ let buff = Buffer.isBuffer(path) ? path :
298
+ /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`, `[1], 'base64') :
299
+ /^https?:\/\//.test(path) ? await (await getBuffer(path)) :
300
+ fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0);
301
+ let buffer;
302
+ if (options && (options.packname || options.author)) buffer = await writeExifVid(buff, options);
303
+ else buffer = await videoToWebp(buff);
304
+ await satanic.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted });
305
+ return buffer;
306
+ };
307
+ satanic.downloadAndSaveMediaMessage = async (message, filename, attachExtension = true) => {
308
+ let quoted = message.msg ? message.msg : message;
309
+ let mime = (message.msg || message).mimetype || "";
310
+ let messageType = message.mtype ? message.mtype.replace(/Message/gi, "") : mime.split("/")[0];
311
+ const stream = await downloadContentFromMessage(quoted, messageType);
312
+ let buffer = Buffer.from([]);
313
+ for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
314
+ let type = await FileType.fromBuffer(buffer);
315
+ let trueFileName = attachExtension ? filename + "." + type.ext : filename;
316
+ await fs.writeFileSync(trueFileName, buffer);
317
+ return trueFileName;
318
+ };
319
+ satanic.albumMessage = async (jid, array, quoted) => {
320
+ const album = generateWAMessageFromContent(jid, {
321
+ messageContextInfo: { messageSecret: crypto.randomBytes(32) },
322
+ albumMessage: {
323
+ expectedImageCount: array.filter((a) => a.hasOwnProperty("image")).length,
324
+ expectedVideoCount: array.filter((a) => a.hasOwnProperty("video")).length,
325
+ },
326
+ }, { userJid: satanic.user.jid, quoted, upload: satanic.waUploadToServer });
327
+ await satanic.relayMessage(jid, album.message, { messageId: album.key.id });
328
+ for (let content of array) {
329
+ const img = await generateWAMessage(jid, content, { upload: satanic.waUploadToServer });
330
+ img.message.messageContextInfo = {
331
+ messageSecret: crypto.randomBytes(32),
332
+ messageAssociation: { associationType: 1, parentMessageKey: album.key },
333
+ participant: "0@s.whatsapp.net",
334
+ remoteJid: "status@broadcast",
335
+ forwardingScore: 99999,
336
+ isForwarded: true,
337
+ mentionedJid: [jid],
338
+ starred: true,
339
+ labels: ["Y", "Important"],
340
+ isHighlighted: true,
341
+ businessMessageForwardInfo: { businessOwnerJid: jid },
342
+ dataSharingContext: { showMmDisclosure: true },
343
+ };
344
+ img.message.forwardedNewsletterMessageInfo = {
345
+ newsletterJid: "0@newsletter",
346
+ serverMessageId: 1,
347
+ newsletterName: `WhatsApp`,
348
+ contentType: 1,
349
+ timestamp: new Date().toISOString(),
350
+ senderName: "✧ Dittsans",
351
+ content: "Text Message",
352
+ priority: "high",
353
+ status: "sent",
354
+ };
355
+ img.message.disappearingMode = {
356
+ initiator: 3, trigger: 4, initiatorDeviceJid: jid,
357
+ initiatedByExternalService: true, initiatedByUserDevice: true,
358
+ initiatedBySystem: true, initiatedByServer: true,
359
+ initiatedByAdmin: true, initiatedByUser: true,
360
+ initiatedByApp: true, initiatedByBot: true, initiatedByMe: true,
361
+ };
362
+ await satanic.relayMessage(jid, img.message, {
363
+ messageId: img.key.id,
364
+ quoted: {
365
+ key: { remoteJid: album.key.remoteJid, id: album.key.id, fromMe: true, participant: satanic.user.jid },
366
+ message: album.message,
367
+ },
368
+ });
369
+ }
370
+ return album;
371
+ };
372
+ satanic.sendStatusMention = async (content, jids = []) => {
373
+ let users;
374
+ for (let id of jids) {
375
+ let userId = await satanic.groupMetadata(id);
376
+ users = await userId.participants.map(u => satanic.decodeJid(u.id));
377
+ }
378
+ let message = await satanic.sendMessage("status@broadcast", content, {
379
+ backgroundColor: "#000000",
380
+ font: Math.floor(Math.random() * 9),
381
+ statusJidList: users,
382
+ additionalNodes: [{
383
+ tag: "meta", attrs: {},
384
+ content: [{
385
+ tag: "mentioned_users", attrs: {},
386
+ content: jids.map((jid) => ({ tag: "to", attrs: { jid }, content: undefined })),
387
+ }],
388
+ }],
389
+ });
390
+ jids.forEach(id => {
391
+ satanic.relayMessage(id, {
392
+ groupStatusMentionMessage: {
393
+ message: { protocolMessage: { key: message.key, type: 25 } },
394
+ },
395
+ }, {
396
+ userJid: satanic.user.jid,
397
+ additionalNodes: [{ tag: "meta", attrs: { is_status_mention: "true" }, content: undefined }],
398
+ });
399
+ delay(2500);
400
+ });
401
+ return message;
402
+ };
403
+ satanic.autoReadSW = async (m) => {
404
+ if (!global.autoreadsw) return
405
+ try {
406
+ if (m.key && m.key.remoteJid === 'status@broadcast') {
407
+ await satanic.readMessages([m.key])
408
+ console.log('📱 Auto read status')
409
+ }
410
+ } catch (e) {}
411
+ }
412
+ satanic.autoReactSW = async (m) => {
413
+ if (!global.autoreactsw) return
414
+ try {
415
+ if (m.key && m.key.remoteJid === 'status@broadcast') {
416
+ const reaction = { react: { text: global.autoreactemoji, key: m.key } }
417
+ await satanic.sendMessage(m.key.remoteJid, reaction)
418
+ console.log(`😀 Auto reacted to status with ${global.autoreactemoji}`)
419
+ }
420
+ } catch (e) {
421
+ console.error('Auto react error:', e)
422
+ }
423
+ }
424
+ async function getMessage(key) { return null; }
425
+ satanic.ev.on('messages.update', async chatUpdate => {
426
+ for (const { key, update } of chatUpdate) {
427
+ if (update.pollUpdates && !key.fromMe) {
428
+ const pollCreation = await getMessage(key)
429
+ if (pollCreation) {
430
+ const pollUpdate = await getAggregateVotesInPollMessage({
431
+ message: pollCreation,
432
+ pollUpdates: update.pollUpdates,
433
+ })
434
+ var toCmd = pollUpdate.filter(v => v.voters.length !== 0)[0]?.name
435
+ if (toCmd == undefined) return
436
+ var prefCmd = prefix + toCmd
437
+ satanic.appenTextMessage(prefCmd, chatUpdate)
438
+ }
439
+ }
440
+ }
441
+ })
442
+ if (!satanic.chats) satanic.chats = {};
443
+ satanic.ev.on('groups.update', async function groupUpdatePushToDb(groupsUpdates) {
444
+ if (!Array.isArray(groupsUpdates)) return;
445
+ for (const update of groupsUpdates) {
446
+ try {
447
+ if (!update || !update.id) continue;
448
+ const id = satanic.decodeJid(update.id);
449
+ if (!id || !id.endsWith('@g.us')) continue;
450
+ if (!satanic.chats[id]) satanic.chats[id] = { id: id };
451
+ let chats = satanic.chats[id];
452
+ chats.isChats = true;
453
+ const metadata = await satanic.groupMetadata(id).catch(() => null);
454
+ if (metadata) {
455
+ chats.subject = metadata.subject;
456
+ chats.metadata = metadata;
457
+ }
458
+ } catch (error) {}
459
+ }
460
+ })
461
+ }