diff --git a/package.json b/package.json index 97a48a2..5b441f8 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "@types/node": "^14.14.37", "express": "^4.17.1", + "handlebars": "^4.7.7", "http": "^0.0.1-security", "js-yaml": "^4.0.0", "morgan": "^1.10.0", @@ -33,6 +34,7 @@ }, "devDependencies": { "@types/express": "^4.17.11", + "@types/handlebars": "^4.1.0", "@types/ramda": "^0.27.39", "@types/winston": "^2.4.4", "@types/yargs": "^16.0.1", diff --git a/src/service/logger/tg.ts b/src/service/logger/tg.ts index 660a758..2feed04 100644 --- a/src/service/logger/tg.ts +++ b/src/service/logger/tg.ts @@ -2,9 +2,7 @@ import { MiddlewareFn } from "telegraf"; import logger from "./index"; const loggerTgMiddleware: MiddlewareFn = async (ctx, next) => { - logger.debug( - `received tg message from @${ctx.message.from.username}: ${ctx.message.text}` - ); + logger.debug(`received tg message`, ctx); await next().catch(logger.warn); }; diff --git a/src/service/telegram/index.ts b/src/service/telegram/index.ts index 4cec80f..e1cc8ed 100644 --- a/src/service/telegram/index.ts +++ b/src/service/telegram/index.ts @@ -4,6 +4,7 @@ import logger from "../logger"; import { Response } from "express"; import { Update } from "typegram"; import loggerTgMiddleware from "../logger/tg"; +import { ExtraReplyMessage } from "telegraf/typings/telegram-types"; // import SocksProxyAgent from 'socks-proxy-agent'; @@ -74,4 +75,16 @@ export class TelegramService { // TODO: test this.webhook.url with axios instead of 'true' return isWebhookEnabled && true; }; + + /** + * Sends simple message to channel + */ + public sendMessageToChan = async ( + channel: string, + message: string, + extra?: ExtraReplyMessage + ) => { + await this.bot.telegram.sendMessage(channel, message, extra); + return; + }; } diff --git a/src/service/template/index.ts b/src/service/template/index.ts index 6c613c2..312128c 100644 --- a/src/service/template/index.ts +++ b/src/service/template/index.ts @@ -6,9 +6,13 @@ import unified from "unified"; import { parse } from "yaml"; import toVFile from "to-vfile"; import path from "path"; +import hb from "handlebars"; -export class Template> { - public fields: T = {} as T; +export class Template< + F extends Record, + V extends Record +> { + public fields: F = {} as F; public template: string = ""; constructor(filename: string) { @@ -26,7 +30,7 @@ export class Template> { const file = toVFile.readSync(path.join(__dirname, "../../", filename)); const result = processor.processSync(file); - this.fields = result.data as T; + this.fields = result.data as F; this.template = result .toString() .replace(/^---\n(.*)---\n?$/gms, "") @@ -35,4 +39,8 @@ export class Template> { throw new Error(`Template: ${e.toString()}`); } } + + theme = (values: V) => { + return hb.compile(this.template)(values); + }; } diff --git a/src/service/vk/handlers/MessageNewHandler.ts b/src/service/vk/handlers/MessageNewHandler.ts index 44619b5..43d2143 100644 --- a/src/service/vk/handlers/MessageNewHandler.ts +++ b/src/service/vk/handlers/MessageNewHandler.ts @@ -3,8 +3,18 @@ import { MessageContext } from "vk-io"; import { NextMiddleware } from "middleware-io"; import logger from "../../logger"; import { ContextDefaultState } from "vk-io/lib/structures/contexts/context"; +import { UsersUserFull } from "vk-io/lib/api/schemas/objects"; -export class MessageNewHandler extends VkEventHandler { +interface Fields { + buttons: string[]; +} + +interface Values { + user: UsersUserFull; + text: string; +} + +export class MessageNewHandler extends VkEventHandler { public execute = async ( context: MessageContext, next: NextMiddleware @@ -23,8 +33,12 @@ export class MessageNewHandler extends VkEventHandler { `received message from ${from.first_name} ${from.last_name}: ${context.text}` ); - const template = this.template.template; - const fields = this.template.fields; + const parsed = this.template.theme({ + user: from, + text: context.text, + }); + + await this.telegram.sendMessageToChan(this.channel, parsed).catch(next); await next(); }; diff --git a/src/service/vk/handlers/VkEventHandler.ts b/src/service/vk/handlers/VkEventHandler.ts index d5e48b7..35d0df0 100644 --- a/src/service/vk/handlers/VkEventHandler.ts +++ b/src/service/vk/handlers/VkEventHandler.ts @@ -4,14 +4,18 @@ import { VkService } from "../index"; import { TelegramService } from "../../telegram"; import { Template } from "../../template"; -export class VkEventHandler { +export class VkEventHandler< + F extends Record = any, + V extends Record = any +> { public constructor( protected type: VkEvent, protected group: ConfigGroup, + protected channel: string, protected instance: GroupInstance, protected vk: VkService, protected telegram: TelegramService, - protected template: Template + protected template: Template ) {} public execute: ( diff --git a/src/service/vk/handlers/index.ts b/src/service/vk/handlers/index.ts index 94c6416..38af5b6 100644 --- a/src/service/vk/handlers/index.ts +++ b/src/service/vk/handlers/index.ts @@ -1,10 +1,22 @@ -import { VkEvent } from "../types"; +import { ConfigGroup, GroupInstance, VkEvent } from "../types"; import { VkEventHandler } from "./VkEventHandler"; import { MessageNewHandler } from "./MessageNewHandler"; import { StubHandler } from "./StubHandler"; +import { VkService } from "../index"; +import { TelegramService } from "../../telegram"; +import { Template } from "../../template"; -type DerivedHandler = typeof VkEventHandler; -interface Handler extends DerivedHandler {} +interface Handler { + new ( + type: VkEvent, + group: ConfigGroup, + channel: string, + instance: GroupInstance, + vk: VkService, + telegram: TelegramService, + template: Template + ): VkEventHandler; +} export const vkEventToHandler: Record = { [VkEvent.GroupJoin]: StubHandler, diff --git a/src/service/vk/index.ts b/src/service/vk/index.ts index b69a73a..51d9b7e 100644 --- a/src/service/vk/index.ts +++ b/src/service/vk/index.ts @@ -1,5 +1,5 @@ import { ConfigGroup, GroupInstance, VkConfig, VkEvent } from "./types"; -import { API, Upload, Updates } from "vk-io"; +import { API, Updates, Upload } from "vk-io"; import logger from "../logger"; import { Request, Response } from "express"; import { flatten, has, keys } from "ramda"; @@ -112,6 +112,7 @@ export class VkService { const handler = new vkEventToHandler[event]( event, group, + chan.id, instance, this, this.telegram, diff --git a/templates/message_new.md b/templates/message_new.md index de3af43..9f6fead 100644 --- a/templates/message_new.md +++ b/templates/message_new.md @@ -1,5 +1,9 @@ --- buttons: [link] --- - -{{ .FirstName }} {{ .LastName }} пишет: {{ .Text }} +{{!-- + use handlebars template here + available variables are: user, text + (see MessageNewHandler) +--}} +{{user.first_name}} {{user.last_name}} пишет: {{text}} diff --git a/yarn.lock b/yarn.lock index becc573..ebf30c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,6 +52,13 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/handlebars@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.1.0.tgz#3fcce9bf88f85fe73dc932240ab3fb682c624850" + integrity sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA== + dependencies: + handlebars "*" + "@types/lodash@^4.14.165": version "4.14.168" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" @@ -593,6 +600,18 @@ glob@^7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" +handlebars@*, handlebars@^4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -931,6 +950,11 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -1276,6 +1300,11 @@ socks@^2.3.3: ip "^1.1.5" smart-buffer "^4.1.0" +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -1405,6 +1434,11 @@ typescript@^4.2.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== +uglify-js@^3.1.4: + version "3.13.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.4.tgz#592588bb9f47ae03b24916e2471218d914955574" + integrity sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw== + unified@^9.1.0: version "9.2.1" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3" @@ -1544,6 +1578,11 @@ winston@*, winston@^3.3.3: triple-beam "^1.3.0" winston-transport "^4.4.0" +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"