-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
223 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"extends": "standard"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: ci | ||
|
||
on: | ||
push: | ||
paths-ignore: | ||
- 'docs/**' | ||
- '*.md' | ||
pull_request: | ||
paths-ignore: | ||
- 'docs/**' | ||
- '*.md' | ||
|
||
jobs: | ||
test: | ||
permissions: | ||
contents: write | ||
pull-requests: write | ||
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3 | ||
with: | ||
lint: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,3 +128,5 @@ dist | |
.yarn/build-state.yml | ||
.yarn/install-state.gz | ||
.pnp.* | ||
.vscode/ | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,58 @@ | ||
# telegraf-save-md-reply | ||
# telegraf-safe-md-reply | ||
|
||
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) | ||
[![ci](https://github.com/Eomm/telegraf-safe-md-reply/actions/workflows/ci.yml/badge.svg)](https://github.com/Eomm/telegraf-safe-md-reply/actions/workflows/ci.yml) | ||
|
||
Reply safely with markdown! | ||
|
||
Are you tired of this error?! | ||
|
||
``` | ||
"type": "TelegramError", | ||
"message": "400: Bad Request: can't parse entities: Character '-' is reserved and must be escaped with the preceding '\\'", | ||
``` | ||
|
||
This package is for you! | ||
|
||
## Usage | ||
|
||
The `telegraf-safe-md-reply` middleware will add new methods to the `ctx` object: | ||
|
||
- `replyWithSafeMarkdownV2`: reply with markdown escaping all the reserved characters | ||
- `escapeMarkdown`: escape a string escaping all the reserved markdown characters | ||
|
||
```js | ||
const Telegraf = require('telegraf') | ||
const safeReply = require('telegraf-safe-md-reply') | ||
|
||
const bot = new Telegraf(process.env.BOT_TOKEN) | ||
|
||
bot.use(safeReply()) | ||
|
||
bot.command('test', async (ctx) => { | ||
// use the new method to reply | ||
ctx.replyWithSafeMarkdownV2('Hello-World(?)') | ||
|
||
// or escape manually: | ||
ctx.replyWithMarkdownV2(`*Hello*${ctx.escapeMarkdown('-World(?)')}`) | ||
}) | ||
``` | ||
|
||
## Options | ||
|
||
You can pass an object with options to the middleware: | ||
|
||
```js | ||
bot.use(safeReply({ | ||
methodName: 'safeReply' | ||
})) | ||
|
||
bot.command('test', (ctx) => { | ||
ctx.safeReply('Hello-World(?)') | ||
}) | ||
``` | ||
|
||
|
||
## License | ||
|
||
Copyright [Manuel Spigolon](https://github.com/Eomm), Licensed under [MIT](./LICENSE). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
'use strict' | ||
|
||
module.exports = function helpMiddleware ({ | ||
methodName = 'replyWithSafeMarkdownV2' | ||
} = {}) { | ||
return function middleware (ctx, next) { | ||
ctx[methodName] = function (text, extra) { | ||
return ctx.replyWithMarkdownV2(escapeMarkdown(text), extra) | ||
} | ||
|
||
ctx.escapeMarkdown = escapeMarkdown | ||
|
||
return next() | ||
} | ||
} | ||
|
||
// https://core.telegram.org/bots/api#markdownv2-style | ||
const SPECIAL_CHARS = [ | ||
'\\', '_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!' | ||
] | ||
|
||
const regex = new RegExp(`[${SPECIAL_CHARS.join('\\')}]`, 'ig') | ||
|
||
function escapeMarkdown (text) { | ||
return text.replace(regex, '\\$&') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "telegraf-safe-md-reply", | ||
"version": "0.0.0", | ||
"description": "Reply safely with markdown!", | ||
"main": "index.js", | ||
"scripts": { | ||
"lint": "standard", | ||
"lint:fix": "standard --fix", | ||
"test": "tap test/*.js" | ||
}, | ||
"keywords": [ | ||
"telegraf", | ||
"telegram", | ||
"bot-middleware", | ||
"middleware", | ||
"markdown", | ||
"reply" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Eomm/telegraf-safe-md-reply.git" | ||
}, | ||
"author": "Manuel Spigolon <[email protected]> (https://github.com/Eomm)", | ||
"funding": "https://github.com/Eomm/telegraf-safe-md-reply?sponsor=1", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/Eomm/telegraf-safe-md-reply/issues" | ||
}, | ||
"engines": { | ||
"node": ">=14" | ||
}, | ||
"homepage": "https://github.com/Eomm/telegraf-safe-md-reply#readme", | ||
"devDependencies": { | ||
"standard": "^17.1.0", | ||
"tap": "^16.3.9" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
'use strict' | ||
|
||
const { test } = require('tap') | ||
|
||
const helpMiddleware = require('../index') | ||
|
||
test('helpMiddleware', async t => { | ||
const ctx = {} | ||
const next = () => Promise.resolve() | ||
|
||
const middleware = helpMiddleware() | ||
|
||
await middleware(ctx, next) | ||
|
||
t.ok(ctx.replyWithSafeMarkdownV2, 'ctx.replyWithSafeMarkdownV2 exists') | ||
t.ok(ctx.escapeMarkdown, 'ctx.escapeMarkdown exists') | ||
}) | ||
|
||
test('helpMiddleware with custom methodName', async t => { | ||
const ctx = {} | ||
const next = () => Promise.resolve() | ||
|
||
const middleware = helpMiddleware({ methodName: 'replyWithMarkdown' }) | ||
|
||
await middleware(ctx, next) | ||
|
||
t.ok(ctx.replyWithMarkdown, 'ctx.replyWithMarkdown exists') | ||
t.ok(ctx.escapeMarkdown, 'ctx.escapeMarkdown exists') | ||
}) | ||
|
||
test('replyWithSafeMarkdownV2', async t => { | ||
const ctx = { | ||
replyWithMarkdownV2: (text, extra) => { | ||
// echo | ||
return text | ||
} | ||
} | ||
const next = () => Promise.resolve() | ||
|
||
const middleware = helpMiddleware() | ||
|
||
await middleware(ctx, next) | ||
|
||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar'), 'foo\\_bar') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo*bar'), 'foo\\*bar') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo[bar'), 'foo\\[bar') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo`bar'), 'foo\\`bar') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.replyWithSafeMarkdownV2('foo_bar*'), 'foo\\_bar\\*') | ||
}) | ||
|
||
test('escapeMarkdown', async t => { | ||
const ctx = {} | ||
const next = () => Promise.resolve() | ||
|
||
const middleware = helpMiddleware() | ||
|
||
await middleware(ctx, next) | ||
|
||
t.equal(ctx.escapeMarkdown('foo_bar'), 'foo\\_bar') | ||
t.equal(ctx.escapeMarkdown('foo*bar'), 'foo\\*bar') | ||
t.equal(ctx.escapeMarkdown('foo[bar'), 'foo\\[bar') | ||
t.equal(ctx.escapeMarkdown('foo`bar'), 'foo\\`bar') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
t.equal(ctx.escapeMarkdown('foo_bar*'), 'foo\\_bar\\*') | ||
}) |