or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-commands.mdcommands-framework.mdcore-objects.mdevent-handling.mdindex.mduser-interface.mdutilities.mdvoice-audio.mdwebhooks.md

event-handling.mddocs/

0

# Event Handling

1

2

Comprehensive event system for responding to Discord activities including messages, reactions, member changes, guild updates, and voice state changes. Discord.py provides both high-level events and raw gateway events for detailed control over bot behavior.

3

4

## Capabilities

5

6

### Core Events

7

8

Essential events for bot functionality and user interactions.

9

10

```python { .api }

11

@client.event

12

async def on_ready():

13

"""

14

Called when the client has successfully connected to Discord.

15

Bot is fully ready to process events and commands.

16

"""

17

pass

18

19

@client.event

20

async def on_resumed():

21

"""

22

Called when the client has resumed a session.

23

"""

24

pass

25

26

@client.event

27

async def on_connect():

28

"""

29

Called when the client has connected to Discord's gateway.

30

This may be called multiple times during reconnections.

31

"""

32

pass

33

34

@client.event

35

async def on_disconnect():

36

"""

37

Called when the client has disconnected from Discord's gateway.

38

"""

39

pass

40

41

@client.event

42

async def on_shard_connect(shard_id: int):

43

"""

44

Called when a shard connects to Discord.

45

46

Parameters:

47

- shard_id: ID of the connected shard

48

"""

49

pass

50

51

@client.event

52

async def on_shard_disconnect(shard_id: int):

53

"""

54

Called when a shard disconnects from Discord.

55

56

Parameters:

57

- shard_id: ID of the disconnected shard

58

"""

59

pass

60

61

@client.event

62

async def on_shard_ready(shard_id: int):

63

"""

64

Called when a shard becomes ready.

65

66

Parameters:

67

- shard_id: ID of the ready shard

68

"""

69

pass

70

71

@client.event

72

async def on_shard_resumed(shard_id: int):

73

"""

74

Called when a shard resumes a session.

75

76

Parameters:

77

- shard_id: ID of the resumed shard

78

"""

79

pass

80

```

81

82

### Message Events

83

84

Events for message creation, editing, deletion, and reactions.

85

86

```python { .api }

87

@client.event

88

async def on_message(message: Message):

89

"""

90

Called when a message is created.

91

92

Parameters:

93

- message: The message that was created

94

"""

95

pass

96

97

@client.event

98

async def on_message_edit(before: Message, after: Message):

99

"""

100

Called when a message is edited.

101

102

Parameters:

103

- before: Message before editing

104

- after: Message after editing

105

"""

106

pass

107

108

@client.event

109

async def on_message_delete(message: Message):

110

"""

111

Called when a message is deleted.

112

113

Parameters:

114

- message: The deleted message (may be partial)

115

"""

116

pass

117

118

@client.event

119

async def on_bulk_message_delete(messages: List[Message]):

120

"""

121

Called when multiple messages are deleted at once.

122

123

Parameters:

124

- messages: List of deleted messages

125

"""

126

pass

127

128

@client.event

129

async def on_reaction_add(reaction: Reaction, user: Union[User, Member]):

130

"""

131

Called when a reaction is added to a message.

132

133

Parameters:

134

- reaction: The reaction that was added

135

- user: User who added the reaction

136

"""

137

pass

138

139

@client.event

140

async def on_reaction_remove(reaction: Reaction, user: Union[User, Member]):

141

"""

142

Called when a reaction is removed from a message.

143

144

Parameters:

145

- reaction: The reaction that was removed

146

- user: User who removed the reaction

147

"""

148

pass

149

150

@client.event

151

async def on_reaction_clear(message: Message, reactions: List[Reaction]):

152

"""

153

Called when all reactions are cleared from a message.

154

155

Parameters:

156

- message: Message that had reactions cleared

157

- reactions: List of reactions that were cleared

158

"""

159

pass

160

161

@client.event

162

async def on_reaction_clear_emoji(reaction: Reaction):

163

"""

164

Called when all reactions of a specific emoji are cleared.

165

166

Parameters:

167

- reaction: The reaction that was cleared

168

"""

169

pass

170

171

@client.event

172

async def on_typing(channel: Messageable, user: Union[User, Member], when: datetime):

173

"""

174

Called when someone starts typing.

175

176

Parameters:

177

- channel: Channel where typing started

178

- user: User who started typing

179

- when: When typing started

180

"""

181

pass

182

```

