does anybody read those anyway?
This commit is contained in:
parent
7a784afbee
commit
30933415c9
13
bot/bot.ts
13
bot/bot.ts
@ -14,8 +14,10 @@ export const runBot = async (cfg: BotConfig, initMode: (bot: Bot<Ctx>) => void)
|
|||||||
const i18n = new I18n<Ctx>({
|
const i18n = new I18n<Ctx>({
|
||||||
defaultLocale: "en",
|
defaultLocale: "en",
|
||||||
directory: cfg.locales_dir,
|
directory: cfg.locales_dir,
|
||||||
|
localeNegotiator: (ctx) =>
|
||||||
|
ctx.from?.language_code ?? "en"
|
||||||
})
|
})
|
||||||
console.log(i18n.locales)
|
console.log("Loaded locales: ", i18n.locales)
|
||||||
bot.use(session({ initial: defaultSessionData }), i18n)
|
bot.use(session({ initial: defaultSessionData }), i18n)
|
||||||
|
|
||||||
bot.catch((err: BotError<Context>) => {
|
bot.catch((err: BotError<Context>) => {
|
||||||
@ -37,5 +39,12 @@ export const runBot = async (cfg: BotConfig, initMode: (bot: Bot<Ctx>) => void)
|
|||||||
await bot.init()
|
await bot.init()
|
||||||
|
|
||||||
console.log(`starting bot ${bot.botInfo.username}`)
|
console.log(`starting bot ${bot.botInfo.username}`)
|
||||||
await bot.start().catch(err => console.log(err))
|
await bot.start({
|
||||||
|
allowed_updates: [
|
||||||
|
"chat_member",
|
||||||
|
"message",
|
||||||
|
"inline_query"
|
||||||
|
]
|
||||||
|
}).catch(err => console.log(err))
|
||||||
|
await bot.stop();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Captcha
|
# Captcha
|
||||||
captcha-already-in-chat = You are already in chat
|
captcha-already-in-chat = You are already in the chat.
|
||||||
captcha-passed = Captcha passed! Now you can join the community: { invite_link }
|
captcha-passed = Captcha passed! Now you can join the community: { $invite_link }
|
||||||
captcha-failed = You didn't pass the captcha. You can try again after { timeout_mins } minutes.
|
captcha-failed = You didn't pass the captcha. You can try again after { $timeout_mins } minute(s).
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Captcha
|
# Captcha
|
||||||
captcha-already-in-chat = Már a csevegésben vagy
|
captcha-already-in-chat = Már a csevegésben vagy
|
||||||
captcha-passed = Captcha sikeresen teljesítve! Most már csatlakozhat közösségünkhöz: { invite_link }
|
captcha-passed = Captcha sikeresen teljesítve! Most már csatlakozhat közösségünkhöz: { $invite_link }
|
||||||
captcha-failed = A captcha nem sikerült. 15 perc múlva próbálkozhat { timeout_mins } újra.
|
captcha-failed = A captcha nem sikerült. 15 perc múlva próbálkozhat { $timeout_mins } újra.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Captcha
|
# Captcha
|
||||||
captcha-already-in-chat = Już jesteś na czacie
|
captcha-already-in-chat = Już jesteś na czacie
|
||||||
captcha-passed = Captcha pomyślnie zakończona! Teraz możesz dołączyć do naszej społeczności: { invite_link }
|
captcha-passed = Captcha pomyślnie zakończona! Teraz możesz dołączyć do naszej społeczności: { $invite_link }
|
||||||
captcha-failed = Captcha nieudana. Spróbuj ponownie za { timeout_mins } minut.
|
captcha-failed = Captcha nieudana. Spróbuj ponownie za { $timeout_mins } minut.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Captcha
|
# Captcha
|
||||||
captcha-already-in-chat = Ti si već u chat-u
|
captcha-already-in-chat = Ti si već u chat-u
|
||||||
captcha-passed = Uspeo si sa captch-om! Sada mozes predruziti se nasoj zajednici: { invite_link }
|
captcha-passed = Uspeo si sa captch-om! Sada mozes predruziti se nasoj zajednici: { $invite_link }
|
||||||
captcha-failed = Nisi prošao captch-u. Mozes pokušati ponovo za { timeout_mins } minuta.
|
captcha-failed = Nisi prošao captch-u. Mozes pokušati ponovo za { $timeout_mins } minuta.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Captcha
|
# Captcha
|
||||||
captcha-already-in-chat = Вы уже в чате
|
captcha-already-in-chat = Вы уже в чате
|
||||||
captcha-passed = Капча пройдена! Теперь вы можете присоединиться к нашему сообществу: { invite_link }
|
captcha-passed = Капча пройдена! Теперь вы можете присоединиться к нашему сообществу: { $invite_link }
|
||||||
captcha-failed = Капча не пройдена. Вы сможете попробовать снова через { timeout_mins } минут.
|
captcha-failed = Капча не пройдена. Вы сможете попробовать снова через { $timeout_mins } минут.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Captcha
|
# Captcha
|
||||||
captcha-already-in-chat = Ви вже в чаті
|
captcha-already-in-chat = Ви вже в чаті
|
||||||
captcha-passed = Капча пройдена! Капча пройдена! Тепер ви можете приєднатися до нашої спільноти: { invite_link }
|
captcha-passed = Капча пройдена! Капча пройдена! Тепер ви можете приєднатися до нашої спільноти: { $invite_link }
|
||||||
captcha-failed = Капча не пройдена. Ви зможете спробувати ще раз через { timeout_mins } хвилин.
|
captcha-failed = Капча не пройдена. Ви зможете спробувати ще раз через { $timeout_mins } хвилин.
|
||||||
|
@ -76,14 +76,14 @@ const captchaFailed = async (ctx: Filter<Ctx, "message:text">, db: Kysely<Databa
|
|||||||
ctx.session.captcha_data!.tries_failed++
|
ctx.session.captcha_data!.tries_failed++
|
||||||
if (ctx.session.captcha_data!.tries_failed > CAPTCHA_FAILS_LIMIT) {
|
if (ctx.session.captcha_data!.tries_failed > CAPTCHA_FAILS_LIMIT) {
|
||||||
const timeoutUntil = new Date()
|
const timeoutUntil = new Date()
|
||||||
timeoutUntil.setHours(timeoutUntil.getHours() + 12)
|
timeoutUntil.setMinutes(timeoutUntil.getMinutes() + TIMEOUT_AFTER_FAIL_MINS)
|
||||||
|
|
||||||
await db.updateTable('users').set({
|
await db.updateTable('users').set({
|
||||||
timeout_until: timeoutUntil,
|
timeout_until: timeoutUntil,
|
||||||
is_timeout: true,
|
is_timeout: true,
|
||||||
}).where('tg_id', '=', ctx.from.id).execute()
|
}).where('tg_id', '=', ctx.from.id).execute()
|
||||||
|
|
||||||
await ctx.reply(ctx.t("captcha-already-in-chat",
|
await ctx.reply(ctx.t("captcha-failed",
|
||||||
{timeout_mins: TIMEOUT_AFTER_FAIL_MINS}))
|
{timeout_mins: TIMEOUT_AFTER_FAIL_MINS}))
|
||||||
await ctx.api.deleteMessage(ctx.chatId, ctx.session.captcha_data!.message_id)
|
await ctx.api.deleteMessage(ctx.chatId, ctx.session.captcha_data!.message_id)
|
||||||
}
|
}
|
||||||
@ -119,7 +119,12 @@ export const checkCaptchaSolution = async (ctx: Filter<Ctx, "message:text">, db:
|
|||||||
|
|
||||||
const user = users[0]
|
const user = users[0]
|
||||||
const userRestrictions = await checkUserRestrictions(db, user)
|
const userRestrictions = await checkUserRestrictions(db, user)
|
||||||
if (userRestrictions.isBlocked || userRestrictions.isTimeout) return
|
if (userRestrictions.isBlocked) return
|
||||||
|
if (userRestrictions.isTimeout) {
|
||||||
|
await ctx.reply("You were timed out")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log("User Info: ", user)
|
||||||
|
|
||||||
if (isSolutionCorrect(ctx.session.captcha_data!.solution, ctx.message.text)) {
|
if (isSolutionCorrect(ctx.session.captcha_data!.solution, ctx.message.text)) {
|
||||||
await captchaPassed(ctx, db, cfg)
|
await captchaPassed(ctx, db, cfg)
|
||||||
|
@ -4,12 +4,10 @@ import { Kysely } from 'npm:kysely';
|
|||||||
import { Ctx } from "../ctx.ts";
|
import { Ctx } from "../ctx.ts";
|
||||||
import { Database } from "../../repo/scheme.ts";
|
import { Database } from "../../repo/scheme.ts";
|
||||||
import { CompiledConfig } from "../../cfg/config.ts";
|
import { CompiledConfig } from "../../cfg/config.ts";
|
||||||
import { checkUser, checkUserOnNewChatMember, onMemberLeftChat, checkUserOnStart } from "./user_managment.ts";
|
import { checkUserOnNewChatMember, onMemberLeftChat, checkUserOnStart, checkUserTrx } from "./user_managment.ts";
|
||||||
import { checkCaptchaSolution, initUserCaptcha } from "./captcha.ts";
|
import { checkCaptchaSolution, initUserCaptcha } from "./captcha.ts";
|
||||||
import { handleSafebooruQuery } from "./safebooru.ts";
|
import { handleSafebooruQuery } from "./safebooru.ts";
|
||||||
|
|
||||||
const DEFAULT_LOCALE = "en"
|
|
||||||
|
|
||||||
interface ChatMemberUpdateStatus {
|
interface ChatMemberUpdateStatus {
|
||||||
joined: boolean,
|
joined: boolean,
|
||||||
left: boolean,
|
left: boolean,
|
||||||
@ -19,13 +17,14 @@ interface ChatMemberUpdateStatus {
|
|||||||
}
|
}
|
||||||
function getChatMemberUpdateStatus(oldMember: ChatMember, newMember: ChatMember): ChatMemberUpdateStatus {
|
function getChatMemberUpdateStatus(oldMember: ChatMember, newMember: ChatMember): ChatMemberUpdateStatus {
|
||||||
return {
|
return {
|
||||||
joined: oldMember.status === "left" &&
|
joined: (oldMember.status === "left" || oldMember.status === "kicked")
|
||||||
newMember.status !== "left" && newMember.status !== "kicked",
|
&& (newMember.status !== "left" && newMember.status !== "kicked"),
|
||||||
left: oldMember.status !== "left" && newMember.status === "left",
|
left: (oldMember.status !== "left" && oldMember.status !== "kicked")
|
||||||
|
&& (newMember.status === "left" || newMember.status === "kicked"),
|
||||||
kicked: newMember.status === "kicked",
|
kicked: newMember.status === "kicked",
|
||||||
restricted: oldMember.status !== "restricted" && newMember.status === "restricted",
|
restricted: oldMember.status !== "restricted" && newMember.status === "restricted",
|
||||||
roleChanged: oldMember.status !== newMember.status &&
|
roleChanged: oldMember.status !== newMember.status
|
||||||
(newMember.status !== "left" && newMember.status !== "kicked")
|
&& (newMember.status !== "left" && newMember.status !== "kicked")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,22 +41,19 @@ export const init = (bot: Bot<Ctx>, db: Kysely<Database>, cfg: CompiledConfig) =
|
|||||||
`From: ${ctx.from.first_name} ${ctx.from.last_name} `+
|
`From: ${ctx.from.first_name} ${ctx.from.last_name} `+
|
||||||
`UID: ${ctx.from.id} Locale: ${ctx.from.language_code}`)
|
`UID: ${ctx.from.id} Locale: ${ctx.from.language_code}`)
|
||||||
console.log(ctx.msg.text)
|
console.log(ctx.msg.text)
|
||||||
console.log()
|
|
||||||
ctx.i18n.useLocale(ctx.from.language_code || DEFAULT_LOCALE)
|
|
||||||
await next()
|
await next()
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.on('message:text', async (ctx, next) => {
|
bot.on('message:text', async (ctx, next) => {
|
||||||
if (ctx.chat.id === botCfg.chat_id) {
|
if (ctx.chat.id === botCfg.chat_id) {
|
||||||
console.log("Message was sent into the mic chat")
|
console.log("Message was sent into the mic chat")
|
||||||
const userInfo = await checkUser(ctx, db, botCfg, true)
|
const userInfo = await checkUserTrx(ctx, db, cfg.botCfg, true)
|
||||||
console.log("User Info: ", userInfo)
|
console.log("User Info: ", userInfo)
|
||||||
} else if (ctx.message.chat.type == "private" && ctx.session.captcha_data) {
|
} else if (ctx.message.chat.type == "private" && ctx.session.captcha_data) {
|
||||||
console.log("Handling message as captcha solution")
|
console.log("Handling message as captcha solution")
|
||||||
await checkCaptchaSolution(ctx, db, botCfg)
|
await checkCaptchaSolution(ctx, db, botCfg)
|
||||||
} else {
|
|
||||||
await next()
|
|
||||||
}
|
}
|
||||||
|
await next()
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.command('start', async ctx => {
|
bot.command('start', async ctx => {
|
||||||
@ -69,25 +65,28 @@ export const init = (bot: Bot<Ctx>, db: Kysely<Database>, cfg: CompiledConfig) =
|
|||||||
})
|
})
|
||||||
|
|
||||||
bot.on('chat_member', async (ctx, next) => {
|
bot.on('chat_member', async (ctx, next) => {
|
||||||
if (ctx.from.is_bot) return
|
if (ctx.chatMember.from.is_bot) return
|
||||||
if (ctx.chat.id !== botCfg.chat_id) return
|
if (ctx.chat.id !== botCfg.chat_id) return
|
||||||
|
|
||||||
ctx.i18n.useLocale(ctx.from.language_code || DEFAULT_LOCALE)
|
|
||||||
const { old_chat_member, new_chat_member } = ctx.chatMember
|
const { old_chat_member, new_chat_member } = ctx.chatMember
|
||||||
const chatMemberUpdateStatus = getChatMemberUpdateStatus(old_chat_member, new_chat_member)
|
const chatMemberUpdateStatus = getChatMemberUpdateStatus(old_chat_member, new_chat_member)
|
||||||
|
console.log(chatMemberUpdateStatus)
|
||||||
|
|
||||||
if (chatMemberUpdateStatus.joined) {
|
if (chatMemberUpdateStatus.joined) {
|
||||||
console.log(`New Chat member ${ctx.chatMember.from.id}:'+
|
const userInfo = await checkUserOnNewChatMember(ctx, db)
|
||||||
'${ctx.from.first_name} ${ctx.from.last_name}`)
|
console.log(
|
||||||
await checkUserOnNewChatMember(ctx, db, botCfg)
|
`New chat member ${ctx.chatMember.from.id}: `+
|
||||||
// TODO:
|
`${ctx.from.first_name} ${ctx.from.last_name}`
|
||||||
// const userInfo = await checkUserOnNewChatMember(ctx, db, botCfg)
|
)
|
||||||
//if (userInfo.isNewUser) { /* Some hello message? */ }
|
console.log("User info: ", userInfo)
|
||||||
} else if (chatMemberUpdateStatus.left || chatMemberUpdateStatus.kicked) {
|
ctx.reply("Welcome!") // TODO: Change message
|
||||||
console.log(`Chat member left ${ctx.chatMember.from.id}:'+
|
} else if (chatMemberUpdateStatus.left) {
|
||||||
'${ctx.from.first_name} ${ctx.from.last_name}`)
|
console.log(
|
||||||
|
`Chat member left ${ctx.chatMember.from.id}: `+
|
||||||
|
`${ctx.from.first_name} ${ctx.from.last_name}`
|
||||||
|
)
|
||||||
await onMemberLeftChat(ctx, db)
|
await onMemberLeftChat(ctx, db)
|
||||||
// TODO: /* POBEG S DURKI! */
|
ctx.reply("pobeg s durki :(") // TODO: Change message
|
||||||
}
|
}
|
||||||
await next()
|
await next()
|
||||||
})
|
})
|
||||||
|
@ -19,8 +19,8 @@ export interface CheckUserOut extends UserCheckedRestrictions {
|
|||||||
// Ignores the start command
|
// Ignores the start command
|
||||||
export const checkUser = async (
|
export const checkUser = async (
|
||||||
ctx: Ctx,
|
ctx: Ctx,
|
||||||
db: Kysely<Database>,
|
trx: Transaction<Database>,
|
||||||
cfg: BotConfig,
|
cfg?: BotConfig,
|
||||||
isMicChat?: boolean,
|
isMicChat?: boolean,
|
||||||
): Promise<CheckUserOut> => {
|
): Promise<CheckUserOut> => {
|
||||||
const out: CheckUserOut = {
|
const out: CheckUserOut = {
|
||||||
@ -32,9 +32,12 @@ export const checkUser = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.chat || !ctx.from) return out
|
if (!ctx.chat || !ctx.from) return out
|
||||||
|
if (cfg === undefined) {
|
||||||
|
isMicChat = false
|
||||||
|
} else {
|
||||||
isMicChat ??= ctx.chat.id === cfg.chat_id
|
isMicChat ??= ctx.chat.id === cfg.chat_id
|
||||||
|
}
|
||||||
|
|
||||||
await db.transaction().execute(async trx => {
|
|
||||||
const users = await trx.selectFrom('users')
|
const users = await trx.selectFrom('users')
|
||||||
.selectAll().where('tg_id', '=', ctx.from!.id).execute()
|
.selectAll().where('tg_id', '=', ctx.from!.id).execute()
|
||||||
if (users.length < 1) {
|
if (users.length < 1) {
|
||||||
@ -51,7 +54,7 @@ export const checkUser = async (
|
|||||||
out.isCaptchaSolved = out.isChatParticipant
|
out.isCaptchaSolved = out.isChatParticipant
|
||||||
} else {
|
} else {
|
||||||
const user = users[0]
|
const user = users[0]
|
||||||
const userRestrictions = await checkUserRestrictions(db, user)
|
const userRestrictions = await checkUserRestrictions(trx, user)
|
||||||
|
|
||||||
if (!user.is_chat_participant && isMicChat) {
|
if (!user.is_chat_participant && isMicChat) {
|
||||||
await trx.updateTable('users').set({
|
await trx.updateTable('users').set({
|
||||||
@ -65,11 +68,23 @@ export const checkUser = async (
|
|||||||
out.isChatParticipant = user.is_chat_participant || isMicChat
|
out.isChatParticipant = user.is_chat_participant || isMicChat
|
||||||
out.isCaptchaSolved = user.is_captcha_passed
|
out.isCaptchaSolved = user.is_captcha_passed
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const checkUserTrx = async (
|
||||||
|
ctx: Ctx,
|
||||||
|
db: Kysely<Database>,
|
||||||
|
cfg?: BotConfig,
|
||||||
|
isMicChat?: boolean,
|
||||||
|
): Promise<CheckUserOut> => {
|
||||||
|
let res: CheckUserOut
|
||||||
|
await db.transaction().execute(async trx => {
|
||||||
|
res = await checkUser(ctx, trx, cfg, isMicChat)
|
||||||
|
})
|
||||||
|
return res!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
interface CheckUserOnNewChatMemberOut extends CheckUserOut {
|
interface CheckUserOnNewChatMemberOut extends CheckUserOut {
|
||||||
@ -81,7 +96,6 @@ interface CheckUserOnNewChatMemberOut extends CheckUserOut {
|
|||||||
export const checkUserOnNewChatMember = async (
|
export const checkUserOnNewChatMember = async (
|
||||||
ctx: Filter<Ctx, "chat_member">,
|
ctx: Filter<Ctx, "chat_member">,
|
||||||
db: Kysely<Database> | Transaction<Database>,
|
db: Kysely<Database> | Transaction<Database>,
|
||||||
cfg: BotConfig
|
|
||||||
): Promise<CheckUserOnNewChatMemberOut> => {
|
): Promise<CheckUserOnNewChatMemberOut> => {
|
||||||
const out: CheckUserOnNewChatMemberOut = {
|
const out: CheckUserOnNewChatMemberOut = {
|
||||||
isBlocked: false,
|
isBlocked: false,
|
||||||
@ -95,13 +109,13 @@ export const checkUserOnNewChatMember = async (
|
|||||||
|
|
||||||
let userInfo: CheckUserOut
|
let userInfo: CheckUserOut
|
||||||
await db.transaction().execute(async trx => {
|
await db.transaction().execute(async trx => {
|
||||||
userInfo = await checkUser(ctx, trx, cfg, true)
|
userInfo = await checkUser(ctx, trx)
|
||||||
if (userInfo.isBlocked || userInfo.isNewUser) {
|
if (userInfo.isBlocked || userInfo.isNewUser) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await trx.updateTable('users').where('tg_id', '=', ctx.from.id).set({
|
await trx.updateTable('users').set({
|
||||||
is_chat_participant: true
|
is_chat_participant: true
|
||||||
}).execute()
|
}).where('tg_id', '=', ctx.from.id).execute()
|
||||||
})
|
})
|
||||||
userInfo = userInfo!
|
userInfo = userInfo!
|
||||||
|
|
||||||
@ -127,14 +141,16 @@ export const checkUserOnNewChatMember = async (
|
|||||||
out.expectedUserTgId = -1
|
out.expectedUserTgId = -1
|
||||||
} else {
|
} else {
|
||||||
const { expect_user_tg_id } = inviteLinksData[0]
|
const { expect_user_tg_id } = inviteLinksData[0]
|
||||||
out.isExpectedUserJoined = expect_user_tg_id === ctx.chatMember.from.id
|
out.isExpectedUserJoined = expect_user_tg_id == ctx.chatMember.from.id
|
||||||
out.expectedUserTgId = expect_user_tg_id
|
out.expectedUserTgId = expect_user_tg_id
|
||||||
await db.deleteFrom('invite_links').where('link', '=', invite_link).execute()
|
await db.deleteFrom('invite_links').where('link', '=', invite_link).execute()
|
||||||
await ctx.revokeChatInviteLink(invite_link)
|
await ctx.revokeChatInviteLink(invite_link)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!out.isExpectedUserJoined) {
|
if (!out.isExpectedUserJoined) {
|
||||||
await db.updateTable('users').where(eb => eb.or([
|
await db.updateTable('users').set({
|
||||||
|
is_banned: true
|
||||||
|
}).where(eb => eb.or([
|
||||||
eb('tg_id', '=', out.expectedUserTgId),
|
eb('tg_id', '=', out.expectedUserTgId),
|
||||||
eb('tg_id', '=', ctx.chatMember.from.id),
|
eb('tg_id', '=', ctx.chatMember.from.id),
|
||||||
])).execute()
|
])).execute()
|
||||||
|
Loading…
Reference in New Issue
Block a user