or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbot-settings.mdbot-setup.mdchat-management.mdindex.mdinteractive-features.mdmedia-files.mdmessage-handling.mdmessaging.md

interactive-features.mddocs/

0

# Interactive Features

1

2

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

3

4

## Capabilities

5

6

### Polls

7

8

Methods for creating and managing polls with various configuration options.

9

10

```javascript { .api }

11

/**

12

* Send native poll

13

* @param {number|string} chatId - Chat identifier

14

* @param {string} question - Poll question (1-300 characters)

15

* @param {string[]} pollOptions - Poll options array (2-10 strings, 1-100 chars each)

16

* @param {object} [options] - Poll configuration options

17

* @returns {Promise<Message>}

18

*/

19

sendPoll(chatId, question, pollOptions, options): Promise<Message>;

20

21

/**

22

* Stop a poll

23

* @param {number|string} chatId - Chat identifier

24

* @param {number} messageId - Poll message identifier

25

* @param {object} [options] - Additional options

26

* @returns {Promise<Poll>}

27

*/

28

stopPoll(chatId, messageId, options): Promise<Poll>;

29

```

30

31

**Usage Example:**

32

33

```javascript

34

// Send simple poll

35

await bot.sendPoll(chatId, 'What is your favorite color?', [

36

'Red ❀️',

37

'Blue πŸ’™',

38

'Green πŸ’š',

39

'Yellow πŸ’›'

40

]);

41

42

// Send anonymous quiz with correct answer

43

await bot.sendPoll(chatId, 'What is 2 + 2?', [

44

'3',

45

'4',

46

'5',

47

'6'

48

], {

49

type: 'quiz',

50

correct_option_id: 1, // Index of correct answer (4)

51

explanation: 'Basic mathematics: 2 + 2 = 4',

52

explanation_parse_mode: 'HTML',

53

is_anonymous: true,

54

allows_multiple_answers: false

55

});

56

57

// Send multiple choice poll

58

await bot.sendPoll(chatId, 'Which programming languages do you know?', [

59

'JavaScript',

60

'Python',

61

'Java',

62

'C++',

63

'Go',

64

'Rust'

65

], {

66

allows_multiple_answers: true,

67

is_anonymous: false

68

});

69

70

// Send poll with time limit

71

await bot.sendPoll(chatId, 'Quick decision needed!', [

72

'Option A',

73

'Option B',

74

'Option C'

75

], {

76

open_period: 60, // Poll closes after 60 seconds

77

is_closed: false

78

});

79

80

// Stop a poll early

81

const stoppedPoll = await bot.stopPoll(chatId, pollMessageId, {

82

reply_markup: {

83

inline_keyboard: [

84

[{ text: 'View Results', callback_data: 'view_results' }]

85

]

86

}

87

});

88

89

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

90

```

91

92

### Dice and Random Games

93

94

Method for sending animated dice and random value games.

95

96

```javascript { .api }

97

/**

98

* Send animated emoji with random value (dice, darts, etc.)

99

* @param {number|string} chatId - Chat identifier

100

* @param {object} [options] - Dice options

101

* @returns {Promise<Message>}

102

*/

103

sendDice(chatId, options): Promise<Message>;

104

```

105

106

**Usage Example:**

107

108

```javascript

109

// Send dice (1-6)

110

const diceMessage = await bot.sendDice(chatId);

111

console.log('Dice value:', diceMessage.dice.value);

112

113

// Send darts game (1-6)

114

const dartsMessage = await bot.sendDice(chatId, {

115

emoji: '🎯'

116

});

117

console.log('Darts score:', dartsMessage.dice.value);

118

119

// Send basketball (1-5)

120

const basketballMessage = await bot.sendDice(chatId, {

121

emoji: 'πŸ€'

122

});

123

124

// Send football/soccer (1-5)

125

const footballMessage = await bot.sendDice(chatId, {

126

emoji: '⚽'

127

});

128

129

// Send slot machine (1-64)

130

const slotMessage = await bot.sendDice(chatId, {

131

emoji: '🎰'

132

});

133

134

// Send bowling (1-6)

135

const bowlingMessage = await bot.sendDice(chatId, {

136

emoji: '🎳'

137

});

138

139

// Handle dice in messages

140

bot.on('dice', (msg) => {

141

const dice = msg.dice;

142

console.log(`Received ${dice.emoji} with value ${dice.value}`);

143

144

// Respond based on dice value

145

if (dice.emoji === '🎲' && dice.value === 6) {

146

bot.sendMessage(msg.chat.id, 'πŸŽ‰ You rolled a six! Lucky!');

147

} else if (dice.emoji === '🎯' && dice.value === 6) {

148

bot.sendMessage(msg.chat.id, 'πŸ† Bullseye! Perfect shot!');

149

}

150

});

151

```