183

184

### Guild Events

185

186

Events for guild (server) management and changes.

187

188

```python { .api }

189

@client.event

190

async def on_guild_join(guild: Guild):

191

"""

192

Called when the bot joins a guild.

193

194

Parameters:

195

- guild: Guild that was joined

196

"""

197

pass

198

199

@client.event

200

async def on_guild_remove(guild: Guild):

201

"""

202

Called when the bot is removed from a guild.

203

204

Parameters:

205

- guild: Guild that was left

206

"""

207

pass

208

209

@client.event

210

async def on_guild_update(before: Guild, after: Guild):

211

"""

212

Called when a guild is updated.

213

214

Parameters:

215

- before: Guild before update

216

- after: Guild after update

217

"""

218

pass

219

220

@client.event

221

async def on_guild_available(guild: Guild):

222

"""

223

Called when a guild becomes available.

224

225

Parameters:

226

- guild: Guild that became available

227

"""

228

pass

229

230

@client.event

231

async def on_guild_unavailable(guild: Guild):

232

"""

233

Called when a guild becomes unavailable.

234

235

Parameters:

236

- guild: Guild that became unavailable

237

"""

238

pass

239

240

@client.event

241

async def on_guild_channel_create(channel: GuildChannel):

242

"""

243

Called when a guild channel is created.

244

245

Parameters:

246

- channel: Channel that was created

247

"""

248

pass

249

250

@client.event

251

async def on_guild_channel_delete(channel: GuildChannel):

252

"""

253

Called when a guild channel is deleted.

254

255

Parameters:

256

- channel: Channel that was deleted

257

"""

258

pass

259

260

@client.event

261

async def on_guild_channel_update(before: GuildChannel, after: GuildChannel):

262

"""

263

Called when a guild channel is updated.

264

265

Parameters:

266

- before: Channel before update

267

- after: Channel after update

268

"""

269

pass

270

271

@client.event

272

async def on_guild_channel_pins_update(channel: Union[TextChannel, DMChannel, GroupChannel], last_pin: Optional[datetime]):

273

"""

274

Called when channel pins are updated.

275

276

Parameters:

277

- channel: Channel with pin update

278

- last_pin: Timestamp of most recent pin

279

"""

280

pass

281

282

@client.event

283

async def on_guild_integrations_update(guild: Guild):

284

"""

285

Called when guild integrations are updated.

286

287

Parameters:

288

- guild: Guild with integration update

289

"""

290

pass

291

292

@client.event

293

async def on_webhooks_update(channel: TextChannel):

294

"""

295

Called when channel webhooks are updated.

296

297

Parameters:

298

- channel: Channel with webhook update

299

"""

300

pass

301

302

@client.event

303

async def on_guild_role_create(role: Role):

304

"""

305

Called when a guild role is created.

306

307

Parameters:

308

- role: Role that was created

309

"""

310

pass

311

312

@client.event

313

async def on_guild_role_delete(role: Role):

314

"""

315

Called when a guild role is deleted.

316

317

Parameters:

318

- role: Role that was deleted

319

"""

320

pass

321

322

@client.event

323

async def on_guild_role_update(before: Role, after: Role):

324

"""

325

Called when a guild role is updated.

326

327

Parameters:

328

- before: Role before update

329

- after: Role after update

330

"""

331

pass

332

333

@client.event

334

async def on_guild_emojis_update(guild: Guild, before: List[Emoji], after: List[Emoji]):

335

"""

336

Called when guild emojis are updated.

337

338

Parameters:

339

- guild: Guild with emoji update

340

- before: Emojis before update

341

- after: Emojis after update

342

"""

343

pass

344

345

@client.event

346

async def on_guild_stickers_update(guild: Guild, before: List[GuildSticker], after: List[GuildSticker]):

347

"""

348

Called when guild stickers are updated.

349

350

Parameters:

351

- guild: Guild with sticker update

352

- before: Stickers before update

353

- after: Stickers after update

354

"""

355

pass

356

```

357

