-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.ts
168 lines (159 loc) Β· 4.56 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import { HOUR, MINUTE } from "@std/datetime/constants";
import { Bot, InputFile } from "grammy/mod.ts";
import { APP_VERSION, Client, errors } from "@mtkruto/mtkruto";
import { display } from "./misc.ts";
import env from "./env.ts";
const client = new Client({
apiId: env.API_ID,
apiHash: env.API_HASH,
appVersion: `${APP_VERSION} (noraids${env.APP_VERSION_SUFFIX})`,
});
const bot = new Bot(env.BOT_TOKEN);
const startTime = new Date().toUTCString();
let timeout: ReturnType<typeof setTimeout> | null = null;
const minutes = 15;
client.on("connectionState", (ctx) => {
if (ctx.connectionState != "ready") return;
if (timeout != null) clearTimeout(timeout);
console.log(`stopping the client in ${minutes} minutes`);
timeout = setTimeout(
() => client.disconnect().then(() => console.log("stopped the client")),
minutes * MINUTE,
);
});
async function disableJoinRequests(username: string) {
if (!client.connected) {
await client.start();
}
try {
await client.disableJoinRequests(username);
console.log("disabled join requests in", username);
return true;
} catch (err) {
if (err instanceof errors.ChatNotModified) {
console.log("join requests were already disabled in", username);
return false;
} else {
throw err;
}
}
}
async function enableJoinRequests(username: string) {
if (!client.connected) {
await client.start();
}
try {
await client.enableJoinRequests(username);
console.log("enabled join requests in", username);
return true;
} catch (err) {
if (err instanceof errors.ChatNotModified) {
console.log("join requests were already enabled in", username);
return false;
} else {
throw err;
}
}
}
const timestamps = new Map<string, number[]>();
const indexes = new Map<string, number>();
const limit = 30;
const timeframe = 1 * HOUR;
function incr(username: string) {
username = username.toLowerCase();
const timestamps_ = timestamps.get(username) ?? (() => {
const v = new Array<number>(limit).fill(0);
timestamps.set(username, v);
return v;
})();
const index = indexes.get(username) ?? 0;
const current = timestamps_[index];
if (Date.now() - current <= timeframe) {
return timestamps_.filter((v) => v).sort((a, b) => a - b);
} else {
timestamps_[index] = Date.now();
}
indexes.set(username, (index + 1) % timestamps_.length);
return null;
}
function reset(username: string) {
username = username.toLowerCase();
timestamps.delete(username);
indexes.delete(username);
}
bot.catch((ctx) => {
const text = Deno.inspect(ctx.error, {
colors: false,
depth: Infinity,
iterableLimit: Infinity,
});
if (text.length <= 4096) {
bot.api.sendMessage(
env.LOG_CHAT_ID,
text,
{ entities: [{ type: "code", offset: 0, length: text.length }] },
)
.catch(console.error);
} else {
bot.api.sendDocument(env.LOG_CHAT_ID, new InputFile(text, "error"))
.catch(console.error);
}
});
bot.chatType("supergroup")
.on("chat_member", async (ctx, next) => {
if (ctx.chat.id == env.LOG_CHAT_ID) return await next();
const username = ctx.chat.username;
if (!username) {
return;
}
if (
ctx.chatMember.old_chat_member.status != "left" ||
ctx.chatMember.new_chat_member.status != "member"
) {
return;
}
const result = incr(username);
if (result != null) {
const then = performance.now();
const enabled = await enableJoinRequests(username);
reset(username);
if (enabled) {
await ctx.reply(
`Join requests enabled in ${performance.now() - then}ms.`,
);
await ctx.reply(`<b>JOIN TIMESTAMPS</b>\n${display(result)}`, {
parse_mode: "HTML",
});
} else {
await ctx.reply("Join requests are already enabled.");
}
}
});
const logChat = bot.filter((ctx) => ctx.chat?.id === env.LOG_CHAT_ID);
logChat.command(
"status",
async (ctx) => {
await ctx.reply(`Up since ${startTime}.`);
},
);
logChat.command("disable", async (ctx) => {
const username = ctx.match;
if (!username) return;
const then = performance.now();
const result = await disableJoinRequests(username);
if (result) {
await ctx.reply(
`Join requests disabled for ${username} in ${
performance.now() - then
}ms.`,
);
} else {
await ctx.reply(`Join requests are already disabled for ${username}.`);
}
});
await client.importAuthString(env.AUTH_STRING);
await client.start();
await bot.start({
drop_pending_updates: true,
allowed_updates: ["chat_member", "message"],
});