152

153

### Location Sharing

154

155

Methods for sharing and managing location information.

156

157

```javascript { .api }

158

/**

159

* Send location point

160

* @param {number|string} chatId - Chat identifier

161

* @param {number} latitude - Latitude of location

162

* @param {number} longitude - Longitude of location

163

* @param {object} [options] - Location options

164

* @returns {Promise<Message>}

165

*/

166

sendLocation(chatId, latitude, longitude, options): Promise<Message>;

167

168

/**

169

* Edit live location

170

* @param {number} latitude - New latitude

171

* @param {number} longitude - New longitude

172

* @param {object} options - Edit options with chat_id and message_id

173

* @returns {Promise<Message|boolean>}

174

*/

175

editMessageLiveLocation(latitude, longitude, options): Promise<Message|boolean>;

176

177

/**

178

* Stop live location updates

179

* @param {object} options - Stop options with chat_id and message_id

180

* @returns {Promise<Message|boolean>}

181

*/

182

stopMessageLiveLocation(options): Promise<Message|boolean>;

183

184

/**

185

* Send venue information

186

* @param {number|string} chatId - Chat identifier

187

* @param {number} latitude - Venue latitude

188

* @param {number} longitude - Venue longitude

189

* @param {string} title - Venue title

190

* @param {string} address - Venue address

191

* @param {object} [options] - Venue options

192

* @returns {Promise<Message>}

193

*/

194

sendVenue(chatId, latitude, longitude, title, address, options): Promise<Message>;

195

```

196

197

**Usage Example:**

198

199

```javascript

200

// Send static location

201

await bot.sendLocation(chatId, 40.7128, -74.0060, {

202

disable_notification: true

203

});

204

205

// Send live location with updates

206

const liveLocationMessage = await bot.sendLocation(chatId, 40.7128, -74.0060, {

207

live_period: 3600, // Update for 1 hour

208

heading: 45, // Direction in degrees

209

proximity_alert_radius: 100 // Alert when within 100 meters

210

});

211

212

// Update live location

213

await bot.editMessageLiveLocation(40.7138, -74.0070, {

214

chat_id: chatId,

215

message_id: liveLocationMessage.message_id,

216

heading: 90,

217

proximity_alert_radius: 50

218

});

219

220

// Stop live location updates

221

await bot.stopMessageLiveLocation({

222

chat_id: chatId,

223

message_id: liveLocationMessage.message_id,

224

reply_markup: {

225

inline_keyboard: [

226

[{ text: 'πŸ“ Location Sharing Stopped', callback_data: 'location_stopped' }]

227

]

228

}

229

});

230

231

// Send venue information

232

await bot.sendVenue(

233

chatId,

234

40.7589, -73.9851, // Times Square coordinates

235

'Times Square',

236

'4 Times Square, New York, NY 10036, USA',

237

{

238

foursquare_id: '4c04bbf2f964a52075a9e5e3',

239

foursquare_type: 'arts_entertainment/plaza',

240

google_place_id: 'ChIJmQJIxlVYwokRLgeuocVOGVU',

241

google_place_type: 'tourist_attraction'

242

}

243

);

244

245

// Handle location messages

246

bot.on('location', (msg) => {

247

const location = msg.location;

248

console.log(`Received location: ${location.latitude}, ${location.longitude}`);

249

250

if (location.live_period) {

251

console.log(`Live location for ${location.live_period} seconds`);

252

}

253

254

if (location.proximity_alert_radius) {

255

console.log(`Proximity alert radius: ${location.proximity_alert_radius} meters`);

256

}

257

});

258

```

259

260

### Contact Sharing

261

262

Method for sharing contact information.

263

264

```javascript { .api }

265

/**

266

* Send contact information

267

* @param {number|string} chatId - Chat identifier

268

* @param {string} phoneNumber - Contact phone number

269

* @param {string} firstName - Contact first name

270

* @param {object} [options] - Contact options

271

* @returns {Promise<Message>}

272

*/

273

sendContact(chatId, phoneNumber, firstName, options): Promise<Message>;

274

```

275

276

**Usage Example:**

277

278

```javascript

279

// Send basic contact

280

await bot.sendContact(chatId, '+1234567890', 'John', {

281

last_name: 'Doe'

282

});

283

284

// Send contact with additional info

285

await bot.sendContact(chatId, '+1987654321', 'Jane', {

286

last_name: 'Smith',

287

vcard: `BEGIN:VCARD

