Skip to content

Commit 45cb897

Browse files
authored
merge: #169 from feat/better-admin-log
2 parents 970a12e + efcd382 commit 45cb897

File tree

16 files changed

+2299
-1673
lines changed

16 files changed

+2299
-1673
lines changed

.circleci/config.yml

Lines changed: 0 additions & 26 deletions
This file was deleted.

.eslintrc.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@
1818
"plugin:@typescript-eslint/recommended-requiring-type-checking",
1919
"plugin:@typescript-eslint/eslint-recommended",
2020
"plugin:@typescript-eslint/recommended",
21-
"plugin:prettier/recommended",
22-
"prettier/@typescript-eslint"
21+
"prettier"
2322
],
2423
"rules": {
25-
"@typescript-eslint/ban-ts-ignore": "warn",
24+
"@typescript-eslint/ban-ts-comment": "warn",
2625
"@typescript-eslint/camelcase": "off",
2726
"@typescript-eslint/explicit-function-return-type": "off",
2827
"@typescript-eslint/no-floating-promises": "error",

.github/workflows/checks.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Checks
2+
on:
3+
push:
4+
branches:
5+
- develop
6+
pull_request:
7+
branches:
8+
- develop
9+
10+
jobs:
11+
release:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v3
16+
- run : npm ci
17+
- name: Lint
18+
run: npm run -s lint
19+
- name: Typecheck
20+
run: npm run -s typecheck

bot/context.js

Lines changed: 0 additions & 55 deletions
This file was deleted.

bot/context.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import warn from "../actions/warn";
2+
import ban from "../actions/ban";
3+
import batchBan from "../actions/batchBan";
4+
import { scheduleDeletion } from "../utils/tg";
5+
6+
import { config } from "../utils/config";
7+
import { ContextExtensions } from "../typings/context";
8+
9+
const {
10+
warnInlineKeyboard,
11+
chats = {},
12+
deleteWarnsAfter = false,
13+
deleteBansAfter = false,
14+
} = config;
15+
16+
const normalisedDeleteWarnsAfter =
17+
typeof deleteWarnsAfter === "object"
18+
? deleteWarnsAfter
19+
: { auto: deleteWarnsAfter, manual: deleteWarnsAfter };
20+
21+
const reply_markup = { inline_keyboard: warnInlineKeyboard };
22+
23+
export const extn: ContextExtensions = {
24+
async ban({ admin, reason, userToBan, msg }) {
25+
const banMessage = await ban({ admin, reason, userToBan });
26+
27+
const done = await this.loggedReply(banMessage, msg).then(
28+
scheduleDeletion(deleteBansAfter),
29+
);
30+
31+
if (msg)
32+
this.telegram
33+
.deleteMessage(msg.chat.id, msg.message_id)
34+
.catch(() => null);
35+
36+
return done;
37+
},
38+
39+
async batchBan({ admin, reason, targets }) {
40+
const banMessage = await batchBan({ admin, reason, targets });
41+
return this.loggedReply(banMessage).then(scheduleDeletion(deleteBansAfter));
42+
},
43+
44+
async warn({ admin, amend, reason, userToWarn, mode, msg }) {
45+
const warnMessage = await warn({ admin, amend, reason, userToWarn });
46+
47+
const done = await this.loggedReply(warnMessage, msg, {
48+
reply_markup,
49+
}).then(scheduleDeletion(normalisedDeleteWarnsAfter[mode]));
50+
51+
if (msg)
52+
this.telegram
53+
.deleteMessage(msg.chat.id, msg.message_id)
54+
.catch(() => null);
55+
56+
return done;
57+
},
58+
59+
async loggedReply(html, reply, extra) {
60+
if (chats.adminLog) {
61+
const msg =
62+
reply &&
63+
(await this.telegram.forwardMessage(
64+
chats.adminLog,
65+
reply.chat.id,
66+
reply.message_id,
67+
));
68+
this.telegram
69+
// @ts-expect-error sendMessage is monkeypatched to accept TgHtml
70+
.sendMessage(chats.adminLog, html, {
71+
parse_mode: "HTML",
72+
reply_to_message_id: msg?.message_id,
73+
})
74+
.catch(() => null);
75+
}
76+
// @ts-expect-error sendMessage is monkeypatched to accept TgHtml
77+
return this.replyWithHTML(html, extra);
78+
},
79+
};

bot/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ Object.defineProperty(bot.context, "botInfo", {
2525

2626
// cyclic dependency
2727
// bot/index requires context requires actions/warn requires bot/index
28-
Object.assign(bot.context, require('./context'));
28+
Object.assign(bot.context, require('./context').extn);

example.config.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ const config = {
4343

4444
chats: {
4545

46+
/**
47+
* @type {(number | false)}
48+
* Chat to send member (un)ban/(un)warn/report notifications and
49+
* relevant messages to. Pass false to disable this feature.
50+
*/
51+
adminLog: false,
52+
4653
/**
4754
* @type {(number | false)}
4855
* Chat to send member join/leave notifications to.
@@ -56,6 +63,13 @@ const config = {
5663
* Pass false to disable this feature.
5764
*/
5865
report: false,
66+
67+
/**
68+
* @type {(true | false)}
69+
* Disable whether clicking on `[Report handled]` deletes the
70+
* report chat message.
71+
*/
72+
noReportChatDeletion: false,
5973
},
6074

6175
/**
@@ -67,7 +81,7 @@ const config = {
6781

6882
deleteCustom: {
6983
longerThan: 450, // UTF-16 characters
70-
after: '20 minutes'
84+
after: '20 minutes',
7185
},
7286

7387
/**

handlers/commands/ban.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ const banHandler = async (ctx) => {
5252
return ctx.replyWithHTML('ℹ️ <b>Can\'t ban other admins.</b>');
5353
}
5454

55-
if (ctx.message.reply_to_message) {
56-
ctx.deleteMessage(ctx.message.reply_to_message.message_id)
57-
.catch(() => null);
58-
}
59-
6055
if (!flags.has('amend') && userToBan.status === 'banned') {
6156
return ctx.replyWithHTML(
6257
html`🚫 ${displayUser(userToBan)} <b>is already banned.</b>`,
@@ -67,6 +62,7 @@ const banHandler = async (ctx) => {
6762
admin: ctx.from,
6863
reason: '[' + ctx.chat.title + '] ' + await substom(reason),
6964
userToBan,
65+
msg: ctx.message.reply_to_message
7066
});
7167
};
7268

handlers/commands/report.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,32 @@ const reportHandler = async ctx => {
2424
// Ignore monospaced reports
2525
if (ctx.message.entities?.[0]?.type === 'code' && ctx.message.entities[0].offset === 0)
2626
return null;
27-
if (!ctx.message.reply_to_message) {
27+
const reply = ctx.message.reply_to_message;
28+
if (!reply) {
2829
await ctx.deleteMessage();
2930
return ctx.replyWithHTML(
30-
'ℹ️ <b>Reply to message you\'d like to report</b>',
31+
'ℹ️ <b>Reply to the message you\'d like to report</b>',
3132
).then(scheduleDeletion());
3233
}
3334
const admins = (await ctx.getChatAdministrators())
3435
.filter(isQualified)
3536
.map(adminMention);
3637
// eslint-disable-next-line max-len
37-
const s = TgHtml.tag`❗️ <b>Message from ${link(ctx.message.reply_to_message.from)} was reported to the admins</b>.${TgHtml.join('', admins)}`;
38+
const s = TgHtml.tag`❗️ <b>Message from ${link(reply.from)} was reported to the admins</b>.${TgHtml.join('', admins)}`;
3839
const report = await ctx.replyWithHTML(s, {
39-
reply_to_message_id: ctx.message.reply_to_message.message_id,
40+
reply_to_message_id: reply.message_id,
4041
});
4142
if (chats.report) {
43+
const msg = await ctx.telegram.forwardMessage(chats.report, ctx.chat.id, reply.message_id);
4244
await ctx.deleteMessage();
4345
await ctx.telegram.sendMessage(
4446
chats.report,
4547
TgHtml.tag`❗️ ${link(ctx.from)} reported <a href="${msgLink(
46-
ctx.message.reply_to_message,
47-
)}">a message</a> from ${link(ctx.message.reply_to_message.from)} in ${ctx.chat.title}!`,
48+
reply,
49+
)}">a message</a> from ${link(reply.from)} in ${ctx.chat.title}!`,
4850
{
4951
parse_mode: 'HTML',
52+
reply_to_message_id: msg.message_id,
5053
reply_markup: { inline_keyboard: [ [ {
5154
text: '✔️ Handled',
5255
callback_data: Cmd.stringify({

handlers/commands/warn.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,13 @@ const warnHandler = async (ctx) => {
4545
.then(scheduleDeletion());
4646
}
4747

48-
if (ctx.message.reply_to_message) {
49-
ctx.deleteMessage(ctx.message.reply_to_message.message_id)
50-
.catch(() => null);
51-
}
52-
5348
return ctx.warn({
5449
admin: ctx.from,
5550
amend: flags.has('amend'),
5651
reason: '[' + ctx.chat.title + '] ' + await substom(reason),
5752
userToWarn,
5853
mode: 'manual',
54+
msg: ctx.message.reply_to_message,
5955
});
6056
};
6157

0 commit comments

Comments
 (0)