358

### Member Events

359

360

Events for member management, joins, leaves, and updates.

361

362

```python { .api }

363

@client.event

364

async def on_member_join(member: Member):

365

"""

366

Called when a member joins a guild.

367

368

Parameters:

369

- member: Member who joined

370

"""

371

pass

372

373

@client.event

374

async def on_member_remove(member: Member):

375

"""

376

Called when a member leaves a guild.

377

378

Parameters:

379

- member: Member who left

380

"""

381

pass

382

383

@client.event

384

async def on_member_update(before: Member, after: Member):

385

"""

386

Called when a member is updated.

387

388

Parameters:

389

- before: Member before update

390

- after: Member after update

391

"""

392

pass

393

394

@client.event

395

async def on_user_update(before: User, after: User):

396

"""

397

Called when a user updates their profile.

398

399

Parameters:

400

- before: User before update

401

- after: User after update

402

"""

403

pass

404

405

@client.event

406

async def on_member_ban(guild: Guild, user: Union[User, Member]):

407

"""

408

Called when a member is banned from a guild.

409

410

Parameters:

411

- guild: Guild where ban occurred

412

- user: User who was banned

413

"""

414

pass

415

416

@client.event

417

async def on_member_unban(guild: Guild, user: User):

418

"""

419

Called when a member is unbanned from a guild.

420

421

Parameters:

422

- guild: Guild where unban occurred

423

- user: User who was unbanned

424

"""

425

pass

426

427

@client.event

428

async def on_presence_update(before: Member, after: Member):

429

"""

430

Called when a member's presence is updated.

431

Requires PRESENCE_UPDATE intent.

432

433

Parameters:

434

- before: Member before presence update

435

- after: Member after presence update

436

"""

437

pass

438

```

439

440

### Voice Events

441

442

Events for voice channel activity and state changes.

443

444

```python { .api }

445

@client.event

446

async def on_voice_state_update(member: Member, before: VoiceState, after: VoiceState):

447

"""

448

Called when a member's voice state changes.

449

450

Parameters:

451

- member: Member whose voice state changed

452

- before: Voice state before change

453

- after: Voice state after change

454

"""

455

pass

456

457

@client.event

458

async def on_stage_instance_create(stage_instance: StageInstance):

459

"""

460

Called when a stage instance is created.

461

462

Parameters:

463

- stage_instance: Stage instance that was created

464

"""

465

pass

466

467

@client.event

468

async def on_stage_instance_delete(stage_instance: StageInstance):

469

"""

470

Called when a stage instance is deleted.

471

472

Parameters:

473

- stage_instance: Stage instance that was deleted

474

"""

475

pass

476

477

@client.event

478

async def on_stage_instance_update(before: StageInstance, after: StageInstance):

479

"""

480

Called when a stage instance is updated.

481

482

Parameters:

483

- before: Stage instance before update

484

- after: Stage instance after update

485

"""

486

pass

487

```

488

489

### Interaction Events

490

491

Events for slash commands, buttons, select menus, and other interactions.

492

493

```python { .api }

494

@client.event

495

async def on_interaction(interaction: Interaction):

496

"""

497

Called when an interaction is received.

498

499

Parameters:

500

- interaction: The interaction that was received

501

"""

502

pass

503

504

@client.event

505

async def on_application_command_error(interaction: Interaction, error: AppCommandError):

506

"""

507

Called when an application command raises an error.

508

509

Parameters:

510

- interaction: Interaction that caused the error

511

- error: Error that was raised

512

"""

513

pass

514

515

@client.event

516

async def on_app_command_completion(interaction: Interaction, command: Union[Command, ContextMenu]):

517

"""

518

Called when an application command completes successfully.

519

520

Parameters:

521

- interaction: Interaction that completed

522

- command: Command that was executed

523

"""

524

pass

525

```

526

527

### Thread Events

528

529

Events for thread creation, deletion, and management.

530

531

