Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions atall/atall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { Plugin } from "@utils/pluginBase";
import { Api } from "telegram";
import { getGlobalClient } from "@utils/globalClient";
import { getPrefixes } from "@utils/pluginManager";

// HTML转义函数
const htmlEscape = (text: string): string =>
text.replace(/[&<>"']/g, m => ({
'&': '&amp;', '<': '&lt;', '>': '&gt;',
'"': '&quot;', "'": '&#x27;'
}[m] || m));

// 消息分割函数(限制调整为4000字符)
const splitMessagesByMention = (mentions: string[], maxLength = 4000): string[] => {
const messages: string[] = [];
let currentMessage = "";

for (const mention of mentions) {
// 如果当前消息为空,直接添加第一个mention
if (currentMessage === "") {
currentMessage = mention;
}
// 如果添加下一个mention后不会超过限制,则添加空格和mention
else if (currentMessage.length + 1 + mention.length <= maxLength) {
currentMessage += " " + mention;
}
// 否则保存当前消息,开始新消息
else {
messages.push(currentMessage);
currentMessage = mention;
}
}

// 添加最后一个消息
if (currentMessage) {
messages.push(currentMessage);
}

return messages;
};

// 帮助文本
const help_text = `📢 <b>AtAll</b>

📝 <b>功能描述:</b>
• 一键@群组中的所有成员
• 自动处理无用户名用户
• 智能消息分割

🔧 <b>使用方法:</b>
• <code>${getPrefixes()[0]}atall</code> - @群组中的所有成员

⚠️ <b>注意事项:</b>
• 极大封号风险,后果自负
• 大群组中可能会生成很多条消息
• 一般来说你可以通过置顶消息来提醒所有人的`;

class AtAllPlugin extends Plugin {
description = help_text;

cmdHandlers = {
atall: async (msg: Api.Message) => {
try {
const client = await getGlobalClient();
if (!client) {
await msg.edit({ text: "❌ 无法获取客户端", parseMode: "html" });
return;
}

// 获取当前聊天
const chat = await msg.getChat();
if (!chat || !("id" in chat)) {
await msg.edit({ text: "❌ 此命令只能在群组中使用", parseMode: "html" });
return;
}

const chatId = chat.id;

// 显示处理中
const processingMsg = await msg.edit({
text: "🔄 正在获取群组成员列表...",
parseMode: "html"
});

// 获取所有群组成员
const participants = await client.getParticipants(chatId, {});

if (!participants || participants.length === 0) {
await processingMsg.edit({
text: "❌ 无法获取群组成员或群组为空",
parseMode: "html"
});
return;
}

// 生成@列表
let mentionList: string[] = [];

for (const participant of participants) {
// 跳过机器人自身
if (participant.bot) continue;

// 尝试获取用户实体
let userEntity;
try {
userEntity = await client.getEntity(participant.id);
} catch {
continue; // 跳过无法获取实体的用户
}

if (userEntity && "username" in userEntity && userEntity.username) {
// 有用户名的情况 - 直接使用@username
mentionList.push(`@${userEntity.username}`);
} else {
// 无用户名,使用mention链接
let displayName = "";
if ("firstName" in participant && participant.firstName) {
displayName = participant.firstName;
if ("lastName" in participant && participant.lastName) {
displayName += ` ${participant.lastName}`;
}
} else if ("title" in participant && participant.title) {
displayName = participant.title;
} else {
displayName = "";
}

// 使用Telegram mention链接
mentionList.push(`<a href="tg://user?id=${participant.id}">${htmlEscape(displayName)}</a>`);
}
}

if (mentionList.length === 0) {
await processingMsg.edit({
text: "❌ 没有可@的成员",
parseMode: "html"
});
return;
}

// 更新处理状态
await processingMsg.edit({
text: `🔄 正在生成@列表... (${mentionList.length} 个成员)`,
parseMode: "html"
});

// 分割消息(基于mention单位),限制调整为4000
const messageParts = splitMessagesByMention(mentionList, 4000);

// 删除处理中消息
await processingMsg.delete({ revoke: true }).catch(() => {});

// 发送所有消息部分
for (let i = 0; i < messageParts.length; i++) {
const part = messageParts[i];

// 在每条消息开头加上"@所有人:"标题
const messageContent = `<b>@所有人:</b>\n${part}`;

await client.sendMessage(chatId, {
message: messageContent,
parseMode: "html",
replyTo: i === 0 ? msg.id : undefined
});

// 为避免消息发送过快,添加短暂延迟
if (i < messageParts.length - 1) {
await new Promise(resolve => setTimeout(resolve, 500));
}
}

} catch (error: any) {
console.error("[AtAll Plugin] Error:", error);

let errorMessage = "❌ <b>发生错误:</b> ";
if (error.message?.includes("CHAT_ADMIN_REQUIRED")) {
errorMessage += "需要管理员权限来获取成员列表";
} else if (error.message?.includes("USER_NOT_PARTICIPANT")) {
errorMessage += "不是群组成员";
} else if (error.message?.includes("CHANNEL_PRIVATE")) {
errorMessage += "无法访问私有频道";
} else {
errorMessage += htmlEscape(error.message || "未知错误");
}

await msg.edit({
text: errorMessage,
parseMode: "html"
});
}
}
};
}

