CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-node-telegram-bot-api

Node.js wrapper for the official Telegram Bot API with polling and webhook support, comprehensive message handling, media operations, and bot management features.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

interactive-features.mddocs/

Interactive Features

Interactive elements including polls, dice games, location sharing, contact sharing, and chat actions for enhanced user engagement.

Capabilities

Polls

Methods for creating and managing polls with various configuration options.

/**
 * Send native poll
 * @param {number|string} chatId - Chat identifier
 * @param {string} question - Poll question (1-300 characters)
 * @param {string[]} pollOptions - Poll options array (2-10 strings, 1-100 chars each)
 * @param {object} [options] - Poll configuration options
 * @returns {Promise<Message>}
 */
sendPoll(chatId, question, pollOptions, options): Promise<Message>;

/**
 * Stop a poll
 * @param {number|string} chatId - Chat identifier
 * @param {number} messageId - Poll message identifier
 * @param {object} [options] - Additional options
 * @returns {Promise<Poll>}
 */
stopPoll(chatId, messageId, options): Promise<Poll>;

Usage Example:

// Send simple poll
await bot.sendPoll(chatId, 'What is your favorite color?', [
  'Red ❤️',
  'Blue 💙',
  'Green 💚',
  'Yellow 💛'
]);

// Send anonymous quiz with correct answer
await bot.sendPoll(chatId, 'What is 2 + 2?', [
  '3',
  '4',
  '5',
  '6'
], {
  type: 'quiz',
  correct_option_id: 1, // Index of correct answer (4)
  explanation: 'Basic mathematics: 2 + 2 = 4',
  explanation_parse_mode: 'HTML',
  is_anonymous: true,
  allows_multiple_answers: false
});

// Send multiple choice poll
await bot.sendPoll(chatId, 'Which programming languages do you know?', [
  'JavaScript',
  'Python',
  'Java',
  'C++',
  'Go',
  'Rust'
], {
  allows_multiple_answers: true,
  is_anonymous: false
});

// Send poll with time limit
await bot.sendPoll(chatId, 'Quick decision needed!', [
  'Option A',
  'Option B',
  'Option C'
], {
  open_period: 60, // Poll closes after 60 seconds
  is_closed: false
});

// Stop a poll early
const stoppedPoll = await bot.stopPoll(chatId, pollMessageId, {
  reply_markup: {
    inline_keyboard: [
      [{ text: 'View Results', callback_data: 'view_results' }]
    ]
  }
});

console.log('Poll results:', stoppedPoll.options);

Dice and Random Games

Method for sending animated dice and random value games.

/**
 * Send animated emoji with random value (dice, darts, etc.)
 * @param {number|string} chatId - Chat identifier
 * @param {object} [options] - Dice options
 * @returns {Promise<Message>}
 */
sendDice(chatId, options): Promise<Message>;

Usage Example:

// Send dice (1-6)
const diceMessage = await bot.sendDice(chatId);
console.log('Dice value:', diceMessage.dice.value);

// Send darts game (1-6)
const dartsMessage = await bot.sendDice(chatId, {
  emoji: '🎯'
});
console.log('Darts score:', dartsMessage.dice.value);

// Send basketball (1-5)
const basketballMessage = await bot.sendDice(chatId, {
  emoji: '🏀'
});

// Send football/soccer (1-5)
const footballMessage = await bot.sendDice(chatId, {
  emoji: '⚽'
});

// Send slot machine (1-64)
const slotMessage = await bot.sendDice(chatId, {
  emoji: '🎰'
});

// Send bowling (1-6)
const bowlingMessage = await bot.sendDice(chatId, {
  emoji: '🎳'
});

// Handle dice in messages
bot.on('dice', (msg) => {
  const dice = msg.dice;
  console.log(`Received ${dice.emoji} with value ${dice.value}`);
  
  // Respond based on dice value
  if (dice.emoji === '🎲' && dice.value === 6) {
    bot.sendMessage(msg.chat.id, '🎉 You rolled a six! Lucky!');
  } else if (dice.emoji === '🎯' && dice.value === 6) {
    bot.sendMessage(msg.chat.id, '🏆 Bullseye! Perfect shot!');
  }
});