```python { .api }

532

@client.event

533

async def on_thread_create(thread: Thread):

534

"""

535

Called when a thread is created.

536

537

Parameters:

538

- thread: Thread that was created

539

"""

540

pass

541

542

@client.event

543

async def on_thread_delete(thread: Thread):

544

"""

545

Called when a thread is deleted.

546

547

Parameters:

548

- thread: Thread that was deleted

549

"""

550

pass

551

552

@client.event

553

async def on_thread_update(before: Thread, after: Thread):

554

"""

555

Called when a thread is updated.

556

557

Parameters:

558

- before: Thread before update

559

- after: Thread after update

560

"""

561

pass

562

563

@client.event

564

async def on_thread_member_join(member: ThreadMember):

565

"""

566

Called when a member joins a thread.

567

568

Parameters:

569

- member: Thread member who joined

570

"""

571

pass

572

573

@client.event

574

async def on_thread_member_remove(member: ThreadMember):

575

"""

576

Called when a member leaves a thread.

577

578

Parameters:

579

- member: Thread member who left

580

"""

581

pass

582

583

@client.event

584

async def on_thread_join(thread: Thread):

585

"""

586

Called when the bot joins a thread.

587

588

Parameters:

589

- thread: Thread that was joined

590

"""

591

pass

592

593

@client.event

594

async def on_thread_remove(thread: Thread):

595

"""

596

Called when the bot is removed from a thread.

597

598

Parameters:

599

- thread: Thread that was left

600

"""

601

pass

602

```

603

604

### Scheduled Event Events

605

606

Events for guild scheduled events.

607

608

```python { .api }

609

@client.event

610

async def on_scheduled_event_create(event: ScheduledEvent):

611

"""

612

Called when a scheduled event is created.

613

614

Parameters:

615

- event: Scheduled event that was created

616

"""

617

pass

618

619

@client.event

620

async def on_scheduled_event_delete(event: ScheduledEvent):

621

"""

622

Called when a scheduled event is deleted.

623

624

Parameters:

625

- event: Scheduled event that was deleted

626

"""

627

pass

628

629

@client.event

630

async def on_scheduled_event_update(before: ScheduledEvent, after: ScheduledEvent):

631

"""

632

Called when a scheduled event is updated.

633

634

Parameters:

635

- before: Event before update

636

- after: Event after update

637

"""

638

pass

639

640

@client.event

641

async def on_scheduled_event_user_add(event: ScheduledEvent, user: User):

642

"""

643

Called when a user subscribes to a scheduled event.

644

645

Parameters:

646

- event: Scheduled event

647

- user: User who subscribed

648

"""

649

pass

650

651

@client.event

652

async def on_scheduled_event_user_remove(event: ScheduledEvent, user: User):

653

"""

654

Called when a user unsubscribes from a scheduled event.

655

656

Parameters:

657

- event: Scheduled event

658

- user: User who unsubscribed

659

"""

660

pass

661

```

662

663

### Auto Moderation Events

664

665

Events for Discord's auto-moderation system.

666

667

```python { .api }

668

@client.event

669

async def on_automod_rule_create(rule: AutoModRule):

670

"""

671

Called when an auto-moderation rule is created.

672

673

Parameters:

674

- rule: Auto-moderation rule that was created

675

"""

676

pass

677

678

@client.event

679

async def on_automod_rule_delete(rule: AutoModRule):

680

"""

681

Called when an auto-moderation rule is deleted.

682

683

Parameters:

684

- rule: Auto-moderation rule that was deleted

685

"""

686

pass

687

688

@client.event

689

async def on_automod_rule_update(before: AutoModRule, after: AutoModRule):

690

"""

691

Called when an auto-moderation rule is updated.

692

693

Parameters:

694

- before: Rule before update

695

- after: Rule after update

696

"""

697

pass

698

699

@client.event

700

async def on_automod_action(execution: AutoModAction):

701

"""

702

Called when an auto-moderation action is executed.

703

704

Parameters:

705

- execution: Auto-moderation action execution

706

"""

707

pass

708

```

709

710

### Raw Events

711

712

Low-level events providing raw Discord gateway data.

713

714

