增加telegram支持

main
落雨楓 3 years ago
parent 1c496b41fd
commit 58b237cd4a

920
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -15,6 +15,7 @@
},
"license": "MIT",
"dependencies": {
"@types/node-telegram-bot-api": "^0.57.1",
"chokidar": "^3.5.1",
"decoders": "^1.25.3",
"handlebars": "^4.7.7",
@ -23,6 +24,7 @@
"lua-runner": "^2.0.3",
"micromatch": "^4.0.4",
"node-schedule": "^2.0.0",
"node-telegram-bot-api": "^0.58.0",
"pusher": "^3.0.1",
"pusher-js": "^5.1.1",
"request": "^2.88.2",

@ -1,6 +1,5 @@
import fs from "fs";
import Yaml from "yaml";
import micromatch from "micromatch";
import chokidar from 'chokidar';
import App from "./App";
@ -10,6 +9,10 @@ export interface Target {
identity: string;
}
/**
*
* @todo
*/
export class SubscribeManager {
private app: App;
private subscribeFile: string;
@ -52,43 +55,133 @@ export class SubscribeManager {
this.subscribeConfig = Yaml.parse(fs.readFileSync(this.subscribeFile, { encoding: 'utf-8' }));
}
/**
*
*/
private reloadSubscribeFile() {
this.loadSubscribeFile();
this.subscribeList = {};
for (let channelId in this.app.channel.channels) {
this.addChannel(channelId);
}
this.rebuildTree();
console.log('已重载Subscribe');
}
/**
*
*/
public rebuildTree() {
for (let robotId in this.subscribeConfig) {
let targetConf = this.subscribeConfig[robotId];
for (let targetType in targetConf) {
let targetTypeConf = targetConf[targetType];
for (let targetId in targetTypeConf) {
let subscribeList = targetTypeConf[targetId];
for (let channelId of subscribeList) {
this.addSubscribe(robotId, targetType, targetId, channelId);
}
}
}
}
}
/**
*
* @param robotId
* @param channelId
*/
public prepareTree(robotId: string, channelId: string) {
if (!(channelId in this.subscribeList)) {
this.subscribeList[channelId] = {};
}
if (!(robotId in this.subscribeList[channelId])) {
this.subscribeList[channelId][robotId] = [];
}
}
/**
*
* @param robotId ID
* @param targetType
* @param targetId ID
* @param channelId ID
*/
public addSubscribe(robotId: string, targetType: string, targetId: string, channelId: string) {
this.prepareTree(robotId, channelId);
this.subscribeList[channelId][robotId].push({
type: targetType,
identity: targetId
});
}
/**
*
* @param robotId ID
* @param targetType
* @param targetId ID
* @param channelId ID
*/
public removeSubscribe(robotId: string, targetType: string, targetId: string, channelId: string) {
if (this.subscribeList?.[channelId]?.[robotId]) {
this.subscribeList[channelId][robotId] = this.subscribeList[channelId][robotId].filter((target) => {
return (target.type !== targetType || targetId != targetId);
});
}
}
/**
*
* @param channelId ID
*/
public addChannel(channelId: string) {
this.subscribeList[channelId] = {};
for (let robotId in this.subscribeConfig) {
this.prepareTree(robotId, channelId); // 这里就先创建tree
let targetConf = this.subscribeConfig[robotId];
let matchedTargetList: Target[] = [];
for (let targetType in targetConf) {
let targetList = targetConf[targetType];
for (let targetIdentity in targetList) {
let matchList = targetList[targetIdentity];
if (micromatch.isMatch(channelId, matchList)) {
matchedTargetList.push({
let subscribeChannelList = targetList[targetIdentity];
if (subscribeChannelList.includes(channelId)) {
this.subscribeList[channelId][robotId].push({
type: targetType,
identity: targetIdentity
});
}
}
}
this.subscribeList[channelId][robotId] = matchedTargetList;
}
}
/**
*
* @param channelId ID
*/
public removeChannel(channelId: string) {
delete this.subscribeList[channelId];
}
/**
*
* @param channelId ID
* @param robotId ID
* @returns
*/
public getSubscriber(channelId: string, robotId: string): Target[] | null {
if (channelId in this.subscribeList && robotId in this.subscribeList[channelId]) {
return this.subscribeList[channelId][robotId];
let subscribers: Target[] = [];
// 先获取频道本身的订阅
if (this.subscribeList?.[channelId]?.[robotId]) {
subscribers.push(...this.subscribeList[channelId][robotId]);
}
// 获取父级(频道组)的订阅
if (channelId.includes('/')) {
let channelGroupPath = channelId.substring(0, channelId.lastIndexOf('/'));
if (this.subscribeList?.[channelGroupPath]?.[robotId]) {
subscribers.push(...this.subscribeList[channelGroupPath][robotId]);
}
}
if (subscribers.length > 0) {
return subscribers;
} else {
return null;
}

@ -44,11 +44,10 @@ export default class QQRobot implements Robot {
return;
}
return await this.doApiRequest('send_msg', {
bot: this.botQQ,
type: 1,
qq: user,
msg: message,
return await this.doApiRequest('send_private_msg', {
bot_id: this.botQQ,
user_id: user,
message: message,
});
}
@ -64,11 +63,10 @@ export default class QQRobot implements Robot {
return;
}
return await this.doApiRequest('send_msg', {
bot: this.botQQ,
type: 2,
group: group,
msg: message,
return await this.doApiRequest('send_group_msg', {
bot_id: this.botQQ,
group_id: group,
message: message,
});
}

@ -0,0 +1,85 @@
import Bluebird from "bluebird";
import TelegramBot from "node-telegram-bot-api";
import App from "../App";
import { Robot } from "../RobotManager";
import { Target } from "../SubscribeManager";
import { Utils } from "../Utils";
export type TelegramRobotConfig = {
token: string;
baseId?: string;
proxy?: string;
}
export default class TelegramRobot implements Robot {
private robotId: string;
bot: TelegramBot;
baseId?: string | undefined;
constructor(app: App, robotId: string, config: TelegramRobotConfig) {
this.robotId = robotId;
this.baseId = config.baseId;
let botOptions: any = {
polling: true
};
if (config.proxy) {
botOptions.request = {
proxy: config.proxy
};
}
this.bot = new TelegramBot(config.token, botOptions);
}
async initialize() {
await this.initCommands();
}
async initCommands() {
this.bot.setMyCommands([
{ command: 'start', description: '显示机器人简介信息' },
{ command: 'getchatid', description: '获取当前会话的id' }
], {
language_code: 'zh'
});
this.bot.onText(/^\/start/, async (message) => {
const chatId = message.chat.id;
this.bot.sendMessage(chatId, '这是异世界百科的推送机器人,目前还未开放加入其他群组的功能。');
});
this.bot.onText(/^\/getchatid/, async (message) => {
const chatId = message.chat.id;
this.bot.sendMessage(chatId, '当前会话ID' + chatId);
});
}
/**
*
*/
async sendToChat(chatId: number|number[], message: string) {
if(Array.isArray(chatId)){ //发送给多个群组的处理
for (let one of chatId) {
await this.sendToChat(one, message);
await Utils.sleep(100);
}
return;
}
return await this.bot.sendMessage(chatId, message);
}
/**
*
* @param targets
* @param message
*/
async sendMessage(targets: Target[], message: string): Promise<void> {
let chatIdList: number[] = [];
for (let target of targets) {
chatIdList.push(parseInt(target.identity));
}
await this.sendToChat(chatIdList, message);
}
}
Loading…
Cancel
Save