From 297086773fc530b26d7872769952dc2646dcc5f2 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 22 Jun 2024 07:23:28 +0800 Subject: [PATCH 1/3] added ignore mechanism --- functions/src/definitions/eventHandlers/userHandlers.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/functions/src/definitions/eventHandlers/userHandlers.ts b/functions/src/definitions/eventHandlers/userHandlers.ts index ab5fb9c0..a1255194 100644 --- a/functions/src/definitions/eventHandlers/userHandlers.ts +++ b/functions/src/definitions/eventHandlers/userHandlers.ts @@ -91,6 +91,14 @@ const userHandlerWhatsapp = async function (message: WhatsappMessageObject) { const isNewlyJoined = messageTimestamp.seconds - firstMessageReceiptTime.seconds < 86400 + const isBanned = userSnap.get("isBanned") + if (isBanned) { + functions.logger.warn( + `Message from banned user ${from}!, text: ${message?.text?.body}` + ) + return + } + switch (type) { case "text": // info on WhatsApp text message payload: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/payload-examples#text-messages From d66f25fe045069a8fd85f5ba38aa29bd9ef074d4 Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 22 Jun 2024 07:26:29 +0800 Subject: [PATCH 2/3] Added ignore mechanism for blocking users --- functions/src/definitions/eventHandlers/userHandlers.ts | 5 +++-- functions/src/types.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/functions/src/definitions/eventHandlers/userHandlers.ts b/functions/src/definitions/eventHandlers/userHandlers.ts index a1255194..75b74446 100644 --- a/functions/src/definitions/eventHandlers/userHandlers.ts +++ b/functions/src/definitions/eventHandlers/userHandlers.ts @@ -91,8 +91,8 @@ const userHandlerWhatsapp = async function (message: WhatsappMessageObject) { const isNewlyJoined = messageTimestamp.seconds - firstMessageReceiptTime.seconds < 86400 - const isBanned = userSnap.get("isBanned") - if (isBanned) { + const isIgnored = userSnap.get("isIgnored") + if (isIgnored) { functions.logger.warn( `Message from banned user ${from}!, text: ${message?.text?.body}` ) @@ -965,6 +965,7 @@ async function createNewUser( referralCount: 0, language: "en", isSubscribedUpdates: true, + isIgnored: false, } await userRef.set(newUserObject) } diff --git a/functions/src/types.ts b/functions/src/types.ts index 7d15dc7c..ef72ad0b 100644 --- a/functions/src/types.ts +++ b/functions/src/types.ts @@ -131,6 +131,7 @@ export type UserData = { referralCount: number language: "en" | "cn" isSubscribedUpdates: boolean + isIgnored: boolean } export type CheckerData = { From 105833f6d00c86cdb7c5eeb87d34e4b6a4c6871f Mon Sep 17 00:00:00 2001 From: Bing Wen Tan Date: Sat, 22 Jun 2024 07:31:35 +0800 Subject: [PATCH 3/3] updated readme --- README.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index e0f534c2..400a9831 100644 --- a/README.md +++ b/README.md @@ -356,6 +356,7 @@ erDiagram string utm "map containing utm parameters, source, medium, content, campaign, term" string language "en or cn, users preferred language" boolean isSubscribedUpdates "whether to blast msgs to this user" + boolean isIgnored "whether the user should be ignored, i.e. blocked, in which case they get no responses" } blasts { @@ -390,7 +391,7 @@ erDiagram The below diagram displays the core flow when users interact with the WhatsApp bot. Each subgraph corresponds to a particular function in functions/src/definitions/, and some nested subgraphs, if there, refer to subfunctions declared within the cloud functions. Some of the functions are also referenced in the above architecture diagram. -Dotted lines refer to asynchronous processes that take longer than the order of seconds. Most of the interfaces between subgraphs/functions are asynchronous in the software engineering sense but they happen near-instantaneously. +Dotted lines refer to asynchronous processes that take longer than the order of seconds. Most of the interfaces between subgraphs/functions are asynchronous in the software engineering sense but they happen near-instantaneously. ```mermaid flowchart TB @@ -523,27 +524,27 @@ We currently have 3 environments, prod, uat, and local. The `/integration-tests` 1. `git clone https://github.com/CheckMateSG/checkMate.git` 2. `cd checkMate` 3. `npm install -g firebase-tools` - - you may have to install/upgrade your java -5. `npm run postinstall` -6. run `firebase login --no-localhost` then login with your betterSG email -7. Contact @sarge1989 to set you up with a cloudflare tunnel, and provide your WhatsApp number so the routing can be done to your setup. _Ngrok will not work for this step_, hence the need for this. -8. Contact @sarge1989 to obtain .secret.local and .env.local files, which for now will be sent via password-encrypted zip. Place these two files in the `/functions` directory -9. The phone number to the WhatsApp User bot non-prod number is also in said zip file, in `WhatsApp.txt`. You might want to add it to your contacts for easy access. + - you may have to install/upgrade your java +4. `npm run postinstall` +5. run `firebase login --no-localhost` then login with your betterSG email +6. Contact @sarge1989 to set you up with a cloudflare tunnel, and provide your WhatsApp number so the routing can be done to your setup. _Ngrok will not work for this step_, hence the need for this. +7. Contact @sarge1989 to obtain .secret.local and .env.local files, which for now will be sent via password-encrypted zip. Place these two files in the `/functions` directory +8. The phone number to the WhatsApp User bot non-prod number is also in said zip file, in `WhatsApp.txt`. You might want to add it to your contacts for easy access. ### If working on Checkers App 1. Create your own Telegram bot via [botfather](https://t.me/botfather) 2. Replace `TELEGRAM_CHECKER_BOT_TOKEN` in `.secret.local` with the bot token. Note, it is `TELEGRAM_CHECKER_BOT_TOKEN` and not `TELEGRAM_BOT_TOKEN` or `TELEGRAM_WEBHOOK_TOKEN` -3. Go to botfather, navigate to the bot you created, go to "Bot Settings" > "Menu Button". Then add the cloudflare tunnel URL provided by @sarge1989 in step 7 above that routes to your localhost:5000 +3. Go to botfather, navigate to the bot you created, go to "Bot Settings" > "Menu Button". Then add the cloudflare tunnel URL provided by @sarge1989 in step 7 above that routes to your localhost:5000 4. In .env.local, replace `CHECKER1_TELEGRAM_ID` and `CHECKER1_PHONE_NUMBER` with your own Telegram ID and WhatsApp Phone number respectively. Note that Whatsapp Phone number should include the country code e.g. 6591111111. Telegram ID can be obtained via this [telegram bot](https://t.me/myidbot) ### First time testing (once all above steps are done) 1. Execute the steps in the below section "Each time developing" 2. Go to the chat with the WhatsApp User bot non-prod number and send in /mockup -2. Ensure that the [Firestore Emulator](http://127.0.0.1:4000/firestore) has been populated with some data -3. Send "hi" to the WhatsApp User bot non-prod number. This should trigger the first usage onboarding -4. Send a message such as "Best Fixed Deposit Rates yield 3.75% if you deposit via Syfe (to get institutional fixed deposit rates) (as of June 2024)" into the bot. You'll notice something onUserPublish might take a while, but this should trigger the asynchronous checking flow +3. Ensure that the [Firestore Emulator](http://127.0.0.1:4000/firestore) has been populated with some data +4. Send "hi" to the WhatsApp User bot non-prod number. This should trigger the first usage onboarding +5. Send a message such as "Best Fixed Deposit Rates yield 3.75% if you deposit via Syfe (to get institutional fixed deposit rates) (as of June 2024)" into the bot. You'll notice something onUserPublish might take a while, but this should trigger the asynchronous checking flow - You can expect to see this on your console: ````> {"severity":"INFO","message":"Processing 5"} > {"severity":"INFO","message":"Unable to get Google identity token in lower environments"} @@ -552,10 +553,10 @@ We currently have 3 environments, prod, uat, and local. The `/integration-tests` i functions: Beginning execution of "asia-southeast1-onMessageWriteV2" > {"severity":"INFO","message":"Transaction success for messageId wamid.HBgKNjU5M452y262ya53452U0QjZBQkYyNEM5NwA=!"}``` ```` -5. You should see a notification in your Telegram Bot. Go through the voting process. -6. Once done, you should get a reply on the user whatsapp bot. -7. With that, you've basically gone through the end-to-end flow for one message (albeit with only 1 voter in the pool) - +6. You should see a notification in your Telegram Bot. Go through the voting process. +7. Once done, you should get a reply on the user whatsapp bot. +8. With that, you've basically gone through the end-to-end flow for one message (albeit with only 1 voter in the pool) + ### Each Time Developing 1. Open 3 shells from in root directory @@ -567,9 +568,11 @@ We currently have 3 environments, prod, uat, and local. The `/integration-tests` 7. Can start on development. There should be live refreshing on the changes you make #### Note: + - When shutting down the emulator, proceed in this order. - - Control-C in Shell 3. Enter "Y" if prompted. Otherwise, pre-existing data may not be saved to local. - - Close the windows running the Java applications. Otherwise, the port will be used up. + - Control-C in Shell 3. Enter "Y" if prompted. Otherwise, pre-existing data may not be saved to local. + - Close the windows running the Java applications. Otherwise, the port will be used up. + --- In the event the Makefile doesn't work,