diff --git a/.env.example b/.env.example index ca2f12b..bbdfeca 100644 --- a/.env.example +++ b/.env.example @@ -22,4 +22,12 @@ ENABLE_REACTIONS="true" QUEUED_REACTION="🔁" WORKING_REACTION="⚙️" DONE_REACTION="✅" -ERROR_REACTION="⚠️" \ No newline at end of file +ERROR_REACTION="⚠️" + +# Whitelist (optional) +# The bot will only answer to these phone numbers (separated by commas) +# Leave this empty if you want the bot to answer to anyone +## Examples: +## Brazil: 5515999999999 # 55 = country code # 15 = area code # 999999999 = phone number +## US: 14155551111 # 1 = country code # 415 = area code # 5551111 = phone number +WHITELIST="5519999999999,14155551111" \ No newline at end of file diff --git a/src/clients/whatsapp.ts b/src/clients/whatsapp.ts index 80867ef..2855772 100644 --- a/src/clients/whatsapp.ts +++ b/src/clients/whatsapp.ts @@ -1,8 +1,13 @@ import qrcode from "qrcode-terminal"; import cli from "../clients/cli"; -import { Client } from "whatsapp-web.js"; +import { Client, GroupChat } from "whatsapp-web.js"; import { handleMessage } from "../handlers/message"; import { handleCommand } from "../handlers/command"; +import { intersection } from "../utils"; + +// filtering empty strings due to how Array.split() works +const WHITELIST = process.env.WHITELIST?.split(",").filter(e => e != "") ?? [] +const WHITELIST_ENABLED = WHITELIST.length != 0 export const whatsapp = new Client({ puppeteer: { @@ -42,14 +47,37 @@ whatsapp.on("ready", () => { }); whatsapp.on("message", async (message) => { - const sender = message.from; - console.log(`Message received from ${sender}`); - - if (sender == "status@broadcast") { - console.log("Its a status broadcast, ignoring..."); + if (message.from == "status@broadcast") { return; } + const chat = await message.getChat() + const contact = await message.getContact() + const sender = contact.id.user + + const _messageType = chat.isGroup ? "Group" : "DM" + const _sender = `${contact.pushname}[${sender}]` + console.log(`${_messageType} message received from ${_sender}`); + + if (WHITELIST_ENABLED) { + const isWhitelisted = WHITELIST.includes(sender) + + if (chat.isGroup) { + const participants = (chat as GroupChat).participants.map(user => user.id.user) + const whitelistedParticipants = intersection(WHITELIST, participants) + + if (whitelistedParticipants.length == 0) { + console.log("There are no whitelisted participants in this group. Ignoring.") + return + } + } else { + if (!isWhitelisted) { + console.log(`${_sender} is not whitelisted. Ignoring.`) + return + } + } + } + if (message.body.startsWith("!")) { const [command, ...args] = message.body.split(" "); await handleCommand(message, command, args.join(" ")); diff --git a/src/utils.ts b/src/utils.ts index 6e495b5..f46689a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,6 +3,12 @@ import { config } from "./config"; import dotenv from "dotenv"; dotenv.config(); +export function intersection(array1: T[], array2: T[]) { + const set = new Set(array1); + return array2.filter(value => set.has(value)); +}; + + const ENABLE_REACTIONS = (process.env.ENABLE_REACTIONS as | "true"