Skip to content

User

User is the primary actor for dispatching synthetic updates. Every method sends a Telegram update to your bot and returns the resulting Message object.

ts
const user = chats.newUser({ first_name: 'Alice' });

SendTextOptions

Most dispatch methods accept an options object. The most common fields:

ts
interface SendTextOptions {
  chat?: Group | Supergroup | Channel | PrivateChat; // target chat (default: user's private chat)
  reply_to_message?: Partial<Message> & { message_id: number };
  reply_markup?: InlineKeyboard | ReplyKeyboardMarkup | ...;
  parse_mode?: 'HTML' | 'Markdown' | 'MarkdownV2';
  entities?: MessageEntity[];
  anonymous?: boolean; // send as GROUP_ANONYMOUS_BOT (requires chat: group)
  // ... all sendMessage fields
}

Text & Commands

sendText(text, options?)

Sends a plain text message.

ts
await user.sendText('Hello!');
await user.sendText('Hi there', { chat: group, parse_mode: 'HTML' });

sendMessage(text, options?)

Alias for sendText.

sendCommand(command, args?, options?)

Sends a text message that looks like a bot command (with a bot_command entity).

ts
await user.sendCommand('/start');
await user.sendCommand('/set', 'dark'); // → /set dark
await user.sendCommand('/ban', '42', { chat: group });

Media

sendPhoto(fileId?, options?)

ts
await user.sendPhoto('AgACAgI...', { caption: 'Look!' });

sendDocument(options?)

ts
await user.sendDocument({ caption: 'report.pdf' });

sendVideo(options?) / sendAudio(options?) / sendVoice(options?) / sendVideoNote(options?)

ts
await user.sendVideo();
await user.sendAudio({ duration: 120 });

sendAnimation(options?) / sendSticker(fileId?, options?)

ts
await user.sendSticker('CAACAgI...');

sendMediaGroup(items)

Sends an album of multiple media items. Returns Message[].

ts
const messages = await user.sendMediaGroup([
  { type: 'photo', media: 'AgACAgI...' },
  { type: 'video', media: 'BAACAgI...' },
]);

Special content

sendLocation(options?) / sendContact(options?) / sendVenue(options?)

ts
await user.sendLocation({ latitude: 50.4, longitude: 30.5 });
await user.sendContact({ phone_number: '+380001234567', first_name: 'Alice' });

sendPoll(question, options?, sendOptions?)

ts
await user.sendPoll('Which?', { options: ['A', 'B', 'C'] });

sendDice(options?)

ts
const msg = await user.sendDice({ emoji: '🎲' });

sendWebAppData(data, buttonText, options?)

ts
await user.sendWebAppData('{"result":42}', 'Submit');

Group & service events

joinChat(chat, options?) → dispatches new_chat_members

ts
await user.joinChat(group);

leaveChat(chat, options?) → dispatches left_chat_member

ts
await user.leaveChat(group);

Inline & callback

sendInlineQuery(query, options?)

ts
await user.sendInlineQuery('search term');

chooseInlineResult(resultId, options?)

ts
await user.chooseInlineResult('result_001');

sendCallbackQuery(data, options?)

Sends a standalone callback query (not associated with a button click). For button clicks, use reply.clickButton().

ts
await user.sendCallbackQuery('my_action');

Reactions & polls

reactTo(reply, reaction) → dispatches message_reaction

ts
await user.reactTo(lastReply, { type: 'emoji', emoji: '👍' });

answerPoll(reply, optionIndices) → dispatches poll_answer

ts
await user.answerPoll(pollReply, [0, 2]);

Payment

sendSuccessfulPayment(options?)

ts
await user.sendSuccessfulPayment({ total_amount: 1000, currency: 'USD' });

sendShippingQuery(options?) / sendPreCheckoutQuery(options?)

ts
await user.sendShippingQuery({ invoice_payload: 'order_42' });

purchasePaidMedia(payload, options?)

ts
await user.purchasePaidMedia('media_payload');

Bot & chat management

boostChat(chat) → dispatches chat_boost

ts
await user.boostChat(channel);

removeBoost(chat, boostId) → dispatches removed_chat_boost

ts
await user.removeBoost(channel, 'boost_001');

requestJoin(group) → dispatches chat_join_request

ts
await user.requestJoin(group);

manageBot(botUser, options?) → dispatches Business managed bot update

ts
await user.manageBot(chats.newUser({ is_bot: true }));

Sending to a specific chat

Pass { chat } to send to a group, supergroup, or channel:

ts
const group = chats.newSupergroup('Dev Chat');
group.join(user);

await user.sendText('/help', { chat: group });
expect(group.messages.lastOrThrow?.text).toBe(...);

Anonymous group messages

ts
await user.sendText('/vote yes', { chat: group, anonymous: true });
// ctx.message.from === GROUP_ANONYMOUS_BOT

Reply to a message

ts
const originalMsg = await user.sendText('Original');

await user.sendText('Reply!', {
  chat: group,
  reply_to_message: { message_id: originalMsg.message_id },
});

Released under the MIT License.