From 4076b4427daa11662c0153143da824e02d0f226b Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Tue, 27 Apr 2021 17:40:42 +0700 Subject: [PATCH] added working webhooks --- package.json | 1 + src/api/http/index.ts | 25 ++++++++-------------- src/api/http/middleware.ts | 33 ++++++++++++++++++++++++++++++ src/api/telegram/index.ts | 1 - src/index.ts | 2 +- src/service/telegram/index.ts | 32 +++++++++++++++++++++-------- src/service/telegram/types.ts | 3 +-- src/service/telegram/validation.ts | 5 ++--- yarn.lock | 18 ++++++++++++++++ 9 files changed, 89 insertions(+), 31 deletions(-) create mode 100644 src/api/http/middleware.ts diff --git a/package.json b/package.json index 83190af..dd914f1 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "socks-proxy-agent": "^5.0.0", "telegraf": "^4.3.0", "typescript": "^4.2.3", + "url": "^0.11.0", "winston": "^3.3.3", "yargs": "^17.0.0-candidate.10", "yup": "^0.32.9" diff --git a/src/api/http/index.ts b/src/api/http/index.ts index 0a7090c..ce10b0e 100644 --- a/src/api/http/index.ts +++ b/src/api/http/index.ts @@ -7,7 +7,8 @@ import logger from "../../service/logger"; import { TelegramService } from "../../service/telegram"; import http from "http"; import { WebhookConfig } from "../../config/types"; -import url, { URL } from "url"; +import { URL } from "url"; +import { corsMiddleware, errorMiddleware } from "./middleware"; export class HttpApi { app: Express; @@ -19,20 +20,9 @@ export class HttpApi { private webhook?: WebhookConfig ) { this.app = express(); + this.app.use(corsMiddleware); this.app.use(express.json()); this.app.use(express.urlencoded({ extended: false })); - this.app.use((req, res, next) => { - res.header("Access-Control-Allow-Origin", "*"); - res.header( - "Access-Control-Allow-Methods", - "GET, PUT, POST, DELETE, PATCH" - ); - res.header( - "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Type, Accept" - ); - next(); - }); this.app.use(loggerHttpMiddleware); this.app.use(bodyParser.json()); @@ -43,6 +33,8 @@ export class HttpApi { logger.info(`using webhook at ${url.pathname}`); this.app.post(url.pathname, this.handleWebhook); } + + this.app.use(errorMiddleware); } /** @@ -57,7 +49,8 @@ export class HttpApi { /** * Handles telegram webhooks */ - private async handleWebhook(req: Request, res: Response) { - return this.telegram.handleUpdate(req.body, res); - } + private handleWebhook = async (req: Request, res: Response) => { + logger.debug("got message via webhook", req.body); + await this.telegram.handleUpdate(req.body, res); + }; } diff --git a/src/api/http/middleware.ts b/src/api/http/middleware.ts new file mode 100644 index 0000000..bffdb78 --- /dev/null +++ b/src/api/http/middleware.ts @@ -0,0 +1,33 @@ +import { Request, Response } from "express"; +import { NextFunction } from "connect"; +import logger from "../../service/logger"; + +export const corsMiddleware = ( + req: Request, + res: Response, + next: NextFunction +) => { + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, PATCH"); + res.header( + "Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept" + ); + next(); +}; + +export const errorMiddleware = ( + err: Error, + req: Request, + res: Response, + next: NextFunction +) => { + logger.warn(`http error`, err); + logger.debug(`http error`, req, err); + + if (res.headersSent) { + return next(err); + } + + res.sendStatus(501); +}; diff --git a/src/api/telegram/index.ts b/src/api/telegram/index.ts index 01668b7..69df60e 100644 --- a/src/api/telegram/index.ts +++ b/src/api/telegram/index.ts @@ -1,5 +1,4 @@ import { TelegramService } from "../../service/telegram"; -import logger from "../../service/logger"; export class TelegramApi { constructor(private telegram: TelegramService) {} diff --git a/src/index.ts b/src/index.ts index 0bf416e..58de77e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import { HttpApi } from "./api/http"; async function main() { try { const config = prepareConfig(); - const telegram = new TelegramService(config.telegram); + const telegram = new TelegramService(config.telegram, config.webhook); const vkService = new VkService(config.vk); const telegramApi = new TelegramApi(telegram).listen(); diff --git a/src/service/telegram/index.ts b/src/service/telegram/index.ts index c016154..2140536 100644 --- a/src/service/telegram/index.ts +++ b/src/service/telegram/index.ts @@ -4,19 +4,20 @@ import logger from "../logger"; import { Response } from "express"; import { Update } from "typegram"; import loggerTgMiddleware from "../logger/tg"; +import { WebhookConfig } from "../../config/types"; // import SocksProxyAgent from 'socks-proxy-agent'; export class TelegramService { public readonly bot: Telegraf; - constructor(private props: TelegramConfig) { + constructor(private props: TelegramConfig, private webhook: WebhookConfig) { // const agent = (CONFIG.PROXY && new SocksProxyAgent(CONFIG.PROXY)) || null; - const options = { - channelMode: true, + const options: Partial> = { telegram: { + webhookReply: true, + apiMode: "bot", // agent, // TODO: add proxy support - webhookReply: !!props.webhookUrl, }, }; @@ -31,10 +32,25 @@ export class TelegramService { * Connects to telegram */ public async start() { - await this.bot.telegram.deleteWebhook().then( - () => this.bot.launch(), - () => this.bot.launch() - ); + if (this.webhook.enabled && this.webhook.url) { + await this.bot.telegram + .deleteWebhook() + .then(() => this.bot.telegram.setWebhook(this.webhook.url)) + .then(async () => { + const info = await this.bot.telegram.getWebhookInfo(); + if (!info.url) { + throw new Error(`telegram hasn't set webhook`); + } + + logger.info(`telegram started webhook at ${this.webhook.url}`); + }) + .catch(logger.warn); + } else { + await this.bot.telegram.deleteWebhook().then( + () => this.bot.launch(), + () => this.bot.launch() + ); + } logger.info("telegram service started"); } diff --git a/src/service/telegram/types.ts b/src/service/telegram/types.ts index 81dd67a..3b7a6e6 100644 --- a/src/service/telegram/types.ts +++ b/src/service/telegram/types.ts @@ -1,4 +1,3 @@ export interface TelegramConfig { - key: string - webhookUrl?: string + key: string; } diff --git a/src/service/telegram/validation.ts b/src/service/telegram/validation.ts index 038e18d..0b7a6c8 100644 --- a/src/service/telegram/validation.ts +++ b/src/service/telegram/validation.ts @@ -1,6 +1,5 @@ -import * as yup from 'yup'; +import * as yup from "yup"; export const telegramConfigSchema = yup.object().required().shape({ key: yup.string().required(), - webhookUrl: yup.string().notRequired(), -}) +}); diff --git a/yarn.lock b/yarn.lock index f62b651..67d53ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -864,11 +864,21 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.1" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + ramda@^0.27.1: version "0.27.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" @@ -1147,6 +1157,14 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"