export default new AtAllPlugin();
8 changes: 6 additions & 2 deletions clean/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,14 @@ class CleanPlugin extends Plugin {
// 插件配置
private readonly PLUGIN_NAME = "clean";
private readonly PLUGIN_VERSION = "2.0.0";
public description: string = "";

// 清理进度状态
private cleanupStartTime: number = 0;
private blockedCleanupStartTime: number = 0;

// 命令处理器
private cmdHandlers: { [key: string]: (msg: Api.Message) => Promise<void> };

constructor() {
super();
Expand Down Expand Up @@ -410,7 +414,7 @@ class CleanPlugin extends Plugin {

let bannedUsers = await getBannedUsers(client, chatEntity);
if (!includeAll) {
bannedUsers = bannedUsers.filter(u => u.kickedBy === myId);
bannedUsers = bannedUsers.filter((u: any) => u.kickedBy === myId);
}

if (bannedUsers.length === 0) {
Expand All @@ -423,7 +427,7 @@ class CleanPlugin extends Plugin {
await this.editMessage(msg, `⚡ 正在解封 ${bannedUsers.length} 个实体...`);

const entityStats = { users: 0, channels: 0, chats: 0 };
bannedUsers.forEach(entity => {
bannedUsers.forEach((entity: any) => {
if (entity.type === 'user') entityStats.users++;
else if (entity.type === 'channel') entityStats.channels++;
else if (entity.type === 'chat') entityStats.chats++;
Expand Down
3 changes: 2 additions & 1 deletion diss/diss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class DissPlugin extends Plugin {
}
}
} catch (error) {
console.warn(`[diss] 第${attempt}次尝试失败:`, error.message);
const errorMessage = error instanceof Error ? error.message : String(error);
console.warn(`[diss] 第${attempt}次尝试失败:`, errorMessage);

// 如果不是最后一次尝试,等待一下再重试
if (attempt < 5) {
Expand Down
1 change: 1 addition & 0 deletions komari/komari.ts
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ async function handleKomariRequest(msg: Api.Message): Promise<void> {
return;
}

displayName = "Komari URL";
ConfigManager.set(CONFIG_KEYS.KOMARI_URL, configValue);
const displayValue = configValue;

Expand Down
2 changes: 1 addition & 1 deletion listusernames/listusernames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ListUsernamesPlugin extends Plugin {

// 调用Telegram API获取公开频道
const result = await client.invoke(
new Api.channels.GetAdminedPublicChannels()
new Api.channels.GetAdminedPublicChannels({})
);

if (!result.chats || result.chats.length === 0) {
Expand Down
7 changes: 5 additions & 2 deletions lu_bs/lu_bs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ class LuBsPlugin extends Plugin {
console.error(`[${this.PLUGIN_NAME}] 发送失败到 ${chatId}:`, error);

// 如果发送失败,可能是聊天不存在或没有权限,移除订阅
if (error.message?.includes("CHAT_WRITE_FORBIDDEN") ||
error.message?.includes("CHAT_NOT_FOUND")) {
if ((error as any).message?.includes("CHAT_WRITE_FORBIDDEN") ||
(error as any).message?.includes("CHAT_NOT_FOUND")) {
this.db.data.subscriptions = this.db.data.subscriptions.filter((id: string) => id !== chatId);
delete this.db.data.lastMessages[chatId];
await this.db.write();
Expand All @@ -174,6 +174,9 @@ class LuBsPlugin extends Plugin {
const chat = await msg.getChat();
const sender = await msg.getSender();

// 检查chat和sender是否存在
if (!chat || !sender) return false;

// 私聊总是允许
if (chat.className === "User") {
return true;
Expand Down
3 changes: 2 additions & 1 deletion oxost/oxost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getPrefixes } from "@utils/pluginManager";
import { Plugin } from "@utils/pluginBase";
import { Api } from "telegram";
import { getGlobalClient } from "@utils/globalClient";
import { Buffer } from "buffer";

// HTML转义
const htmlEscape = (text: string): string =>
Expand Down Expand Up @@ -141,7 +142,7 @@ class Ox0Plugin extends Plugin {

// 使用 Node.js 原生 FormData(无需 form-data 依赖)
const form = new globalThis.FormData();
form.append("file", new Blob([buffer], { type: "application/octet-stream" }), filename);
form.append("file", new Blob([new Uint8Array(buffer)], { type: "application/octet-stream" }), filename);
if (expires) form.append("expires", expires);
if (secret) form.append("secret", "1");
const headers = { 'User-Agent': 'curl/8.0.1' };
Expand Down
4 changes: 4 additions & 0 deletions plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
"url": "https://github.com/TeleBoxOrg/TeleBox_Plugins/blob/main/annualreport/annualreport.ts?raw=true",
"desc": "年度报告"
},
"atadmins": {
"url": "https://github.com/TeleBoxDev/TeleBox_Plugins/blob/main/atall/atall.ts?raw=true",
"desc": "一键艾特全部成员"
},
"atadmins": {
"url": "https://github.com/TeleBoxDev/TeleBox_Plugins/blob/main/atadmins/atadmins.ts?raw=true",
"desc": "一键艾特全部管理员"
Expand Down
5 changes: 4 additions & 1 deletion premium/premium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ class PremiumPlugin extends Plugin {

// 处理不同类型的participant
if (participant instanceof Api.ChannelParticipant) {
user = participant.user as Api.User;
if ((participant as any).user) {
user = (participant as any).user as Api.User;
}
continue;
} else if (participant instanceof Api.ChatParticipant) {
user = participant.userId as unknown as Api.User;
} else if (participant instanceof Api.User) {
Expand Down
16 changes: 11 additions & 5 deletions restore_pin/restore_pin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Plugin } from "@utils/pluginBase";
import { Api } from "telegram";
import { Api, types } from "telegram";
import { getGlobalClient } from "@utils/globalClient";

// HTML转义函数(必需)
Expand Down Expand Up @@ -41,8 +41,8 @@ class RestorePinPlugin extends Plugin {
new Api.channels.GetAdminLog({
channel: chatId,
q: "",
maxId: BigInt(0),
minId: BigInt(0),
maxId: 0,
minId: 0,
limit: 100,
eventsFilter: new Api.ChannelAdminLogEventsFilter({
pinned: true
Expand All @@ -62,7 +62,7 @@ class RestorePinPlugin extends Plugin {
for (const event of events.events) {
// 检查是否为取消置顶事件
if (event.action instanceof Api.ChannelAdminLogEventActionUpdatePinned) {
if (!event.action.message.pinned) { // 取消置顶
if (!(event.action.message instanceof Api.MessageEmpty) && !event.action.message.pinned) { // 取消置顶
const messageId = event.action.message.id;
messageIds.push(messageId);
}
Expand Down Expand Up @@ -173,10 +173,16 @@ class RestorePinPlugin extends Plugin {
}

// 检查管理员权限
const sender = await msg.getSender();
if (!sender) {
await msg.edit({ text: "❌ 无法获取发送者信息", parseMode: "html" });
return;
}

const participant = await client.invoke(
new Api.channels.GetParticipant({
channel: chat.id,
participant: await msg.getSender() as Api.InputUser
participant: sender as unknown as Api.InputUser
})
);

Expand Down
Loading
Loading