1
0
Fork 0
mirror of https://github.com/muerwre/vk-tg-bot.git synced 2025-04-24 22:46:41 +07:00

added help command

This commit is contained in:
Fedor Katurov 2023-12-30 18:09:02 +07:00
parent 6d3f511807
commit 621b03fb70
12 changed files with 91 additions and 9 deletions

View file

@ -16,6 +16,8 @@ vk:
endpoint: /
groups: []
templates:
help: templates/help.md
help_admin: templates/help_admin.md
message_new: templates/message_new.md
wall_post_new: templates/post_new.md
group_join: templates/group_join.md

View file

@ -16,6 +16,8 @@ export class TelegramApi {
this.telegram.bot.command("config", this.dumpConfig);
this.telegram.bot.command("pop", this.pop);
this.telegram.bot.command("wtf", this.wtf);
this.telegram.bot.command("help", this.help);
this.telegram.bot.command("start", this.help);
return;
}
@ -104,6 +106,22 @@ export class TelegramApi {
return next();
};
/**
* Sends recent logs
*/
private help = async (ctx, next) => {
const username = ctx?.update?.message?.from?.username;
const isOwner = !!username && this.telegram.isOwner(`@${username}`);
const message = this.telegram.getHelpMessage(isOwner);
if (!message) {
console.warn("No templates for help found, skipping");
}
await ctx.reply(message);
return next();
};
/**
* Probes webhook url and falls back to polling mode on error
*/

View file

@ -33,7 +33,7 @@ const parseVal = (val?: string) => {
return parsed;
};
const escape = (val?: string) => val && val.replace(/([-.\[\]])/g, "\\$1");
const escape = (val?: string) => val && val.replace(/([-.\[\]\(\)])/g, "\\$1");
const deviate = (max: number, factor: number) => [
Math.round(max * (1 - factor)),
Math.round(max * (1 + factor)),
@ -86,7 +86,7 @@ const getRoute = async (
export const roll = async (text: string) => {
try {
const parts = text.match(/^\/roll\s?(\d+)?[-\s]?(\d+)?$/);
const parts = text.match(/^\/roll\s?(\d+)?[-\s,]?(\d+)?$/);
const result = await getRoute(parseVal(parts?.[1]), parseVal(parts?.[2]));
if (!result || !result?.id) {

View file

@ -16,6 +16,8 @@ export const defaultConfig: Config = {
groups: [],
},
templates: {
help: "templates/help.md",
help_admin: "templates/help_admin.md",
message_new: "templates/message_new.md",
wall_post_new: "templates/post_new.md",
group_join: "templates/group_join.md",

View file

@ -13,12 +13,18 @@ const data = fs.readFileSync(
"utf8"
);
const userConfig = yaml.load(data) as Config;
const userConfig = yaml.load<Config>(data);
const config =
(userConfig && merge(defaultConfig, userConfig)) || defaultConfig;
export default function prepareConfig() {
validateConfig(config);
config.telegram.templates = {
help: config.templates.help,
help_admin: config.templates.help_admin,
};
return config;
}

View file

@ -4,7 +4,8 @@ import { HttpConfig } from "../api/http/types";
import { LoggerConfig } from "../service/logger/types";
import { PostgresConfig } from "../service/db/postgres/types";
export type TemplateConfig = Record<VkEvent, string>;
export type TemplateConfig = Record<VkEvent, string> &
Partial<Record<"help" | "help_admin", string>>;
export interface Config extends Record<string, any> {
http: HttpConfig;

View file

@ -11,6 +11,8 @@ export const templateConfigSchema = object().required().shape({
wall_post_new: string().required(),
group_join: string().required(),
group_leave: string().required(),
help: string().optional(),
help_admin: string().optional(),
});
export const templateOptionalSchema = object().shape({

View file

@ -5,6 +5,7 @@ import { Response } from "express";
import { InputMediaPhoto, Update } from "typegram";
import loggerTgMiddleware from "../logger/tg";
import { ExtraReplyMessage } from "telegraf/typings/telegram-types";
import { Template } from "../template";
// import SocksProxyAgent from 'socks-proxy-agent';
@ -14,6 +15,9 @@ export class TelegramService {
public readonly bot: Telegraf;
public readonly webhook: WebhookConfig = {};
protected helpTemplate: Template<{}, {}> | undefined;
protected adminHelpTemplate: Template<{}, {}> | undefined;
constructor(private props: TelegramConfig) {
// const agent = (CONFIG.PROXY && new SocksProxyAgent(CONFIG.PROXY)) || null;
const options: Partial<Telegraf.Options<any>> = {
@ -29,6 +33,14 @@ export class TelegramService {
this.bot = new Telegraf(props.key, options);
this.bot.use(loggerTgMiddleware);
this.helpTemplate = props.templates?.help
? new Template(props.templates?.help)
: undefined;
this.adminHelpTemplate = props.templates?.help_admin
? new Template(props.templates?.help_admin)
: undefined;
process.once("SIGINT", () => this.stop("SIGINT"));
process.once("SIGTERM", () => this.stop("SIGTERM"));
}
@ -40,6 +52,18 @@ export class TelegramService {
* Connects to telegram
*/
public async start() {
if (!this.helpTemplate) {
console.warn(
"No help template specified, check templates.help in config"
);
}
if (!this.adminHelpTemplate) {
console.warn(
"No admin help template specified, check templates.help_admin in config"
);
}
if (this.isWebhookEnabled) {
await this.bot.telegram
.deleteWebhook()
@ -196,4 +220,16 @@ export class TelegramService {
);
}
});
public getHelpMessage = (forOwner?: boolean) => {
const template = forOwner
? this.adminHelpTemplate ?? this.helpTemplate
: this.helpTemplate;
if (!template) {
return;
}
return template?.theme({});
};
}

View file

@ -7,4 +7,8 @@ export interface TelegramConfig {
key: string;
owners?: string[];
webhook: WebhookConfig;
templates?: {
help?: string;
help_admin?: string;
};
}

View file

@ -16,10 +16,10 @@ const removeFrontmatter = () => (tree) => {
};
export class Template<
F extends Record<string, any>,
V extends Record<string, any>
Fields extends Record<string, any>,
Values extends Record<string, any>
> {
public fields: F = {} as F;
public fields: Fields = {} as Fields;
public template: string = "";
private readonly file: VFileCompatible = "";
@ -44,7 +44,7 @@ export class Template<
this.file = toVFile.readSync(path.join(__dirname, dir, filename));
const result = processor.processSync(this.file);
this.fields = result.data as F;
this.fields = result.data as Fields;
} catch (e) {
throw new Error(`Template: ${e?.toString()}`);
}
@ -54,7 +54,7 @@ export class Template<
* Themes the template with values, removes markdown from template.
* NOTE: text, that we'll insert into template, won't be used here
*/
public theme = (values: V, markdown?: boolean) => {
public theme = (values: Values, markdown?: boolean) => {
const processor = unified()
.use(stringify)
.use(frontmatter)

4
templates/help.md Normal file
View file

@ -0,0 +1,4 @@
Привет, вот, что я умею:
/roll - вернёт случайный маршрут
/roll 100 - вернёт маршрут около 100км
/roll 50-100 - вернёт маршрут от 50 до 100км

7
templates/help_admin.md Normal file
View file

@ -0,0 +1,7 @@
Привет, вот, что я умею:
/roll - вернёт случайный маршрут
/roll 100 - вернёт маршрут около 100км
/roll 50-100 - вернёт маршрут от 50 до 100км
/wtf - вышлет последние логи
/pop - вернёт последнее сообщение, принятое из ВК
/config - вернёт дамп конфига