Location Sharing

Methods for sharing and managing location information.

/**
 * Send location point
 * @param {number|string} chatId - Chat identifier
 * @param {number} latitude - Latitude of location
 * @param {number} longitude - Longitude of location
 * @param {object} [options] - Location options
 * @returns {Promise<Message>}
 */
sendLocation(chatId, latitude, longitude, options): Promise<Message>;

/**
 * Edit live location
 * @param {number} latitude - New latitude
 * @param {number} longitude - New longitude
 * @param {object} options - Edit options with chat_id and message_id
 * @returns {Promise<Message|boolean>}
 */
editMessageLiveLocation(latitude, longitude, options): Promise<Message|boolean>;

/**
 * Stop live location updates
 * @param {object} options - Stop options with chat_id and message_id
 * @returns {Promise<Message|boolean>}
 */
stopMessageLiveLocation(options): Promise<Message|boolean>;

/**
 * Send venue information
 * @param {number|string} chatId - Chat identifier
 * @param {number} latitude - Venue latitude
 * @param {number} longitude - Venue longitude
 * @param {string} title - Venue title
 * @param {string} address - Venue address
 * @param {object} [options] - Venue options
 * @returns {Promise<Message>}
 */
sendVenue(chatId, latitude, longitude, title, address, options): Promise<Message>;

Usage Example:

// Send static location
await bot.sendLocation(chatId, 40.7128, -74.0060, {
  disable_notification: true
});

// Send live location with updates
const liveLocationMessage = await bot.sendLocation(chatId, 40.7128, -74.0060, {
  live_period: 3600, // Update for 1 hour
  heading: 45, // Direction in degrees
  proximity_alert_radius: 100 // Alert when within 100 meters
});

// Update live location
await bot.editMessageLiveLocation(40.7138, -74.0070, {
  chat_id: chatId,
  message_id: liveLocationMessage.message_id,
  heading: 90,
  proximity_alert_radius: 50
});

// Stop live location updates
await bot.stopMessageLiveLocation({
  chat_id: chatId,
  message_id: liveLocationMessage.message_id,
  reply_markup: {
    inline_keyboard: [
      [{ text: '📍 Location Sharing Stopped', callback_data: 'location_stopped' }]
    ]
  }
});

// Send venue information
await bot.sendVenue(
  chatId,
  40.7589, -73.9851, // Times Square coordinates
  'Times Square',
  '4 Times Square, New York, NY 10036, USA',
  {
    foursquare_id: '4c04bbf2f964a52075a9e5e3',
    foursquare_type: 'arts_entertainment/plaza',
    google_place_id: 'ChIJmQJIxlVYwokRLgeuocVOGVU',
    google_place_type: 'tourist_attraction'
  }
);

// Handle location messages
bot.on('location', (msg) => {
  const location = msg.location;
  console.log(`Received location: ${location.latitude}, ${location.longitude}`);
  
  if (location.live_period) {
    console.log(`Live location for ${location.live_period} seconds`);
  }
  
  if (location.proximity_alert_radius) {
    console.log(`Proximity alert radius: ${location.proximity_alert_radius} meters`);
  }
});

Contact Sharing

Method for sharing contact information.

/**
 * Send contact information
 * @param {number|string} chatId - Chat identifier
 * @param {string} phoneNumber - Contact phone number
 * @param {string} firstName - Contact first name
 * @param {object} [options] - Contact options
 * @returns {Promise<Message>}
 */
sendContact(chatId, phoneNumber, firstName, options): Promise<Message>;

Usage Example:

// Send basic contact
await bot.sendContact(chatId, '+1234567890', 'John', {
  last_name: 'Doe'
});

