Telegram quote bot
https://t.me/QuotLyBot
- JavaScript 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The timing middleware replaced ctx.telegram.callApi on every update:
ctx.telegram.oCallApi = ctx.telegram.callApi
ctx.telegram.callApi = (method, data = {}) => ctx.telegram.oCallApi(...)
ctx.telegram is one object shared by every update - it is bot.telegram -
and oCallApi is resolved when the wrapper runs, not when it is built. So on
the second update oCallApi points at the wrapper itself, and the next
Telegram API call recurses until the stack goes. Reproduced against the
installed telegraf: ctx.telegram is identical across contexts, and after two
updates `bot.telegram.callApi('getMe')` throws RangeError: Maximum call stack
size exceeded. It is wrapped once at startup now, against a bound reference,
and 5000 consecutive calls run flat. The logging went behind
BOT_API_TIMING=true; it used to print two lines per API call.
The middleware below it called next() without returning it and returned true
instead, so the rest of the chain ran detached from the promise Telegraf
awaits - anything that threw downstream escaped bot.catch. It did nothing
else and is gone.
Startup was silent about its own failures:
- Only the 'open' event of the Mongo connection was handled. A wrong
MONGODB_URI or a database that was not running left the process up,
healthy-looking, with no bot attached and nothing logged. Verified: it
now reports MongooseServerSelectionError and exits 1.
- Neither bot.launch() call had a .catch, so an invalid token rejected into
nowhere.
- index.js loaded './.env', which resolves against the working directory
rather than the file, so starting from anywhere else - what pm2 does with
a cwd, what systemd does by default - loaded no configuration at all and
left BOT_TOKEN undefined. It resolves against __dirname.
- bot.catch logged with console.log.
Dependencies: npm audit goes from 40 findings (5 critical, 20 high) to 5
(1 critical, 4 moderate), staying inside the lines telegraf 3 allows -
mongoose 5.13.23, got 11.8, sharp 0.35, uuid 11, dotenv 16, eslint 8 with
eslint-plugin-n in place of the deprecated eslint-plugin-node. sharp and
uuid were checked to still load and work under require.
Lint had never been run - eslint was a devDependency with no script - and it
found real defects besides style:
- `new Buffer(image, 'base64')` in handlers/quote.js, deprecated since Node
6 and a source of uninitialised memory when handed a number. The
eslint-disable above it named the old plugin's rule, so it had stopped
applying anyway.
- Three `.map()` calls used purely for their side effects, in rate.js,
language.js and helpers/tdlib, each building an array of undefined and
discarding it.
ecosystem.config.js had watch: true for both environments, so pm2 restarted
the production bot on any write under the project, .env included. It is off,
and ignore_watch covers the tdlib data directory and logs.
Added lint and lint:fix scripts, engines, and a CI workflow running lint, a
parse check over every file, and a load of the models, middlewares and all
five locales. bot.js itself is not loaded in CI because helpers/tdlib pulls
in airgram, which needs the native TDLib library - that is also why it
cannot be loaded here, on the original tree as much as this one.
Not done: telegraf 3 is end-of-life and the remaining audit findings need
either telegraf 4 (a rewrite, and telegraf-i18n 4 with it) or mongoose 9.
The mongoose advisory is a search-injection one; this code has no $where,
no mapReduce and no query value that is not either a literal or a Telegram
string used as an equality match.
|
||
| .forgejo/workflows | ||
| .github | ||
| database | ||
| handlers | ||
| helpers | ||
| locales | ||
| middlewares | ||
| utils | ||
| .editorconfig | ||
| .env.example | ||
| .eslintrc.json | ||
| .gitignore | ||
| bot.js | ||
| ecosystem.config.js | ||
| index.js | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||