```python { .api }

715

@client.event

716

async def on_raw_message_edit(payload: RawMessageUpdateEvent):

717

"""

718

Called when a message is edited (raw event).

719

720

Parameters:

721

- payload: Raw message update data

722

"""

723

pass

724

725

@client.event

726

async def on_raw_message_delete(payload: RawMessageDeleteEvent):

727

"""

728

Called when a message is deleted (raw event).

729

730

Parameters:

731

- payload: Raw message delete data

732

"""

733

pass

734

735

@client.event

736

async def on_raw_bulk_message_delete(payload: RawBulkMessageDeleteEvent):

737

"""

738

Called when messages are bulk deleted (raw event).

739

740

Parameters:

741

- payload: Raw bulk delete data

742

"""

743

pass

744

745

@client.event

746

async def on_raw_reaction_add(payload: RawReactionActionEvent):

747

"""

748

Called when a reaction is added (raw event).

749

750

Parameters:

751

- payload: Raw reaction data

752

"""

753

pass

754

755

@client.event

756

async def on_raw_reaction_remove(payload: RawReactionActionEvent):

757

"""

758

Called when a reaction is removed (raw event).

759

760

Parameters:

761

- payload: Raw reaction data

762

"""

763

pass

764

765

@client.event

766

async def on_raw_reaction_clear(payload: RawReactionClearEvent):

767

"""

768

Called when reactions are cleared (raw event).

769

770

Parameters:

771

- payload: Raw reaction clear data

772

"""

773

pass

774

775

@client.event

776

async def on_raw_reaction_clear_emoji(payload: RawReactionClearEmojiEvent):

777

"""

778

Called when emoji reactions are cleared (raw event).

779

780

Parameters:

781

- payload: Raw emoji clear data

782

"""

783

pass

784

785

@client.event

786

async def on_raw_typing(payload: RawTypingEvent):

787

"""

788

Called when typing starts (raw event).

789

790

Parameters:

791

- payload: Raw typing data

792

"""

793

pass

794

795

@client.event

796

async def on_raw_member_remove(payload: RawMemberRemoveEvent):

797

"""

798

Called when a member leaves (raw event).

799

800

Parameters:

801

- payload: Raw member remove data

802

"""

803

pass

804

805

@client.event

806

async def on_raw_thread_update(payload: RawThreadUpdateEvent):

807

"""

808

Called when a thread is updated (raw event).

809

810

Parameters:

811

- payload: Raw thread update data

812

"""

813

pass

814

815

@client.event

816

async def on_raw_thread_delete(payload: RawThreadDeleteEvent):

817

"""

818

Called when a thread is deleted (raw event).

819

820

Parameters:

821

- payload: Raw thread delete data

822

"""

823

pass

824

825

@client.event

826

async def on_raw_app_command_permissions_update(payload: RawAppCommandPermissionsUpdateEvent):

827

"""

828

Called when app command permissions are updated (raw event).

829

830

Parameters:

831

- payload: Raw permissions update data

832

"""

833

pass

834

```

835

836

### Error Events

837

838

Events for handling errors and exceptions.

839

840

```python { .api }

841

@client.event

842

async def on_error(event: str, *args, **kwargs):

843

"""

844

Called when an event handler raises an uncaught exception.

845

846

Parameters:

847

- event: Name of the event that raised the exception

848

- args: Positional arguments passed to the event

849

- kwargs: Keyword arguments passed to the event

850

"""

851

pass

852

853

@client.event

854

async def on_command_error(ctx: Context, error: CommandError):

855

"""

856

Called when a command raises an error.

857

Only available when using the commands extension.

858

859

Parameters:

860

- ctx: Command context

861

- error: Error that was raised

862

"""

863

pass

864

```

865

866

## Raw Event Payloads

867

868

Raw event payload classes for low-level event handling:

869

870

