From 55d2f1e216cb4d4d620a14c846e16079cb352d34 Mon Sep 17 00:00:00 2001 From: doitwithnotepad Date: Wed, 14 Aug 2024 12:01:20 +0000 Subject: [PATCH 1/5] Add cronjob to notify admin about missing solvers (#314) - Schedule a daily job at midnight to check for solvers using `node-schedule`. - Implement `checkSolvers(bot)` to send a message to the community admin if no solvers are found. - Increment the count of messages sent to the admin in the database. - Add logic to disable the community if no solvers are added after a specified number of notifications. Fixes #314 --- bot/start.ts | 5 +++++ jobs/check_solvers.ts | 40 ++++++++++++++++++++++++++++++++++++++++ models/community.ts | 4 ++++ 3 files changed, 49 insertions(+) create mode 100644 jobs/check_solvers.ts diff --git a/bot/start.ts b/bot/start.ts index fbbc5737..903d33f4 100644 --- a/bot/start.ts +++ b/bot/start.ts @@ -63,6 +63,7 @@ const { attemptCommunitiesPendingPayments, deleteCommunity, nodeInfo, + checkSolvers, } = require('../jobs'); const { logger } = require('../logger'); export interface MainContext extends Context { @@ -197,6 +198,10 @@ const initialize = (botToken: string, options: Partial { + await checkSolvers(bot); + }); + bot.start(async (ctx: MainContext) => { try { if (!('message' in ctx.update) || !('text' in ctx.update.message)){ diff --git a/jobs/check_solvers.ts b/jobs/check_solvers.ts new file mode 100644 index 00000000..45137a35 --- /dev/null +++ b/jobs/check_solvers.ts @@ -0,0 +1,40 @@ +import { Community, User } from '../models'; +import { Telegraf } from 'telegraf'; +import { MainContext } from '../bot/start'; +import { logger } from '../logger'; + +const MAX_MESSAGES = 5; // Number of messages before disabling the community + +exports.checkSolvers = async (bot: Telegraf): Promise => { + try { + const communities = await Community.find({ isDisabled: false }); + + for (const community of communities) { + const solvers = await User.find({ default_community_id: community._id, role: 'solver' }); + + if (solvers.length === 0) { + community.messagesSent += 1; + + if (community.messagesSent >= MAX_MESSAGES) { + community.isDisabled = true; + await community.save(); + logger.info(`Community ${community._id} has been disabled due to lack of solvers.`); + } else { + await community.save(); + const admin = await User.findOne({ tg_id: community.creator_id, admin: true }); + if (admin) { + await bot.telegram.sendMessage( + admin.tg_id, + `Your community ${community.name} doesn't have any solvers. Please add at least one solver.` + ); + } + } + } else { + community.messagesSent = 0; // Reset the counter if solvers are added + await community.save(); + } + } + } catch (error) { + logger.error(error); + } +}; diff --git a/models/community.ts b/models/community.ts index 09e34908..fdd0f79a 100644 --- a/models/community.ts +++ b/models/community.ts @@ -49,6 +49,8 @@ export interface ICommunity extends Document { currencies: Array; created_at: Date; nostr_public_key: string; + messagesSent: number; + isDisabled: boolean; } const CommunitySchema = new Schema({ @@ -81,6 +83,8 @@ const CommunitySchema = new Schema({ }, created_at: { type: Date, default: Date.now }, nostr_public_key: { type: String }, + messagesSent: { type: Number, default: 0 }, + isDisabled: { type: Boolean, default: false }, }); From 29fa53979b957fafb2af4ac778dc3a60f826a7b5 Mon Sep 17 00:00:00 2001 From: doitwithnotepad Date: Wed, 14 Aug 2024 21:02:20 +0000 Subject: [PATCH 2/5] Add constant to .env file --- .env-sample | 5 ++++- jobs/check_solvers.ts | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.env-sample b/.env-sample index 8aa836f9..2ec39a67 100644 --- a/.env-sample +++ b/.env-sample @@ -80,4 +80,7 @@ COMMUNITY_CURRENCIES=20 RELAYS='ws://localhost:7000,ws://localhost:8000,ws://localhost:9000' # Seconds to wait to allow disputes to be started -DISPUTE_START_WINDOW=600 \ No newline at end of file +DISPUTE_START_WINDOW=600 + +# Number of messages before disabling the community +COMMUNITY_MESSAGES=5 \ No newline at end of file diff --git a/jobs/check_solvers.ts b/jobs/check_solvers.ts index 45137a35..44cc61d9 100644 --- a/jobs/check_solvers.ts +++ b/jobs/check_solvers.ts @@ -3,7 +3,7 @@ import { Telegraf } from 'telegraf'; import { MainContext } from '../bot/start'; import { logger } from '../logger'; -const MAX_MESSAGES = 5; // Number of messages before disabling the community +const MESSAGES: number = parseInt(process.env.COMMUNITY_MESSAGES || '5'); exports.checkSolvers = async (bot: Telegraf): Promise => { try { @@ -15,7 +15,7 @@ exports.checkSolvers = async (bot: Telegraf): Promise => { if (solvers.length === 0) { community.messagesSent += 1; - if (community.messagesSent >= MAX_MESSAGES) { + if (community.messagesSent >= MESSAGES) { community.isDisabled = true; await community.save(); logger.info(`Community ${community._id} has been disabled due to lack of solvers.`); From 308821bf1e44d0a9f33671b99a2a2a13932ccfa0 Mon Sep 17 00:00:00 2001 From: doitwithnotepad Date: Wed, 14 Aug 2024 21:03:31 +0000 Subject: [PATCH 3/5] i18n stuff --- jobs/check_solvers.ts | 7 ++----- locales/de.yaml | 4 ++++ locales/en.yaml | 4 ++++ locales/es.yaml | 4 ++++ locales/fa.yaml | 4 ++++ locales/fr.yaml | 4 ++++ locales/it.yaml | 4 ++++ locales/ko.yaml | 4 ++++ locales/pt.yaml | 4 ++++ locales/ru.yaml | 4 ++++ locales/uk.yaml | 4 ++++ 11 files changed, 42 insertions(+), 5 deletions(-) diff --git a/jobs/check_solvers.ts b/jobs/check_solvers.ts index 44cc61d9..febc599c 100644 --- a/jobs/check_solvers.ts +++ b/jobs/check_solvers.ts @@ -5,7 +5,7 @@ import { logger } from '../logger'; const MESSAGES: number = parseInt(process.env.COMMUNITY_MESSAGES || '5'); -exports.checkSolvers = async (bot: Telegraf): Promise => { +exports.checkSolvers = async (ctx: MainContext, bot: Telegraf): Promise => { try { const communities = await Community.find({ isDisabled: false }); @@ -23,10 +23,7 @@ exports.checkSolvers = async (bot: Telegraf): Promise => { await community.save(); const admin = await User.findOne({ tg_id: community.creator_id, admin: true }); if (admin) { - await bot.telegram.sendMessage( - admin.tg_id, - `Your community ${community.name} doesn't have any solvers. Please add at least one solver.` - ); + await bot.telegram.sendMessage(admin.tg_id, ctx.i18n.t('check_solvers')); } } } else { diff --git a/locales/de.yaml b/locales/de.yaml index c7072800..172219f3 100644 --- a/locales/de.yaml +++ b/locales/de.yaml @@ -619,3 +619,7 @@ order_frozen: Sie haben die Bestellung eingefroren dispute_solver: 👮‍♂️ Ein Löser wird sich um Ihren Streitfall kümmern, Sie können ihn/sie direkt anschreiben, indem Sie auf seinen/ihren Benutzernamen tippen => @${solver} <=, wenn der Löser Sie zuerst anschreibt, sollten Sie ihn/sie bitten, Ihnen mitzuteilen, was das Token Ihres Streitfalls ist, Ihr Token ist ${token}. setinvoice_no_response: Sie haben keine zu bezahlenden Aufträge already_cancelled: Die Bestellung wurde bereits storniert! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/en.yaml b/locales/en.yaml index 38d487b4..9687e800 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -620,3 +620,7 @@ disclaimer: | order_frozen: You have frozen the order dispute_solver: 👮‍♂️ A solver will be attending your dispute, you can write to him/her directly by tapping his/her username => @${solver} <=, if the solver writes to you first, you should ask him/her to tell you what is the token of your dispute, your token is ${token}. setinvoice_no_response: You have no orders to be paid + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/es.yaml b/locales/es.yaml index 659d0889..6fc285d5 100644 --- a/locales/es.yaml +++ b/locales/es.yaml @@ -618,3 +618,7 @@ order_frozen: Has congelado la orden dispute_solver: 👮‍♂️ Un solver estará atendiendo tu disputa, puedes escribirle directamente tocando su username => @${solver} <=, si el/la solver te escribe primero, debes pedirle que te diga cuál es el token de tu disputa, tu token es ${token}. setinvoice_no_response: No tienes ordenes a ser pagadas already_cancelled: ¡La orden ya ha sido cancelada! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/fa.yaml b/locales/fa.yaml index 599e905f..b617cdcd 100644 --- a/locales/fa.yaml +++ b/locales/fa.yaml @@ -618,3 +618,7 @@ order_frozen: شما سفارش را مسدود کردید dispute_solver: 👮‍♂️ یک حل‌کننده در دعوای شما شرکت خواهد کرد، می‌توانید با ضربه زدن روی نام کاربری او مستقیماً برای او بنویسید => @${solver} <=، اگر حل‌کننده ابتدا برای شما نامه نوشت، باید از او بخواهید که به شما بگویم که نشانه اختلاف شما چیست، رمز شما ${token} است. setinvoice_no_response: هیچ سفارشی برای پرداخت ندارید already_cancelled: سفارش قبلاً لغو شده است! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/fr.yaml b/locales/fr.yaml index 23a0a37e..694e664d 100644 --- a/locales/fr.yaml +++ b/locales/fr.yaml @@ -618,3 +618,7 @@ order_frozen: Vous avez gelé la commande dispute_solver: 👮‍♂️ Un résolveur va s'occuper de votre litige, vous pouvez lui écrire directement en tapant son nom d'utilisateur => @${solver} <=, si le résolveur vous écrit en premier, vous devriez lui demander de vous dire quel est le jeton de votre litige, votre jeton est ${token}. setinvoice_no_response : Vous n'avez pas d'ordre à payer already_cancelled: L'offre a déjà été annulée ! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/it.yaml b/locales/it.yaml index efa9baa2..7efc5c69 100644 --- a/locales/it.yaml +++ b/locales/it.yaml @@ -616,3 +616,7 @@ order_frozen: hai congelato l'ordine dispute_solver: 👮‍♂️ Un solutore si occuperà della vostra controversia, potete scrivergli direttamente toccando il suo nome utente => @${solver} <=, se il solutore vi scrive per primo, dovreste chiedergli di dirvi qual è il token della vostra controversia, il vostro token è ${token}. setinvoice_no_response: Non ci sono ordini da pagare. already_cancelled: L'offerta è già stata annullata! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/ko.yaml b/locales/ko.yaml index 318bd83c..79574f73 100644 --- a/locales/ko.yaml +++ b/locales/ko.yaml @@ -614,3 +614,7 @@ disclaimer: | dispute_solver: 👮‍♂️ 분쟁 해결사가 분쟁에 참석할 것이며, 사용자 아이디 => @${해결사} <=를 눌러 해결사에게 직접 편지를 보낼 수 있으며, 해결사가 먼저 편지를 보내면 분쟁의 토큰이 무엇인지 물어봐야 하며, 토큰은 ${토큰}입니다. setinvoice_no_response: 결제할 주문이 없습니다. already_cancelled: 오퍼가 이미 취소되었습니다! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/pt.yaml b/locales/pt.yaml index ebb91b9e..2fd37703 100644 --- a/locales/pt.yaml +++ b/locales/pt.yaml @@ -616,3 +616,7 @@ order_frozen: Você congelou o pedido dispute_solver: 👮‍♂️ Um solucionador atenderá sua disputa. Você pode escrever para ele diretamente tocando no nome de usuário dele => @${solver} <=, se o solucionador escrever para você primeiro, você deve pedir a ele que lhe diga qual é o token de sua disputa, seu token é ${token}. setinvoice_no_response: Você não tem ordens a serem pagas already_cancelled: A oferta já foi cancelada! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/ru.yaml b/locales/ru.yaml index 6c4e832a..cd27c929 100644 --- a/locales/ru.yaml +++ b/locales/ru.yaml @@ -619,3 +619,7 @@ order_frozen: вы заморозили заказ dispute_solver: 👮‍♂️ На вашем споре будет присутствовать решатель, вы можете написать ему напрямую, нажав его имя пользователя => @${solver} <=, если решатель напишет вам первым, вы должны попросить его сообщить вам, какой токен у вашего спора, ваш токен - ${token}. setinvoice_no_response: У вас нет заказов для оплаты already_cancelled: Предложение уже отменено! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers diff --git a/locales/uk.yaml b/locales/uk.yaml index 79e51029..c48e394f 100644 --- a/locales/uk.yaml +++ b/locales/uk.yaml @@ -615,3 +615,7 @@ order_frozen: Ви заморозили замовлення dispute_solver: 👮‍♂️ У вашій суперечці буде присутній розв'язувач, ви можете написати йому безпосередньо, натиснувши його ім'я користувача => @${solver} <=, якщо розв'язувач напише вам першим, ви повинні попросити його повідомити вам токен вашої суперечки, вашим токеном буде ${token}. setinvoice_no_response: У вас немає замовлень для оплати already_cancelled: Пропозицію вже скасовано! + +# START jobs/check_solvers +check_solvers: Your community ${community.name} doesn't have any solvers. Please add at least one solver. +# END jobs/check_solvers From 28360d2fa3adc9294df24bc2f3b94581eb290e3b Mon Sep 17 00:00:00 2001 From: doitwithnotepad Date: Wed, 14 Aug 2024 21:19:48 +0000 Subject: [PATCH 4/5] Proper export function --- jobs/check_solvers.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jobs/check_solvers.ts b/jobs/check_solvers.ts index febc599c..86da6213 100644 --- a/jobs/check_solvers.ts +++ b/jobs/check_solvers.ts @@ -5,7 +5,7 @@ import { logger } from '../logger'; const MESSAGES: number = parseInt(process.env.COMMUNITY_MESSAGES || '5'); -exports.checkSolvers = async (ctx: MainContext, bot: Telegraf): Promise => { +const checkSolvers = async (ctx: MainContext, bot: Telegraf): Promise => { try { const communities = await Community.find({ isDisabled: false }); @@ -35,3 +35,5 @@ exports.checkSolvers = async (ctx: MainContext, bot: Telegraf): Pro logger.error(error); } }; + +module.exports = { checkSolvers }; From bcce2700f17c926e1a82c02969c313353e3e4b56 Mon Sep 17 00:00:00 2001 From: doitwithnotepad Date: Wed, 14 Aug 2024 21:43:19 +0000 Subject: [PATCH 5/5] Fix proper export function --- jobs/check_solvers.ts | 4 +--- jobs/index.js | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jobs/check_solvers.ts b/jobs/check_solvers.ts index 86da6213..febc599c 100644 --- a/jobs/check_solvers.ts +++ b/jobs/check_solvers.ts @@ -5,7 +5,7 @@ import { logger } from '../logger'; const MESSAGES: number = parseInt(process.env.COMMUNITY_MESSAGES || '5'); -const checkSolvers = async (ctx: MainContext, bot: Telegraf): Promise => { +exports.checkSolvers = async (ctx: MainContext, bot: Telegraf): Promise => { try { const communities = await Community.find({ isDisabled: false }); @@ -35,5 +35,3 @@ const checkSolvers = async (ctx: MainContext, bot: Telegraf): Promi logger.error(error); } }; - -module.exports = { checkSolvers }; diff --git a/jobs/index.js b/jobs/index.js index b784f178..98f88419 100644 --- a/jobs/index.js +++ b/jobs/index.js @@ -7,6 +7,7 @@ const deleteOrders = require('./delete_published_orders'); const calculateEarnings = require('./calculate_community_earnings'); const deleteCommunity = require('./communities'); const nodeInfo = require('./node_info'); +const checkSolvers = require('./check_solvers'); module.exports = { attemptPendingPayments, @@ -16,4 +17,5 @@ module.exports = { attemptCommunitiesPendingPayments, deleteCommunity, nodeInfo, + checkSolvers, };