288

VERSION:3.0

289

FN:Jane Smith

290

ORG:Example Company

291

TITLE:Software Engineer

292

TEL;TYPE=WORK,VOICE:+1987654321

293

EMAIL:jane.smith@example.com

294

URL:https://example.com

295

END:VCARD`

296

});

297

298

// Handle contact messages

299

bot.on('contact', (msg) => {

300

const contact = msg.contact;

301

console.log(`Received contact: ${contact.first_name} ${contact.last_name || ''}`);

302

console.log(`Phone: ${contact.phone_number}`);

303

304

if (contact.user_id) {

305

console.log(`Telegram user ID: ${contact.user_id}`);

306

}

307

308

if (contact.vcard) {

309

console.log('vCard data:', contact.vcard);

310

}

311

});

312

```

313

314

### Chat Actions

315

316

Method for sending typing indicators and other chat actions.

317

318

```javascript { .api }

319

/**

320

* Send chat action (typing, uploading, etc.)

321

* @param {number|string} chatId - Chat identifier

322

* @param {string} action - Action type

323

* @param {object} [options] - Additional options

324

* @returns {Promise<boolean>}

325

*/

326

sendChatAction(chatId, action, options): Promise<boolean>;

327

```

328

329

**Usage Example:**

330

331

```javascript

332

// Show typing indicator

333

await bot.sendChatAction(chatId, 'typing');

334

335

// Simulate long operation with typing

336

bot.sendChatAction(chatId, 'typing');

337

setTimeout(async () => {

338

await bot.sendMessage(chatId, 'Processing completed!');

339

}, 3000);

340

341

// Show different action types

342

await bot.sendChatAction(chatId, 'upload_photo');

343

await bot.sendChatAction(chatId, 'record_video');

344

await bot.sendChatAction(chatId, 'upload_video');

345

await bot.sendChatAction(chatId, 'record_voice');

346

await bot.sendChatAction(chatId, 'upload_voice');

347

await bot.sendChatAction(chatId, 'upload_document');

348

await bot.sendChatAction(chatId, 'choose_sticker');

349

await bot.sendChatAction(chatId, 'find_location');

350

await bot.sendChatAction(chatId, 'record_video_note');

351

await bot.sendChatAction(chatId, 'upload_video_note');

352

353

// Usage with file operations

354

async function sendLargeFile(chatId, filePath) {

355

// Show upload action while preparing file

356

await bot.sendChatAction(chatId, 'upload_document');

357

358

// Send the actual file

359

await bot.sendDocument(chatId, filePath);

360

}

361

362

// Continuous typing for long operations

363

function showTypingPeriodically(chatId, duration = 5000) {

364

const interval = setInterval(() => {

365

bot.sendChatAction(chatId, 'typing');

366

}, 4000); // Send every 4 seconds (action lasts ~5 seconds)

367

368

setTimeout(() => {

369

clearInterval(interval);

370

}, duration);

371

}

372

```

373

374

### Message Reactions

375

376

Method for setting reactions on messages.

377

378

```javascript { .api }

379

/**

380

* Set reactions on a message

381

* @param {number|string} chatId - Chat identifier

382

* @param {number} messageId - Message identifier

383

* @param {object} [options] - Reaction options

384

* @returns {Promise<boolean>}

385

*/

386

setMessageReaction(chatId, messageId, options): Promise<boolean>;

387

```

388

389

**Usage Example:**

390

391

```javascript

392

// Add thumbs up reaction

393

await bot.setMessageReaction(chatId, messageId, {

394

reaction: [{ type: 'emoji', emoji: 'πŸ‘' }],

395

is_big: false

396

});

397

398

// Add multiple reactions

399

await bot.setMessageReaction(chatId, messageId, {

400

reaction: [

401

{ type: 'emoji', emoji: '❀️' },

402

{ type: 'emoji', emoji: 'πŸ”₯' },

403

{ type: 'emoji', emoji: 'πŸ‘' }

404

]

405

});

406

407

// Remove all reactions

408

await bot.setMessageReaction(chatId, messageId, {

409

reaction: []

410

});

411

412

// Add custom emoji reaction (for Premium users)

413

await bot.setMessageReaction(chatId, messageId, {

414

reaction: [{ type: 'custom_emoji', custom_emoji_id: '5789506394507541006' }],

415

is_big: true

416

});

417

418

// Handle message reaction updates

419

bot.on('message_reaction', (messageReaction) => {

420

console.log('Message reaction updated:', messageReaction);

421

console.log('Chat:', messageReaction.chat.id);

422

console.log('Message:', messageReaction.message_id);

423

console.log('User:', messageReaction.user?.id);

424

console.log('Date:', new Date(messageReaction.date * 1000));

425

console.log('Old reactions:', messageReaction.old_reaction);

426

console.log('New reactions:', messageReaction.new_reaction);

427

});

428

429

// Handle reaction count updates

430

bot.on('message_reaction_count', (reactionCount) => {

431

console.log('Reaction count updated:', reactionCount);

432

console.log('Total reactions:', reactionCount.reactions.length);

433

434

reactionCount.reactions.forEach(reaction => {

435

if (reaction.type.type === 'emoji') {

436

console.log(`${reaction.type.emoji}: ${reaction.total_count}`);

437

}

438

});

439

});

440

```