```python { .api }

871

class RawMessageUpdateEvent:

872

"""Raw message update event payload."""

873

message_id: int # Message ID

874

channel_id: int # Channel ID

875

guild_id: Optional[int] # Guild ID

876

data: Dict[str, Any] # Message data

877

cached_message: Optional[Message] # Cached message if available

878

879

class RawMessageDeleteEvent:

880

"""Raw message delete event payload."""

881

message_id: int # Deleted message ID

882

channel_id: int # Channel ID

883

guild_id: Optional[int] # Guild ID

884

cached_message: Optional[Message] # Cached message if available

885

886

class RawBulkMessageDeleteEvent:

887

"""Raw bulk message delete event payload."""

888

message_ids: Set[int] # Deleted message IDs

889

channel_id: int # Channel ID

890

guild_id: Optional[int] # Guild ID

891

cached_messages: List[Message] # Cached messages if available

892

893

class RawReactionActionEvent:

894

"""Raw reaction add/remove event payload."""

895

message_id: int # Message ID

896

user_id: int # User ID

897

channel_id: int # Channel ID

898

guild_id: Optional[int] # Guild ID

899

emoji: PartialEmoji # Reaction emoji

900

member: Optional[Member] # Member who reacted (if available)

901

event_type: str # 'REACTION_ADD' or 'REACTION_REMOVE'

902

903

class RawReactionClearEvent:

904

"""Raw reaction clear event payload."""

905

message_id: int # Message ID

906

channel_id: int # Channel ID

907

guild_id: Optional[int] # Guild ID

908

909

class RawReactionClearEmojiEvent:

910

"""Raw emoji reaction clear event payload."""

911

message_id: int # Message ID

912

channel_id: int # Channel ID

913

guild_id: Optional[int] # Guild ID

914

emoji: PartialEmoji # Cleared emoji

915

916

class RawTypingEvent:

917

"""Raw typing event payload."""

918

channel_id: int # Channel ID

919

user_id: int # User ID

920

timestamp: datetime # When typing started

921

guild_id: Optional[int] # Guild ID

922

member: Optional[Member] # Member who is typing

923

924

class RawMemberRemoveEvent:

925

"""Raw member remove event payload."""

926

user: User # User who left

927

guild_id: int # Guild ID

928

929

class RawThreadUpdateEvent:

930

"""Raw thread update event payload."""

931

thread_id: int # Thread ID

932

guild_id: int # Guild ID

933

data: Dict[str, Any] # Thread data

934

thread: Optional[Thread] # Thread object if cached

935

936

class RawThreadDeleteEvent:

937

"""Raw thread delete event payload."""

938

thread_id: int # Thread ID

939

guild_id: int # Guild ID

940

parent_id: int # Parent channel ID

941

thread_type: ChannelType # Thread type

942

thread: Optional[Thread] # Thread object if cached

943

944

class RawAppCommandPermissionsUpdateEvent:

945

"""Raw app command permissions update event payload."""

946

id: int # Command ID

947

application_id: int # Application ID

948

guild_id: int # Guild ID

949

permissions: List[AppCommandPermissions] # Updated permissions

950

```

951

952

## Usage Examples

953

954

### Basic Event Handling

955

956

```python

957

import discord

958

from discord.ext import commands

959

960

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

961

962

@bot.event

963

async def on_ready():

964

print(f'{bot.user} has connected to Discord!')

965

print(f'Connected to {len(bot.guilds)} guilds')

966

967

@bot.event

968

async def on_member_join(member):

969

# Send welcome message

970

channel = discord.utils.get(member.guild.text_channels, name='welcome')

971

if channel:

972

embed = discord.Embed(

973

title=f'Welcome {member.display_name}!',

974

description=f'Welcome to {member.guild.name}!',

975

color=0x00ff00

976

)

977

embed.set_thumbnail(url=member.display_avatar.url)

978

embed.add_field(name='Member Count', value=len(member.guild.members))

979

await channel.send(embed=embed)

980

981

@bot.event

982

async def on_member_remove(member):

983

# Log member leave

984

channel = discord.utils.get(member.guild.text_channels, name='mod-log')

985

if channel:

986

embed = discord.Embed(

987

title='Member Left',

988

description=f'{member} left the server',

989

color=0xff0000,

990

timestamp=discord.utils.utcnow()

991

)

992

await channel.send(embed=embed)

993

994

@bot.event

995

async def on_message(message):

996

# Ignore bot messages

997

if message.author.bot:

998

return

999

1000

# Auto-react to messages containing "discord.py"

1001

if 'discord.py' in message.content.lower():

1002

await message.add_reaction('๐Ÿ')

1003

1004

# Process commands

1005

await bot.process_commands(message)

1006

1007

bot.run('YOUR_TOKEN')

1008

```

1009

1010

### Reaction Role System

1011

1012