// Send contact with additional info
await bot.sendContact(chatId, '+1987654321', 'Jane', {
  last_name: 'Smith',
  vcard: `BEGIN:VCARD
VERSION:3.0
FN:Jane Smith
ORG:Example Company
TITLE:Software Engineer
TEL;TYPE=WORK,VOICE:+1987654321
EMAIL:jane.smith@example.com
URL:https://example.com
END:VCARD`
});

// Handle contact messages
bot.on('contact', (msg) => {
  const contact = msg.contact;
  console.log(`Received contact: ${contact.first_name} ${contact.last_name || ''}`);
  console.log(`Phone: ${contact.phone_number}`);
  
  if (contact.user_id) {
    console.log(`Telegram user ID: ${contact.user_id}`);
  }
  
  if (contact.vcard) {
    console.log('vCard data:', contact.vcard);
  }
});

Chat Actions

Method for sending typing indicators and other chat actions.

/**
 * Send chat action (typing, uploading, etc.)
 * @param {number|string} chatId - Chat identifier
 * @param {string} action - Action type
 * @param {object} [options] - Additional options
 * @returns {Promise<boolean>}
 */
sendChatAction(chatId, action, options): Promise<boolean>;

Usage Example:

// Show typing indicator
await bot.sendChatAction(chatId, 'typing');

// Simulate long operation with typing
bot.sendChatAction(chatId, 'typing');
setTimeout(async () => {
  await bot.sendMessage(chatId, 'Processing completed!');
}, 3000);

// Show different action types
await bot.sendChatAction(chatId, 'upload_photo');
await bot.sendChatAction(chatId, 'record_video');
await bot.sendChatAction(chatId, 'upload_video');
await bot.sendChatAction(chatId, 'record_voice');
await bot.sendChatAction(chatId, 'upload_voice');
await bot.sendChatAction(chatId, 'upload_document');
await bot.sendChatAction(chatId, 'choose_sticker');
await bot.sendChatAction(chatId, 'find_location');
await bot.sendChatAction(chatId, 'record_video_note');
await bot.sendChatAction(chatId, 'upload_video_note');

// Usage with file operations
async function sendLargeFile(chatId, filePath) {
  // Show upload action while preparing file
  await bot.sendChatAction(chatId, 'upload_document');
  
  // Send the actual file
  await bot.sendDocument(chatId, filePath);
}

// Continuous typing for long operations
function showTypingPeriodically(chatId, duration = 5000) {
  const interval = setInterval(() => {
    bot.sendChatAction(chatId, 'typing');
  }, 4000); // Send every 4 seconds (action lasts ~5 seconds)
  
  setTimeout(() => {
    clearInterval(interval);
  }, duration);
}

Message Reactions

Method for setting reactions on messages.

/**
 * Set reactions on a message
 * @param {number|string} chatId - Chat identifier
 * @param {number} messageId - Message identifier
 * @param {object} [options] - Reaction options
 * @returns {Promise<boolean>}
 */
setMessageReaction(chatId, messageId, options): Promise<boolean>;

Usage Example:

// Add thumbs up reaction
await bot.setMessageReaction(chatId, messageId, {
  reaction: [{ type: 'emoji', emoji: '👍' }],
  is_big: false
});

// Add multiple reactions
await bot.setMessageReaction(chatId, messageId, {
  reaction: [
    { type: 'emoji', emoji: '❤️' },
    { type: 'emoji', emoji: '🔥' },
    { type: 'emoji', emoji: '👏' }
  ]
});

// Remove all reactions
await bot.setMessageReaction(chatId, messageId, {
  reaction: []
});

// Add custom emoji reaction (for Premium users)
await bot.setMessageReaction(chatId, messageId, {
  reaction: [{ type: 'custom_emoji', custom_emoji_id: '5789506394507541006' }],
  is_big: true
});

// Handle message reaction updates
bot.on('message_reaction', (messageReaction) => {
  console.log('Message reaction updated:', messageReaction);
  console.log('Chat:', messageReaction.chat.id);
  console.log('Message:', messageReaction.message_id);
  console.log('User:', messageReaction.user?.id);
  console.log('Date:', new Date(messageReaction.date * 1000));
  console.log('Old reactions:', messageReaction.old_reaction);
  console.log('New reactions:', messageReaction.new_reaction);
});