441

442

## Types

443

444

```javascript { .api }

445

interface Poll {

446

id: string;

447

question: string;

448

options: PollOption[];

449

total_voter_count: number;

450

is_closed: boolean;

451

is_anonymous: boolean;

452

type: 'regular' | 'quiz';

453

allows_multiple_answers: boolean;

454

correct_option_id?: number;

455

explanation?: string;

456

explanation_entities?: MessageEntity[];

457

open_period?: number;

458

close_date?: number;

459

}

460

461

interface PollOption {

462

text: string;

463

voter_count: number;

464

}

465

466

interface Dice {

467

emoji: string;

468

value: number;

469

}

470

471

interface Location {

472

longitude: number;

473

latitude: number;

474

live_period?: number;

475

heading?: number;

476

proximity_alert_radius?: number;

477

}

478

479

interface Venue {

480

location: Location;

481

title: string;

482

address: string;

483

foursquare_id?: string;

484

foursquare_type?: string;

485

google_place_id?: string;

486

google_place_type?: string;

487

}

488

489

interface Contact {

490

phone_number: string;

491

first_name: string;

492

last_name?: string;

493

user_id?: number;

494

vcard?: string;

495

}

496

497

type ChatAction =

498

| 'typing'

499

| 'upload_photo'

500

| 'record_video'

501

| 'upload_video'

502

| 'record_voice'

503

| 'upload_voice'

504

| 'upload_document'

505

| 'choose_sticker'

506

| 'find_location'

507

| 'record_video_note'

508

| 'upload_video_note';

509

510

interface ReactionType {

511

type: 'emoji';

512

emoji: string;

513

}

514

515

interface ReactionTypeCustomEmoji {

516

type: 'custom_emoji';

517

custom_emoji_id: string;

518

}

519

520

interface MessageReactionUpdated {

521

chat: Chat;

522

message_id: number;

523

user?: User;

524

actor_chat?: Chat;

525

date: number;

526

old_reaction: ReactionType[];

527

new_reaction: ReactionType[];

528

}

529

530

interface MessageReactionCountUpdated {

531

chat: Chat;

532

message_id: number;

533

date: number;

534

reactions: ReactionCount[];

535

}

536

537

interface ReactionCount {

538

type: ReactionType | ReactionTypeCustomEmoji;

539

total_count: number;

540

}

541

542

interface SendPollOptions {

543

business_connection_id?: string;

544

message_thread_id?: number;

545

is_anonymous?: boolean;

546

type?: 'quiz' | 'regular';

547

allows_multiple_answers?: boolean;

548

correct_option_id?: number;

549

explanation?: string;

550

explanation_parse_mode?: 'HTML' | 'Markdown' | 'MarkdownV2';

551

explanation_entities?: MessageEntity[];

552

open_period?: number;

553

close_date?: number;

554

is_closed?: boolean;

555

disable_notification?: boolean;

556

protect_content?: boolean;

557

reply_parameters?: ReplyParameters;

558

reply_markup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;

559

}

560

561

interface SendLocationOptions {

562

business_connection_id?: string;

563

message_thread_id?: number;

564

horizontal_accuracy?: number;

565

live_period?: number;

566

heading?: number;

567

proximity_alert_radius?: number;

568

disable_notification?: boolean;

569

protect_content?: boolean;

570

reply_parameters?: ReplyParameters;

571

reply_markup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;

572

}

573

574

interface SendContactOptions {

575

business_connection_id?: string;

576

message_thread_id?: number;

577

last_name?: string;

578

vcard?: string;

579

disable_notification?: boolean;

580

protect_content?: boolean;

581

reply_parameters?: ReplyParameters;

582

reply_markup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;

583

}

584

```