```python

1013

@bot.event

1014

async def on_raw_reaction_add(payload):

1015

"""Handle reaction role assignment."""

1016

# Configuration: message_id -> {emoji: role_id}

1017

REACTION_ROLES = {

1018

123456789012345678: { # Replace with actual message ID

1019

'๐ŸŽฎ': 987654321098765432, # Gaming role ID

1020

'๐ŸŽต': 876543210987654321, # Music role ID

1021

'๐Ÿ“š': 765432109876543210, # Study role ID

1022

}

1023

}

1024

1025

if payload.message_id not in REACTION_ROLES:

1026

return

1027

1028

if payload.user_id == bot.user.id:

1029

return # Ignore bot reactions

1030

1031

guild = bot.get_guild(payload.guild_id)

1032

if not guild:

1033

return

1034

1035

member = guild.get_member(payload.user_id)

1036

if not member:

1037

return

1038

1039

emoji_str = str(payload.emoji)

1040

role_id = REACTION_ROLES[payload.message_id].get(emoji_str)

1041

1042

if role_id:

1043

role = guild.get_role(role_id)

1044

if role and role not in member.roles:

1045

try:

1046

await member.add_roles(role, reason="Reaction role")

1047

print(f"Added {role.name} to {member}")

1048

except discord.HTTPException as e:

1049

print(f"Failed to add role: {e}")

1050

1051

@bot.event

1052

async def on_raw_reaction_remove(payload):

1053

"""Handle reaction role removal."""

1054

# Same configuration as above

1055

REACTION_ROLES = {

1056

123456789012345678: {

1057

'๐ŸŽฎ': 987654321098765432,

1058

'๐ŸŽต': 876543210987654321,

1059

'๐Ÿ“š': 765432109876543210,

1060

}

1061

}

1062

1063

if payload.message_id not in REACTION_ROLES:

1064

return

1065

1066

if payload.user_id == bot.user.id:

1067

return

1068

1069

guild = bot.get_guild(payload.guild_id)

1070

if not guild:

1071

return

1072

1073

member = guild.get_member(payload.user_id)

1074

if not member:

1075

return

1076

1077

emoji_str = str(payload.emoji)

1078

role_id = REACTION_ROLES[payload.message_id].get(emoji_str)

1079

1080

if role_id:

1081

role = guild.get_role(role_id)

1082

if role and role in member.roles:

1083

try:

1084

await member.remove_roles(role, reason="Reaction role removed")

1085

print(f"Removed {role.name} from {member}")

1086

except discord.HTTPException as e:

1087

print(f"Failed to remove role: {e}")

1088

```

1089

1090

### Advanced Message Monitoring

1091

1092

```python

1093

@bot.event

1094

async def on_message_edit(before, after):

1095

"""Log message edits."""

1096

if before.author.bot:

1097

return

1098

1099

if before.content == after.content:

1100

return # No content change

1101

1102

# Log to mod channel

1103

mod_channel = discord.utils.get(before.guild.text_channels, name='mod-log')

1104

if mod_channel:

1105

embed = discord.Embed(

1106

title='Message Edited',

1107

color=0xffaa00,

1108

timestamp=after.edited_at

1109

)

1110

embed.add_field(name='Author', value=before.author.mention, inline=True)

1111

embed.add_field(name='Channel', value=before.channel.mention, inline=True)

1112

embed.add_field(name='Message ID', value=before.id, inline=True)

1113

embed.add_field(name='Before', value=before.content[:1024], inline=False)

1114

embed.add_field(name='After', value=after.content[:1024], inline=False)

1115

embed.add_field(name='Jump to Message', value=f'[Click here]({after.jump_url})', inline=False)

1116

1117

await mod_channel.send(embed=embed)

1118

1119

@bot.event

1120

async def on_message_delete(message):

1121

"""Log message deletions."""

1122

if message.author.bot:

1123

return

1124

1125

mod_channel = discord.utils.get(message.guild.text_channels, name='mod-log')

1126

if mod_channel:

1127

embed = discord.Embed(

1128

title='Message Deleted',

1129

color=0xff0000,

1130

timestamp=discord.utils.utcnow()

1131

)

1132

embed.add_field(name='Author', value=message.author.mention, inline=True)

1133

embed.add_field(name='Channel', value=message.channel.mention, inline=True)

1134

embed.add_field(name='Message ID', value=message.id, inline=True)

1135

embed.add_field(name='Content', value=message.content[:1024] or '*No content*', inline=False)

1136

1137

if message.attachments:

1138

attachments = '\n'.join([att.filename for att in message.attachments])

1139

embed.add_field(name='Attachments', value=attachments, inline=False)

1140

1141

await mod_channel.send(embed=embed)

1142

```