// Handle reaction count updates
bot.on('message_reaction_count', (reactionCount) => {
  console.log('Reaction count updated:', reactionCount);
  console.log('Total reactions:', reactionCount.reactions.length);
  
  reactionCount.reactions.forEach(reaction => {
    if (reaction.type.type === 'emoji') {
      console.log(`${reaction.type.emoji}: ${reaction.total_count}`);
    }
  });
});

Types

interface Poll {
  id: string;
  question: string;
  options: PollOption[];
  total_voter_count: number;
  is_closed: boolean;
  is_anonymous: boolean;
  type: 'regular' | 'quiz';
  allows_multiple_answers: boolean;
  correct_option_id?: number;
  explanation?: string;
  explanation_entities?: MessageEntity[];
  open_period?: number;
  close_date?: number;
}

interface PollOption {
  text: string;
  voter_count: number;
}

interface Dice {
  emoji: string;
  value: number;
}

interface Location {
  longitude: number;
  latitude: number;
  live_period?: number;
  heading?: number;
  proximity_alert_radius?: number;
}

interface Venue {
  location: Location;
  title: string;
  address: string;
  foursquare_id?: string;
  foursquare_type?: string;
  google_place_id?: string;
  google_place_type?: string;
}

interface Contact {
  phone_number: string;
  first_name: string;
  last_name?: string;
  user_id?: number;
  vcard?: string;
}

type ChatAction = 
  | 'typing'
  | 'upload_photo'
  | 'record_video'
  | 'upload_video'
  | 'record_voice'
  | 'upload_voice'
  | 'upload_document'
  | 'choose_sticker'
  | 'find_location'
  | 'record_video_note'
  | 'upload_video_note';

interface ReactionType {
  type: 'emoji';
  emoji: string;
}

interface ReactionTypeCustomEmoji {
  type: 'custom_emoji';
  custom_emoji_id: string;
}

interface MessageReactionUpdated {
  chat: Chat;
  message_id: number;
  user?: User;
  actor_chat?: Chat;
  date: number;
  old_reaction: ReactionType[];
  new_reaction: ReactionType[];
}

interface MessageReactionCountUpdated {
  chat: Chat;
  message_id: number;
  date: number;
  reactions: ReactionCount[];
}

interface ReactionCount {
  type: ReactionType | ReactionTypeCustomEmoji;
  total_count: number;
}

interface SendPollOptions {
  business_connection_id?: string;
  message_thread_id?: number;
  is_anonymous?: boolean;
  type?: 'quiz' | 'regular';
  allows_multiple_answers?: boolean;
  correct_option_id?: number;
  explanation?: string;
  explanation_parse_mode?: 'HTML' | 'Markdown' | 'MarkdownV2';
  explanation_entities?: MessageEntity[];
  open_period?: number;
  close_date?: number;
  is_closed?: boolean;
  disable_notification?: boolean;
  protect_content?: boolean;
  reply_parameters?: ReplyParameters;
  reply_markup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;
}

interface SendLocationOptions {
  business_connection_id?: string;
  message_thread_id?: number;
  horizontal_accuracy?: number;
  live_period?: number;
  heading?: number;
  proximity_alert_radius?: number;
  disable_notification?: boolean;
  protect_content?: boolean;
  reply_parameters?: ReplyParameters;
  reply_markup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;
}

interface SendContactOptions {
  business_connection_id?: string;
  message_thread_id?: number;
  last_name?: string;
  vcard?: string;
  disable_notification?: boolean;
  protect_content?: boolean;
  reply_parameters?: ReplyParameters;
  reply_markup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;
}

docs

advanced-features.md

bot-settings.md

bot-setup.md

chat-management.md

index.md

interactive-features.md

media-files.md

message-handling.md

messaging.md

tile.json