mirror of
https://github.com/thedevs-network/the-guard-bot
synced 2025-08-29 05:07:49 +00:00
Add /permit, closes #72
This commit is contained in:
parent
e54719ad11
commit
8fcfea6bb9
@ -56,6 +56,7 @@ Command | Role | Available at | Description
|
||||
`/warn <reason>` | _Admin_ | _Groups_ | Warns the user.
|
||||
`/unwarn` | _Admin_ | _Everywhere_ | Removes the last warn from the user.
|
||||
`/nowarns` | _Admin_ | _Everywhere_ | Clears warns for the user.
|
||||
`/permit` | _Admin_ | _Everywhere_ | Permits the user to advertise once, within 24 hours.
|
||||
`/ban <reason>` | _Admin_ | _Groups_ | Bans the user from groups.
|
||||
`/unban` | _Admin_ | _Everywhere_ | Removes the user from ban list.
|
||||
`/user` | _Admin_ | _Everywhere_ | Shows the status of the user.
|
||||
|
@ -25,6 +25,7 @@ const adminCommands = `\
|
||||
<code>/warn <reason></code> - Warns the user.
|
||||
<code>/unwarn</code> - Removes the last warn from the user.
|
||||
<code>/nowarns</code> - Clears warns for the user.
|
||||
<code>/permit</code> - Permits the user to advertise once, within 24 hours.
|
||||
<code>/ban <reason></code> - Bans the user from groups.
|
||||
<code>/unban</code> - Removes the user from ban list.
|
||||
<code>/user</code> - Shows user's status and warns.
|
||||
|
26
handlers/commands/permit.ts
Normal file
26
handlers/commands/permit.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { displayUser, scheduleDeletion } from "../../utils/tg";
|
||||
import { html, lrm } from "../../utils/html";
|
||||
import { parse, strip } from "../../utils/cmd";
|
||||
import type { ExtendedContext } from "../../typings/context";
|
||||
import { permit } from "../../stores/user";
|
||||
|
||||
export = async (ctx: ExtendedContext) => {
|
||||
if (ctx.from?.status !== "admin") return null;
|
||||
|
||||
const { targets } = parse(ctx.message);
|
||||
if (targets.length !== 1) {
|
||||
return ctx
|
||||
.replyWithHTML("ℹ️ <b>Specify one user to permit.</b>")
|
||||
.then(scheduleDeletion());
|
||||
}
|
||||
|
||||
const permitted = await permit(strip(targets[0]), {
|
||||
by_id: ctx.from.id,
|
||||
date: new Date(),
|
||||
});
|
||||
|
||||
return ctx.replyWithHTML(html`
|
||||
🎟 ${lrm}${ctx.from.first_name} <b>permitted</b> ${displayUser(permitted)} to
|
||||
promote once within the next 24 hours!
|
||||
`);
|
||||
};
|
@ -9,7 +9,7 @@ const { isMaster, isWarnNotExpired } = require('../../utils/config');
|
||||
const { parse, strip } = require('../../utils/cmd');
|
||||
|
||||
// DB
|
||||
const { getUser } = require('../../stores/user');
|
||||
const { getUser, permit } = require('../../stores/user');
|
||||
|
||||
/** @param {Date} date */
|
||||
const formatDate = date =>
|
||||
@ -100,9 +100,19 @@ const getWarnsHandler = async ({ from, message, replyWithHTML }) => {
|
||||
formatDate(theUser.createdAt),
|
||||
);
|
||||
|
||||
return replyWithHTML(TgHtml.join('\n\n', [
|
||||
const permitS = permit.isValid(theUser.permit)
|
||||
// eslint-disable-next-line max-len
|
||||
? `🎟 ${(await getUser({ id: theUser.permit.by_id })).first_name}, ${formatDate(theUser.permit.date)}`
|
||||
: '';
|
||||
|
||||
const oneliners = TgHtml.join('\n', [
|
||||
header,
|
||||
firstSeen,
|
||||
permitS,
|
||||
].filter(isNotEmpty));
|
||||
|
||||
return replyWithHTML(TgHtml.join('\n\n', [
|
||||
oneliners,
|
||||
userWarns,
|
||||
banReason,
|
||||
].filter(isNotEmpty))).then(scheduleDeletion());
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* eslint new-cap: ["error", {"capIsNewExceptionPattern": "^(?:Action|jspack)\."}] */
|
||||
|
||||
import * as R from "ramda";
|
||||
import { html, lrm } from "../../utils/html";
|
||||
import { isAdmin, permit } from "../../stores/user";
|
||||
import { config } from "../../utils/config";
|
||||
import type { ExtendedContext } from "../../typings/context";
|
||||
import fetch from "node-fetch";
|
||||
import { isAdmin } from "../../stores/user";
|
||||
import { jspack } from "jspack";
|
||||
import { managesGroup } from "../../stores/group";
|
||||
import type { MessageEntity } from "telegraf/typings/telegram-types";
|
||||
@ -223,6 +224,13 @@ export = async (ctx: ExtendedContext, next) => {
|
||||
if (userToWarn.id === 777000) return next();
|
||||
if (await isAdmin(userToWarn)) return next();
|
||||
|
||||
if (await permit.revoke(userToWarn)) {
|
||||
await ctx.replyWithHTML(html`
|
||||
${lrm}${userToWarn.first_name} used 🎟 permit!
|
||||
`);
|
||||
return next();
|
||||
}
|
||||
|
||||
ctx.deleteMessage().catch(() => null);
|
||||
return ctx.warn({
|
||||
admin: ctx.botInfo!,
|
||||
|
@ -3,11 +3,12 @@
|
||||
const R = require('ramda');
|
||||
const { optional, passThru } = require('telegraf');
|
||||
|
||||
const { permit } = require('../../stores/user');
|
||||
|
||||
const { html, lrm } = require('../../utils/html');
|
||||
const { excludeLinks = [] } = require('../../utils/config').config;
|
||||
|
||||
if (excludeLinks === false || excludeLinks === '*') {
|
||||
|
||||
/** @type { import('../../typings/context').GuardMiddlewareFn } */
|
||||
module.exports = passThru();
|
||||
return;
|
||||
}
|
||||
@ -46,7 +47,12 @@ const pred = R.allPass([
|
||||
]);
|
||||
|
||||
/** @param { import('../../typings/context').ExtendedContext } ctx */
|
||||
const handler = ctx => {
|
||||
const handler = async (ctx, next) => {
|
||||
if (await permit.revoke(ctx.from)) {
|
||||
await ctx.replyWithHTML(html`${lrm}${ctx.from.first_name} used 🎟 permit!`);
|
||||
return next();
|
||||
}
|
||||
|
||||
ctx.deleteMessage().catch(() => null);
|
||||
return ctx.warn({
|
||||
admin: ctx.botInfo,
|
||||
|
@ -1,9 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef { { id: number } | { username: string } } UserQuery
|
||||
* @exports UserQuery
|
||||
*/
|
||||
|
||||
// Utils
|
||||
const { strip } = require('../utils/cmd');
|
||||
|
||||
const Datastore = require('nedb-promise');
|
||||
const ms = require('millisecond');
|
||||
const R = require('ramda');
|
||||
|
||||
const User = new Datastore({
|
||||
@ -117,10 +123,36 @@ const unban = ({ id }) =>
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* @param {UserQuery} user
|
||||
*/
|
||||
const permit = (user, { by_id, date }) =>
|
||||
User.update(
|
||||
user,
|
||||
{ $set: { permit: { by_id, date } } },
|
||||
{ returnUpdatedDocs: true },
|
||||
).then(getUpdatedDocument);
|
||||
|
||||
/**
|
||||
* @param {UserQuery} user
|
||||
*/
|
||||
permit.revoke = (user) =>
|
||||
User.update(
|
||||
{ permit: { $exists: true }, ...strip(user) },
|
||||
{ $unset: { permit: true } },
|
||||
{ returnUpdatedDocs: true },
|
||||
).then(getUpdatedDocument);
|
||||
|
||||
permit.isValid = (p) => Date.now() - ms('24h') < p?.date;
|
||||
|
||||
const warn = ({ id }, reason, { amend }) =>
|
||||
User.update(
|
||||
{ id, $not: { status: 'admin' } },
|
||||
{ $pop: { warns: +!!amend }, $push: { warns: reason } },
|
||||
{
|
||||
$pop: { warns: +!!amend },
|
||||
$push: { warns: reason },
|
||||
$unset: { permit: true },
|
||||
},
|
||||
{ returnUpdatedDocs: true },
|
||||
).then(getUpdatedDocument);
|
||||
|
||||
@ -145,6 +177,7 @@ module.exports = {
|
||||
getUser,
|
||||
isAdmin,
|
||||
nowarns,
|
||||
permit,
|
||||
unadmin,
|
||||
unban,
|
||||
unwarn,
|
||||
|
Loading…
x
Reference in New Issue
Block a user