1143

1144

### Voice Activity Monitoring

1145

1146

```python

1147

@bot.event

1148

async def on_voice_state_update(member, before, after):

1149

"""Monitor voice activity."""

1150

1151

# Member joined voice

1152

if before.channel is None and after.channel is not None:

1153

print(f"{member} joined {after.channel}")

1154

1155

# Create temporary voice channel if joining "Create Channel" channel

1156

if after.channel.name == "โž• Create Channel":

1157

category = after.channel.category

1158

temp_channel = await after.channel.guild.create_voice_channel(

1159

name=f"{member.display_name}'s Channel",

1160

category=category,

1161

user_limit=10

1162

)

1163

await member.move_to(temp_channel)

1164

1165

# Set permissions for channel owner

1166

await temp_channel.set_permissions(member, manage_channels=True, manage_permissions=True)

1167

1168

# Member left voice

1169

elif before.channel is not None and after.channel is None:

1170

print(f"{member} left {before.channel}")

1171

1172

# Delete temporary channels when empty

1173

if before.channel.name.endswith("'s Channel") and len(before.channel.members) == 0:

1174

await before.channel.delete(reason="Temporary channel cleanup")

1175

1176

# Member moved channels

1177

elif before.channel != after.channel and before.channel is not None and after.channel is not None:

1178

print(f"{member} moved from {before.channel} to {after.channel}")

1179

1180

# Voice state changes

1181

if before.self_mute != after.self_mute:

1182

status = "muted" if after.self_mute else "unmuted"

1183

print(f"{member} {status} themselves")

1184

1185

if before.self_deaf != after.self_deaf:

1186

status = "deafened" if after.self_deaf else "undeafened"

1187

print(f"{member} {status} themselves")

1188

```

1189

1190

### Error Handling

1191

1192

```python

1193

@bot.event

1194

async def on_error(event, *args, **kwargs):

1195

"""Handle errors in event handlers."""

1196

import traceback

1197

import sys

1198

1199

print(f'Ignoring exception in {event}:', file=sys.stderr)

1200

traceback.print_exc()

1201

1202

# Log to error channel

1203

error_channel = bot.get_channel(ERROR_CHANNEL_ID)

1204

if error_channel:

1205

embed = discord.Embed(

1206

title='Event Error',

1207

description=f'Error in event: `{event}`',

1208

color=0xff0000,

1209

timestamp=discord.utils.utcnow()

1210

)

1211

embed.add_field(name='Traceback', value=f'```py\n{traceback.format_exc()[:1900]}\n```', inline=False)

1212

await error_channel.send(embed=embed)

1213

1214

@bot.event

1215

async def on_command_error(ctx, error):

1216

"""Handle command errors."""

1217

if isinstance(error, commands.CommandNotFound):

1218

return # Ignore unknown commands

1219

1220

elif isinstance(error, commands.MissingRequiredArgument):

1221

await ctx.send(f'Missing required argument: `{error.param.name}`')

1222

1223

elif isinstance(error, commands.BadArgument):

1224

await ctx.send(f'Invalid argument: {error}')

1225

1226

elif isinstance(error, commands.MissingPermissions):

1227

perms = ', '.join(error.missing_permissions)

1228

await ctx.send(f'You need the following permissions: {perms}')

1229

1230

elif isinstance(error, commands.BotMissingPermissions):

1231

perms = ', '.join(error.missing_permissions)

1232

await ctx.send(f'I need the following permissions: {perms}')

1233

1234

elif isinstance(error, commands.CommandOnCooldown):

1235

await ctx.send(f'Command is on cooldown. Try again in {error.retry_after:.2f} seconds.')

1236

1237

else:

1238

# Log unexpected errors

1239

import traceback

1240

traceback.print_exception(type(error), error, error.__traceback__)

1241

await ctx.send('An unexpected error occurred.')

1242

```