Skip to content

Commit

Permalink
feat(body): add entities formatting support (#250)
Browse files Browse the repository at this point in the history
  • Loading branch information
BubuMVX authored Oct 16, 2024
1 parent a553a6b commit 7a7e88b
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 1 deletion.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,22 @@ const menuTemplate = new MenuTemplate<MyContext>((ctx) => {
});
```

### Can I use `entities` in the message body?

Also see: [`grammyjs/parse-mode`](https://github.com/grammyjs/parse-mode)

```ts
import { bold, fmt, underline } from '@grammyjs/parse-mode';

const menu = new MenuTemplate<MyContext>(async () => {
const message = fmt`${bold(underline('Hello world!'))}`;
return {
text: message.text,
entities: message.entities,
};
});
```

### Can the menu body be some media?

The menu body can be an object containing `media` and `type` for media.
Expand Down
32 changes: 32 additions & 0 deletions source/body.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ const EXAMPLE_TEXTS: ReadonlyArray<string | TextBody> = [
text: 'Hello World',
disable_web_page_preview: true,
},
{
text: 'Hello world!',
entities: [
{
type: 'bold',
offset: 0,
length: 5,
},
{
type: 'italic',
offset: 6,
length: 5,
},
],
},
];

const EXAMPLE_MEDIA: readonly MediaBody[] = [
Expand All @@ -130,6 +145,23 @@ const EXAMPLE_MEDIA: readonly MediaBody[] = [
text: 'whatever',
parse_mode: 'Markdown',
},
{
media: 'whatever',
type: 'photo',
text: 'Hello world!',
entities: [
{
type: 'bold',
offset: 0,
length: 5,
},
{
type: 'italic',
offset: 6,
length: 5,
},
],
},
];

const EXAMPLE_LOCATION: readonly LocationBody[] = [
Expand Down
5 changes: 4 additions & 1 deletion source/body.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {InputFile} from 'grammy';
import type {
LabeledPrice, Location, ParseMode, Venue,
LabeledPrice, Location, MessageEntity, ParseMode, Venue,
} from 'grammy/types';
import type {ReadonlyDeep} from 'type-fest';
import {hasTruthyKey, isObject} from './generic-types.js';
Expand All @@ -24,6 +24,7 @@ export type MediaType = typeof MEDIA_TYPES[number];

export type TextBody = {
readonly text: string;
readonly entities?: MessageEntity[];
readonly parse_mode?: ParseMode;
readonly disable_web_page_preview?: boolean;
};
Expand All @@ -34,6 +35,7 @@ export type MediaBody = {

/** Caption */
readonly text?: string;
readonly entities?: MessageEntity[];
readonly parse_mode?: ParseMode;
};

Expand Down Expand Up @@ -160,6 +162,7 @@ export function isInvoiceBody(body: unknown): body is InvoiceBody {
&& typeof invoice.description === 'string';
}

// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
export function getBodyText(body: TextBody | string): string {
return typeof body === 'string' ? body : body.text;
}
4 changes: 4 additions & 0 deletions source/send-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ export function generateEditMessageIntoMenuFunction<Context>(
type: body.type,
media: body.media,
caption: body.text,
caption_entities: body.entities,
parse_mode: body.parse_mode,
},
createGenericOther(keyboard, other),
Expand Down Expand Up @@ -401,12 +402,14 @@ export function generateEditMessageIntoMenuFunction<Context>(
}

function createTextOther(
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
body: string | TextBody,
keyboard: InlineKeyboard,
base: Readonly<Record<string, unknown>>,
) {
return {
...base,
entities: typeof body === 'string' ? undefined : body.entities,
parse_mode: typeof body === 'string' ? undefined : body.parse_mode,
disable_web_page_preview: typeof body !== 'string'
&& body.disable_web_page_preview,
Expand All @@ -426,6 +429,7 @@ function createSendMediaOther(
...base,
parse_mode: body.parse_mode,
caption: body.text,
caption_entities: body.entities,
reply_markup: {
inline_keyboard: keyboard.map(o => [...o]),
},
Expand Down
3 changes: 3 additions & 0 deletions test/menu-middleware/reply-to-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ await test('menu-middleware reply-to-context replies main menu', async t => {
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -67,6 +68,7 @@ await test('menu-middleware reply-to-context replies main menu explicitly', asyn
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -105,6 +107,7 @@ await test('menu-middleware reply-to-context replies submenu', async t => {
strictEqual(text, 'submenu');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down
9 changes: 9 additions & 0 deletions test/send-menu/context-edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ await test('context-edit text reply when not a callback query', async t => {
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand All @@ -36,6 +37,7 @@ await test('context-edit text reply when no message on callback query', async t
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -65,6 +67,7 @@ await test('context-edit text edit when message is a text message', async t => {
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -106,6 +109,7 @@ await test('context-edit text reply when message is a media message', async t =>
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -151,6 +155,7 @@ await test('context-edit text reply when message is a media message but fails wi
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -193,6 +198,7 @@ await test('context-edit media reply when not a callback query', async t => {
strictEqual(photo, 'whatever');
deepStrictEqual(other, {
caption: undefined,
caption_entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -227,6 +233,7 @@ await test('context-edit media reply when text message', async t => {
strictEqual(photo, 'whatever');
deepStrictEqual(other, {
caption: undefined,
caption_entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -375,6 +382,7 @@ await test('context-edit text edit without webpage preview', async () => {
async editMessageText(_text, other) {
deepStrictEqual(other, {
disable_web_page_preview: true,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -409,6 +417,7 @@ await test('context-edit text edit with parse mode', async () => {
async editMessageText(_text, other) {
deepStrictEqual(other, {
disable_web_page_preview: undefined,
entities: undefined,
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [],
Expand Down
1 change: 1 addition & 0 deletions test/send-menu/context-reply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ await test('context-reply media', async t => {
strictEqual(media, 'whatever');
deepStrictEqual(other, {
caption: undefined,
caption_entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down
2 changes: 2 additions & 0 deletions test/send-menu/context-resend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ await test('context-resend on callback query', async t => {
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down Expand Up @@ -52,6 +53,7 @@ await test('context-resend on whatever', async t => {
strictEqual(text, 'whatever');
deepStrictEqual(other, {
disable_web_page_preview: false,
entities: undefined,
parse_mode: undefined,
reply_markup: {
inline_keyboard: [],
Expand Down
Loading

0 comments on commit 7a7e88b

Please sign in to comment.