Part 2 - Lightbulb Bot#
Lightbulb is a command handler for Hikari, making it easy to create commands.
So to start using Lightbulb, let’s change our bot.py
a little (new code has been highlighted):
1import os
2from typing import Optional
3
4import dotenv
5import hikari
6import lightbulb
7from hikari import Intents
8
9dotenv.load_dotenv()
10
11INTENTS = Intents.GUILD_MEMBERS | Intents.GUILDS
12
13bot = lightbulb.BotApp(
14 os.environ["BOT_TOKEN"],
15 intents=INTENTS,
16 banner=None,
17)
18
19
20@bot.command
21@lightbulb.command("ping", description="The bot's ping.")
22@lightbulb.implements(lightbulb.SlashCommand)
23async def ping(ctx: lightbulb.SlashContext) -> None:
24 await ctx.respond(f"Pong! Latency: {bot.heartbeat_latency * 1000:.2f}ms.")
25
26
27if __name__ == "__main__":
28 bot.run()
Line 2 & 6-7 - Import Optional from typing, lightbulb, and Intents from hikari
Line 11 - Set up the intents we want to use
Read the docs - IntentsLine 13-17 - Use lightbulb to create the bot now,
passing our bot’s token as before
changing the
intents
kwarg to use our new set of intentsadding a
banner
kwarg set toNone
, disabling the hikari banner shown when the bot startsThis isn’t necessary, but the banner can get a little annoying after a while (sorry dav >_>)
Line 20-24 - Create a slash command with lightbulb named
ping
which works the same as the oldping
command, responding withPong!
and the bot’s heartbeat latency
Note
The GUILD_MEMBERS
intent must be enable on the developer portal for your bot to use them.
Now let’s run the bot again!
You should see a slightly different output this time:
I 2022-12-24 13:24:37,209 hikari.bot: you can start 998 sessions before the next window which starts at 2022-12-25 12:55:43.325554+00:00; planning to start 1 session...
I 2022-12-24 13:24:37,808 hikari.gateway.0: shard is ready: 2 guilds, Hikari#1093 (1007678609466601492), session '9432e40babfaa02547b09cf16b23ac98' on v10 gateway
I 2022-12-24 13:24:38,216 lightbulb.internal: Processing guild application commands
I 2022-12-24 13:24:38,216 lightbulb.internal: Processing global application commands
I 2022-12-24 13:24:38,567 lightbulb.internal: Application command processing completed
I 2022-12-24 13:24:38,567 hikari.bot: started successfully in approx 1.78 seconds
Trying to run @bot ping
will no longer work, as we’ve removed the code for that. However, you now have the slash command /ping
!
Try typing /ping
. A command should appear, with your bot’s avatar next to it:
Hit enter, and let’s run this new command!
We’ve just made a slash command! By passing lightbulb.SlashCommand
to the @lightbulb.implements
decorator, lightbulb will turn the command into a slash command.
Command Options#
Slash Commands can have options, and Discord supports quite a few different options types.
Read the docs - Command Option Types
Let’s make a new slash command using some of these option types to demonstrate them!
After your ping
command, add this:
1@bot.command
2@lightbulb.option(
3 "ping", "Role to ping with announcement.", type=hikari.Role, required=False
4)
5@lightbulb.option(
6 "image", "Announcement attachment.", type=hikari.Attachment, required=False
7)
8@lightbulb.option(
9 "channel", "Channel to post announcement to.", type=hikari.TextableChannel
10)
11@lightbulb.option("message", "The message to announce.", type=str)
12@lightbulb.command("announce", "Make an announcement!", pass_options=True)
13@lightbulb.implements(lightbulb.SlashCommand)
14async def announce(
15 ctx: lightbulb.SlashContext,
16 message: str,
17 channel: hikari.GuildTextChannel,
18 image: Optional[hikari.Attachment] = None,
19 ping: Optional[hikari.Role] = None,
20) -> None:
21 embed = hikari.Embed(
22 title="Announcement!",
23 description=message,
24 )
25 embed.set_image(image)
26
27 await ctx.app.rest.create_message(
28 channel=channel.id,
29 content=ping.mention if ping else hikari.UNDEFINED,
30 embed=embed,
31 role_mentions=True,
32 )
33
34 await ctx.respond(
35 f"Announcement posted to <#{channel.id}>!", flags=hikari.MessageFlag.EPHEMERAL
36 )
Line 2-11 - Specify the options for our command
We’ve specified a type for each option, such as
hikari.Role
,hikari.Attachment
andhikari.TextableChannel
Using built-in Python types such as
str
andint
is also valid (Line 11)
Line 16-19 - Pass the options as parameters to the command’s function.
You must specify
pass_options=True
in the command decorator (Line 12) when passing the options as function parameters, or else lightbulb will error when attempting to run your command.
Warning
The parameters must be named exactly as the options. You cannot, for example, name your
message
parameter “msg
”. Lightbulb will error if you do so.Line 21-25 - Create an embed, setting its description and image to the message and attachment the command author provided
We’ll look at embeds in more detail in the next partLine 27-32 - Send the message to the given channel, pinging the role (if provided in the command options)
Note
To ping everyone with the role, you must have set
role_mentions
toTrue
, and the bot must have the permissions to mention the role in the guildLine 34-36 - Respond to the interaction with an
ephemeral
message, stating where the announcement has been posted