| const axios = require('axios') |
| const { jidDecode, delay, generateWAMessageFromContent, proto } = require('baileys') |
| const id3 = require('browser-id3-writer') |
| const { fromBuffer } = require('file-type') |
| const path = require('path') |
| const FormData = require('form-data') |
| const { spawn } = require('child_process') |
| const { default: fetch } = require('node-fetch') |
| let { JSDOM } = require('jsdom') |
| const cheerio = require('cheerio') |
| const { commands } = require('./plugins') |
| const config = require('../config') |
| const jsQR = require('jsqr') |
| const fs = require('fs') |
| const jimp = require('jimp') |
| const { loadMessage } = require('./database/StoreDb') |
| const { tmpdir } = require('os') |
| const { exec } = require('child_process') |
| const streamBuffers = require('stream-buffers') |
| const { URLSearchParams } = require('url') |
| async function editAudio(message, effect = 'bass', options = '') { |
| if (!message.quoted) { |
| return await message.send('*Reply to audio*') |
| } |
|
|
| let mediaType = message.quoted.mtype || message.mtype |
| if (!/audio/.test(mediaType)) { |
| return await message.send('*_Reply Audio_*', {}, '', options) |
| } |
| let filterCommand = '-af equalizer=f=54:width_type=o:width=2:g=20' |
|
|
| switch (effect.toLowerCase()) { |
| case 'bass': |
| filterCommand = '-af equalizer=f=54:width_type=o:width=2:g=20' |
| break |
| case 'blown': |
| filterCommand = '-af acrusher=.1:1:64:0:log' |
| break |
| case 'deep': |
| filterCommand = '-af atempo=4/4,asetrate=44500*2/3' |
| break |
| case 'earrape': |
| filterCommand = '-af volume=12' |
| break |
| case 'fast': |
| filterCommand = '-filter:a "atempo=1.63,asetrate=44100"' |
| break |
| case 'fat': |
| filterCommand = '-filter:a "atempo=1.6,asetrate=22100"' |
| break |
| case 'nightcore': |
| filterCommand = '-filter:a atempo=1.06,asetrate=44100*1.25' |
| break |
| case 'reverse': |
| filterCommand = '-filter_complex "areverse"' |
| break |
| case 'robot': |
| filterCommand = "-filter_complex \"afftfilt=real='hypot(re,im)*sin(0)':imag='hypot(re,im)*cos(0)':win_size=512:overlap=0.75\"" |
| break |
| case 'slow': |
| filterCommand = '-filter:a "atempo=0.7,asetrate=44100"' |
| break |
| case 'smooth': |
| filterCommand = '-filter:v "minterpolate=\'mi_mode=mci:mc_mode=aobmc:vsbmc=1:fps=120\'"' |
| break |
| case 'tupai': |
| filterCommand = '-filter:a "atempo=0.5,asetrate=65100"' |
| break |
| default: |
| break |
| } |
|
|
| let audioFilePath = await message.client.downloadAndSaveMediaMessage(message.quoted) |
| let outputFilePath = 'temp/' + (message.sender.slice(6) + effect) + '.mp3' |
|
|
| exec(`ffmpeg -i ${audioFilePath} ${filterCommand} ${outputFilePath}`, async (error, stdout, stderr) => { |
| try { |
| fs.unlinkSync(audioFilePath) |
| } catch {} |
|
|
| if (error) { |
| return message.error(error) |
| } else { |
| let editedAudio = fs.readFileSync(outputFilePath) |
| try { |
| fs.unlinkSync(outputFilePath) |
| } catch {} |
|
|
| let contextInfo = { |
| ...(await message.bot.contextInfo('Sir ' + message.senderName + ' 🤍', '⇆ㅤ ||◁ㅤ❚❚ㅤ▷||ㅤ ⇆')), |
| } |
|
|
| return message.bot.sendMessage( |
| message.chat, |
| { |
| audio: editedAudio, |
| mimetype: 'audio/mpeg', |
| ptt: /ptt|voice/.test(message.test || '') ? true : false, |
| contextInfo: contextInfo, |
| }, |
| { |
| quoted: message, |
| messageId: message.bot.messageId(), |
| } |
| ) |
| } |
| }) |
| } |
| const captureScreenshot = (url, device = 'desktop') => { |
| return new Promise((resolve, reject) => { |
| const screenshotApiUrl = 'https://www.screenshotmachine.com/capture.php' |
| const requestData = { |
| url, |
| device, |
| cacheLimit: 0, |
| } |
|
|
| axios |
| .post(screenshotApiUrl, new URLSearchParams(requestData), { |
| headers: { |
| 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', |
| }, |
| }) |
| .then((response) => { |
| const cookies = response.headers['set-cookie'] |
| if (response.data.status === 'success') { |
| axios |
| .get(`https://www.screenshotmachine.com/${response.data.link}`, { |
| headers: { cookie: cookies.join('') }, |
| responseType: 'arraybuffer', |
| }) |
| .then(({ data }) => { |
| resolve({ status: 200, result: data }) |
| }) |
| } else { |
| reject({ |
| status: 404, |
| statusText: 'Link Error', |
| message: response.data, |
| }) |
| } |
| }) |
| .catch(reject) |
| }) |
| } |
| async function m3u82Mp4(m3u8Url) { |
| return new Promise((resolve, reject) => { |
| const writableStreamBuffer = new streamBuffers.WritableStreamBuffer({ |
| initialSize: 100 * 1024, |
| incrementAmount: 10 * 1024, |
| }) |
| const tempOutputFile = 'output.mp4' |
| const command = `"${ffmpegPath}" -i "${m3u8Url}" -c copy "${tempOutputFile}"` |
| const ffmpegProcess = exec(command, (error, stdout, stderr) => { |
| if (error) { |
| console.error(`Error occurred: ${error.message}`) |
| return reject(error) |
| } |
|
|
| |
| fs.readFile(tempOutputFile, (err, data) => { |
| if (err) { |
| return reject(err) |
| } |
| writableStreamBuffer.write(data) |
| writableStreamBuffer.end() |
| fs.unlinkSync(tempOutputFile) |
| resolve(writableStreamBuffer.getContents()) |
| }) |
| }) |
| ffmpegProcess.stderr.on('data', (data) => { |
| const progressLine = data.toString() |
| const timeMatch = progressLine.match(/time=(\d{2}:\d{2}:\d{2}\.\d{2})/) |
| if (timeMatch) { |
| const elapsedTime = timeMatch[1] |
| console.log(`Conversion progress: ${elapsedTime}`) |
| } |
| }) |
| }) |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| async function buffToFile(buffer, filename) { |
| if (!filename) filename = Date.now() |
| let { ext } = await fromBuffer(buffer) |
| let filePath = path.join(tmpdir(), `${filename}.${ext}`) |
| await fs.promises.writeFile(filePath, buffer) |
| return filePath |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| const removeBg = async (imageBuffer) => { |
| const formData = new FormData() |
| const inputPath = await buffToFile(imageBuffer) |
| formData.append('size', 'auto') |
| formData.append('image_file', fs.createReadStream(inputPath), path.basename(inputPath)) |
| try { |
| const response = await axios({ |
| method: 'post', |
| url: 'https://api.remove.bg/v1.0/removebg', |
| data: formData, |
| responseType: 'arraybuffer', |
| headers: { |
| ...formData.getHeaders(), |
| 'X-Api-Key': config.REMOVEBG, |
| }, |
| encoding: null, |
| }) |
|
|
| if (response.status !== 200) { |
| console.error('Error:', response.status, response.statusText) |
| return null |
| } |
|
|
| return response.data |
| } catch (error) { |
| console.error('Request failed:', error) |
| return null |
| } |
| } |
|
|
| async function validatAndSaveDeleted(client, msg) { |
| if (msg.type === 'protocolMessage') { |
| if (msg.message.protocolMessage.type === 'REVOKE') { |
| await client.sendMessage(msg.key.remoteJid, { text: 'Message Deleted' }) |
| let jid = config.DELETED_LOG_CHAT |
| let message = await loadMessage(msg.message.protocolMessage.key.id) |
| const m = generateWAMessageFromContent(jid, message.message, { |
| userJid: client.user.id, |
| }) |
| await client.relayMessage(jid, m.message, { |
| messageId: m.key.id, |
| }) |
| return m |
| } |
| } |
| } |
| async function textToImg(text) { |
| try { |
| const words = text.split(' ') |
| const lines = [] |
| let line = '' |
| words.forEach((word) => { |
| if (line.length + word.length < 30) { |
| line += word + ' ' |
| } else { |
| lines.push(line) |
| line = word + ' ' |
| } |
| }) |
| lines.push(line) |
| text = lines.join('\n') |
| const font = await jimp.loadFont(jimp.FONT_SANS_64_WHITE) |
| const textWidth = jimp.measureText(font, text.substring(0, 35)) |
| const textHeight = jimp.measureTextHeight(font, text) |
| const canvasWidth = textWidth |
| const canvasHeight = textHeight + -(textHeight * 0.8) |
| const image = new jimp(canvasWidth, canvasHeight, 0x075e54ff) |
| const x = 5 |
| const y = 5 |
| image.print(font, x, y, text, textWidth, textHeight) |
| image.shadow({ blur: 3, x: 6, y: 5, color: '#000000' }) |
| const buffer = await image.getBufferAsync(jimp.MIME_PNG) |
| return buffer |
| } catch (err) { |
| throw new Error(err) |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| async function readQr(imageBuffer) { |
| try { |
| const image = await jimp.read(imageBuffer) |
| const { data, width, height } = image.bitmap |
| const code = jsQR(data, width, height) |
| if (code) { |
| return code.data |
| } |
| } catch (err) { |
| throw new Error(`Error reading QR code: ${err.message}`) |
| } |
| return null |
| } |
|
|
| function createInteractiveMessage(data, options = {}) { |
| const { jid, button, header, footer, body } = data |
| let buttons = [] |
| for (let i = 0; i < button.length; i++) { |
| let btn = button[i] |
| let Button = {} |
| Button.buttonParamsJson = JSON.stringify(btn.params) |
| switch (btn.type) { |
| case 'copy': |
| Button.name = 'cta_copy' |
| break |
| case 'url': |
| Button.name = 'cta_url' |
| break |
| case 'location': |
| Button.name = 'send_location' |
| break |
| case 'address': |
| Button.name = 'address_message' |
| break |
| case 'call': |
| Button.name = 'cta_call' |
| break |
| case 'reply': |
| Button.name = 'quick_reply' |
| break |
| case 'list': |
| Button.name = 'single_select' |
| break |
| default: |
| Button.name = 'quick_reply' |
| break |
| } |
| buttons.push(Button) |
| } |
| const mess = { |
| viewOnceMessage: { |
| message: { |
| messageContextInfo: { |
| deviceListMetadata: {}, |
| deviceListMetadataVersion: 2, |
| }, |
| interactiveMessage: proto.Message.InteractiveMessage.create({ |
| body: proto.Message.InteractiveMessage.Body.create({ ...body }), |
| footer: proto.Message.InteractiveMessage.Footer.create({ ...footer }), |
| header: proto.Message.InteractiveMessage.Header.create({ ...header }), |
| nativeFlowMessage: proto.Message.InteractiveMessage.NativeFlowMessage.create({ |
| buttons: buttons, |
| }), |
| }), |
| }, |
| }, |
| } |
| let optional = generateWAMessageFromContent(jid, mess, options) |
| return optional |
| } |
|
|
| function ffmpeg(buffer, args = [], ext = '', ext2 = '') { |
| return new Promise(async (resolve, reject) => { |
| try { |
| let tmp = path.join(tmpdir() + '/' + new Date() + '.' + ext) |
| let out = tmp + '.' + ext2 |
| await fs.promises.writeFile(tmp, buffer) |
| const ffmpegProcess = spawn('ffmpeg', ['-y', '-i', tmp, ...args, out]) |
| .on('error', reject) |
| .on('close', async (code) => { |
| try { |
| await fs.promises.unlink(tmp) |
| if (code !== 0) { |
| reject(new Error(`FFmpeg process exited with code ${code}`)) |
| return |
| } |
| const processedData = await fs.promises.readFile(out) |
| await fs.promises.unlink(out) |
| resolve(processedData) |
| } catch (e) { |
| reject(e) |
| } |
| }) |
| } catch (e) { |
| reject(e) |
| } |
| }) |
| } |
|
|
| |
| |
| |
| |
| |
| function toAudio(buffer, ext) { |
| return ffmpeg(buffer, ['-vn', '-ac', '2', '-b:a', '128k', '-ar', '44100', '-f', 'mp3'], ext, 'mp3') |
| } |
|
|
| |
| |
| |
| |
| |
| function toPTT(buffer, ext) { |
| return ffmpeg(buffer, ['-vn', '-c:a', 'libopus', '-b:a', '128k', '-vbr', 'on', '-compression_level', '10'], ext, 'opus') |
| } |
|
|
| |
| |
| |
| |
| |
| function toVideo(buffer, ext) { |
| return ffmpeg(buffer, ['-c:v', 'libx264', '-c:a', 'aac', '-ab', '128k', '-ar', '44100', '-crf', '32', '-preset', 'slow'], ext, 'mp4') |
| } |
|
|
| async function getBuffer(url, options = {}) { |
| try { |
| const res = await axios({ |
| method: 'get', |
| url, |
| headers: { |
| DNT: 1, |
| 'Upgrade-Insecure-Request': 1, |
| }, |
| ...options, |
| responseType: 'arraybuffer', |
| }) |
| return res.data |
| } catch (error) { |
| throw new Error(`Error: ${error.message}`) |
| } |
| } |
| const decodeJid = (jid) => { |
| if (!jid) return jid |
| if (/:\d+@/gi.test(jid)) { |
| const decode = jidDecode(jid) || {} |
| return decode.user && decode.server ? `${decode.user}@${decode.server}` : jid |
| } else { |
| return jid |
| } |
| } |
| async function FiletypeFromUrl(url) { |
| const buffer = await getBuffer(url) |
| const out = await fromBuffer(buffer) |
| let type |
| if (out) { |
| type = out.mime.split('/')[0] |
| } |
| return { type, buffer } |
| } |
| function extractUrlFromMessage(message) { |
| const urlRegex = /(https?:\/\/[^\s]+)/gi |
| const match = urlRegex.exec(message) |
| return match ? match[0] : null |
| } |
|
|
| const removeCommand = async (name) => { |
| return new Promise((resolve, reject) => { |
| commands.map(async (command, index) => { |
| if (command.pattern !== undefined && command.pattern.test(new RegExp(`${config.HANDLERS}( ?${name})`, 'is'))) { |
| commands.splice(index, 1) |
| return resolve(true) |
| } |
| }) |
| resolve(false) |
| }) |
| } |
| async function igdl(igurl) { |
| const data = `q=${encodeURIComponent(igurl)}&t=media&lang=en` |
| const config = { |
| method: 'post', |
| maxBodyLength: Infinity, |
| url: 'https://v3.saveig.app/api/ajaxSearch', |
| headers: { |
| Accept: '/', |
| 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', |
| }, |
| data: data, |
| } |
|
|
| const response = await axios.request(config) |
| const html = response.data.data |
|
|
| const $ = cheerio.load(html, { decodeEntities: true }) |
| const downloadItems = $('.download-items') |
| const result = [] |
|
|
| downloadItems.each((index, element) => { |
| let url = $(element).find('.download-items__btn > a').attr('href') |
| if (url.includes('file')) { |
| let newUrl = new URL(url) |
| let encodedUrl = newUrl.searchParams.get('file') |
| let decodedUrl = Buffer.from(encodedUrl, 'base64').toString('utf-8') |
| result.push(decodedUrl) |
| } else { |
| result.push(url) |
| } |
| }) |
|
|
| return result |
| } |
|
|
| function aiImage(prompt) { |
| return new Promise((resolve, reject) => { |
| axios |
| .post( |
| 'https://socket.xasena.me/generate-image', |
| { |
| prompt: prompt, |
| }, |
| { |
| headers: { |
| Accept: '*/*', |
| 'User-Agent': 'Thunder Client (https://www.thunderclient.com)', |
| 'Content-Type': 'application/json', |
| }, |
| responseType: 'arraybuffer', |
| } |
| ) |
| .then(function (response) { |
| if (response.status === 400) { |
| resolve(response.data) |
| } else { |
| resolve(Buffer.from(response.data, 'binary')) |
| } |
| }) |
| .catch(function (error) { |
| reject(error) |
| }) |
| }) |
| } |
|
|
| async function getJson(url, options) { |
| try { |
| options ? options : {} |
| const res = await axios({ |
| method: 'GET', |
| url: url, |
| headers: { |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', |
| }, |
| ...options, |
| }) |
| return res.data |
| } catch (err) { |
| return err |
| } |
| } |
|
|
| const API_KEY = 'e6d0cd0023b7ee562a97be33d3c5f524' |
| const BASE_URL = 'https://api.musixmatch.com/ws/1.1/' |
|
|
| async function getLyrics(song, artist) { |
| try { |
| const searchUrl = `${BASE_URL}track.search?q_track=${encodeURIComponent(song)}&q_artist=${encodeURIComponent(artist)}&f_has_lyrics=1&apikey=${API_KEY}` |
| const searchData = await getJson(searchUrl) |
| const trackList = searchData.message.body.track_list |
|
|
| let trackId = null |
| if (trackList.length > 0) { |
| trackId = trackList[0].track.track_id |
| } else { |
| const allTracksUrl = `${BASE_URL}track.search?q_artist=${encodeURIComponent(artist)}&apikey=${API_KEY}` |
| const allTracksData = await getJson(allTracksUrl) |
| const allTracks = allTracksData.message.body.track_list |
| if (allTracks.length > 0) { |
| trackId = allTracks[0].track.track_id |
| } |
| } |
|
|
| if (trackId) { |
| const lyricsUrl = `${BASE_URL}track.lyrics.get?track_id=${trackId}&apikey=${API_KEY}` |
| const lyricsData = await getJson(lyricsUrl) |
| let lyrics = lyricsData.message.body.lyrics.lyrics_body |
| const disclaimer = '********************** This Lyrics is NOT for Commercial use **********************' |
| lyrics = lyrics.replace(disclaimer, '') |
| return { |
| artist_name: artist, |
| song, |
| lyrics: lyrics.replace(/\(\d+\)$/, ''), |
| } |
| } |
| } catch (error) { |
| console.error('Error:', error) |
| throw error |
| } |
|
|
| return null |
| } |
|
|
| module.exports = { |
| parseTimeToSeconds: (timeString) => { |
| const [minutes, seconds] = timeString.split(':').map(Number) |
| return minutes * 60 + seconds |
| }, |
| toAudio, |
| toPTT, |
| toVideo, |
| ffmpeg, |
|
|
| removeBg, |
| FiletypeFromUrl, |
| removeCommand, |
| getBuffer, |
| extractUrlFromMessage, |
| decodeJid, |
| isAdmin: async (jid, user, client) => { |
| const groupMetadata = await client.groupMetadata(jid) |
| const groupAdmins = groupMetadata.participants.filter((participant) => participant.admin !== null).map((participant) => participant.id) |
|
|
| return groupAdmins.includes(decodeJid(user)) |
| }, |
| webp2mp4: async (source) => { |
| let form = new FormData() |
| let isUrl = typeof source === 'string' && /https?:\/\//.test(source) |
| form.append('new-image-url', isUrl ? source : '') |
| form.append('new-image', isUrl ? '' : source, 'image.webp') |
| let res = await fetch('https://ezgif.com/webp-to-mp4', { |
| method: 'POST', |
| body: form, |
| }) |
| let html = await res.text() |
| let { document } = new JSDOM(html).window |
| let form2 = new FormData() |
| let obj = {} |
| for (let input of document.querySelectorAll('form input[name]')) { |
| obj[input.name] = input.value |
| form2.append(input.name, input.value) |
| } |
| let res2 = await fetch('https://ezgif.com/webp-to-mp4/' + obj.file, { |
| method: 'POST', |
| body: form2, |
| }) |
| let html2 = await res2.text() |
| let { document: document2 } = new JSDOM(html2).window |
| return new URL(document2.querySelector('div#output > p.outfile > video > source').src, res2.url).toString() |
| }, |
| validatAndSaveDeleted, |
| webp2png: async (source) => { |
| let form = new FormData() |
| let isUrl = typeof source === 'string' && /https?:\/\//.test(source) |
| form.append('new-image-url', isUrl ? source : '') |
| form.append('new-image', isUrl ? '' : source, 'image.webp') |
| let res = await fetch('https://s6.ezgif.com/webp-to-png', { |
| method: 'POST', |
| body: form, |
| }) |
| let html = await res.text() |
| let { document } = new JSDOM(html).window |
| let form2 = new FormData() |
| let obj = {} |
| for (let input of document.querySelectorAll('form input[name]')) { |
| obj[input.name] = input.value |
| form2.append(input.name, input.value) |
| } |
| let res2 = await fetch('https://ezgif.com/webp-to-png/' + obj.file, { |
| method: 'POST', |
| body: form2, |
| }) |
| let html2 = await res2.text() |
| console.log(html2) |
| let { document: document2 } = new JSDOM(html2).window |
| return new URL(document2.querySelector('div#output > p.outfile > img').src, res2.url).toString() |
| }, |
| parseJid(text = '') { |
| return [...text.matchAll(/@([0-9]{5,16}|0)/g)].map((v) => v[1] + '@s.whatsapp.net') |
| }, |
| parsedJid(text = '') { |
| return [...text.matchAll(/([0-9]{5,16}|0)/g)].map((v) => v[1] + '@s.whatsapp.net') |
| }, |
| getLyrics, |
| getJson, |
| isIgUrl: (url) => { |
| return /(?:(?:http|https):\/\/)?(?:www.)?(?:instagram.com|instagr.am|instagr.com)\/(\w+)/gim.test(url) |
| }, |
| isUrl: (isUrl = (url) => { |
| return new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/, 'gi').test(url) |
| }), |
| getUrl: (getUrl = (url) => { |
| return url.match(new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/, 'gi')) |
| }), |
| qrcode: async (string) => { |
| const { toBuffer } = require('qrcode') |
| let buff = await toBuffer(string) |
| return buff |
| }, |
| aiImage, |
| secondsToDHMS: (seconds) => { |
| seconds = Number(seconds) |
|
|
| const days = Math.floor(seconds / (3600 * 24)) |
| seconds %= 3600 * 24 |
|
|
| const hours = Math.floor(seconds / 3600) |
| seconds %= 3600 |
|
|
| const minutes = Math.floor(seconds / 60) |
| seconds %= 60 |
|
|
| seconds = Math.floor(seconds) |
|
|
| const parts = [] |
|
|
| if (days) parts.push(`${days} Days`) |
| if (hours) parts.push(`${hours} Hours`) |
| if (minutes) parts.push(`${minutes} Minutes`) |
| if (seconds) parts.push(`${seconds} Seconds`) |
| return parts.join(' ') |
| }, |
| formatBytes: (bytes, decimals = 2) => { |
| if (!+bytes) return '0 Bytes' |
|
|
| const k = 1024 |
| const dm = decimals < 0 ? 0 : decimals |
| const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] |
|
|
| const i = Math.floor(Math.log(bytes) / Math.log(k)) |
|
|
| return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}` |
| }, |
| sleep: delay, |
| clockString: (duration) => { |
| ;(seconds = Math.floor((duration / 1000) % 60)), (minutes = Math.floor((duration / (1000 * 60)) % 60)), (hours = Math.floor((duration / (1000 * 60 * 60)) % 24)) |
|
|
| hours = hours < 10 ? '0' + hours : hours |
| minutes = minutes < 10 ? '0' + minutes : minutes |
| seconds = seconds < 10 ? '0' + seconds : seconds |
|
|
| return hours + ':' + minutes + ':' + seconds |
| }, |
| runtime: () => { |
| const duration = process.uptime() |
| const seconds = Math.floor(duration % 60) |
| const minutes = Math.floor((duration / 60) % 60) |
| const hours = Math.floor((duration / (60 * 60)) % 24) |
|
|
| const formattedTime = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` |
|
|
| return formattedTime |
| }, |
| validateQuality: (quality) => { |
| let valid = ['144p', '240p', '360p', '480p', '720p', '1080p'] |
| return valid.includes(quality) |
| }, |
| AddMp3Meta: async (songbuffer, coverBuffer, options = { title: 'X-Asena Whatsapp bot', artist: ['Xasena'] }) => { |
| if (!Buffer.isBuffer(songbuffer)) { |
| songbuffer = await getBuffer(songbuffer) |
| } |
| if (!Buffer.isBuffer(coverBuffer)) { |
| coverBuffer = await getBuffer(coverBuffer) |
| } |
|
|
| const writer = new id3(songbuffer) |
| writer.setFrame('TIT2', options.title).setFrame('TPE1', ['X-Asena']).setFrame('APIC', { |
| type: 3, |
| data: coverBuffer, |
| description: 'Xasena', |
| }) |
|
|
| writer.addTag() |
| return Buffer.from(writer.arrayBuffer) |
| }, |
| Bitly: async (url) => { |
| return new Promise((resolve, reject) => { |
| const BitlyClient = require('bitly').BitlyClient |
| const bitly = new BitlyClient('6e7f70590d87253af9359ed38ef81b1e26af70fd') |
| bitly |
| .shorten(url) |
| .then((a) => { |
| resolve(a) |
| }) |
| .catch((A) => reject(A)) |
| return |
| }) |
| }, |
| isNumber: function isNumber() { |
| const int = parseInt(this) |
| return typeof int === 'number' && !isNaN(int) |
| }, |
| getRandom: function getRandom() { |
| if (Array.isArray(this) || this instanceof String) return this[Math.floor(Math.random() * this.length)] |
| return Math.floor(Math.random() * this) |
| }, |
| createInteractiveMessage, |
| igdl, |
| textToImg, |
| readQr, |
| m3u82Mp4, |
| captureScreenshot, |
| editAudio, |
| } |
|
|