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 asyncio
2import os
3
4import dotenv
5import hikari
6import lightbulb
7
8dotenv.load_dotenv()
9
10bot = lightbulb.BotApp(
11 os.environ["BOT_TOKEN"],
12 intents=hikari.Intents.ALL,
13 prefix="+",
14 banner=None,
15)
16
17
18@bot.command
19@lightbulb.command("ping", description="The bot's ping")
20@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
21async def ping(ctx: lightbulb.Context) -> None:
22 await ctx.respond(f"Pong! Latency: {bot.heartbeat_latency*1000:.2f}ms")
23
24
25if __name__ == "__main__":
26 if os.name == "nt":
27 asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
28
29 bot.run()
Line 6 - We’ve imported lightbulb now too
- Line 10-15 - We’ve used lightbulb to create the bot, adding
a
prefix
kwarg set to"+"
, for text-based commands- a
banner
kwarg set toNone
, disabling the hikari banner that appears when the bot startsThis isn’t necessary, but the banner can get a little annoying after a while (sorry dav >_>)
Line 18-22 - Creates a command with the lightbulb bot named
ping
which works the same as the oldping
command, responding withPong!
and the bot’s heartbeat latency
Now let’s run the bot again!
You should see a slightly different output this time:
I 2022-08-13 16:40:23,476 hikari.bot: you can start 998 sessions before the next window which starts at 2022-08-13 17:23:11.910600+01:00; planning to start 1 session...
I 2022-08-13 16:40:24,051 hikari.gateway.0: shard is ready: 1 guilds, Hikari#1093 (1007678609466601492), session '9c0a984004cdf4ed7d52ee1343f44121' on v8 gateway
I 2022-08-13 16:40:24,368 lightbulb.internal: Processing guild application commands
I 2022-08-13 16:40:24,973 lightbulb.internal: Processing application commands for guild 765236394577756171
I 2022-08-13 16:40:25,250 lightbulb.internal: Processing global application commands
I 2022-08-13 16:40:25,517 lightbulb.internal: Application command processing completed
I 2022-08-13 16:40:25,520 hikari.bot: started successfully in approx 2.35 seconds
Again, if you run the command +ping
in your server, the bot should respond with it’s heartbeat latency.
Now, try typing /ping
in Discord. 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, as well as a text-based prefix command (lightbulb.PrefixCommand
).
Note
If you wanted to make your commands slash-only, you can remove the prefix kwarg on line 14 and
lightbulb.PrefixCommand
from the implements decorator.
Command Options#
Let’s make a new command using some of these option types to demonstrate them!
After your ping
command, add this:
1@bot.command
2@lightbulb.option("ping", "Role to ping with announcement.", type=hikari.Role)
3@lightbulb.option(
4 "channel", "Channel to post announcement to.", type=hikari.TextableChannel
5)
6@lightbulb.option("image", "Announcement attachment.", type=hikari.Attachment)
7@lightbulb.option("message", "The message to announce.", type=str)
8@lightbulb.command("announce", "Make an announcement!", pass_options=True)
9@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
10async def announce(
11 ctx: lightbulb.Context,
12 message: str,
13 image: hikari.Attachment,
14 channel: hikari.InteractionChannel,
15 ping: hikari.Role,
16) -> None:
17 embed = hikari.Embed(
18 title="Announcement!",
19 description=message,
20 )
21 embed.set_image(image)
22
23 await ctx.bot.rest.create_message(
24 content=ping.mention,
25 channel=channel.id,
26 embed=embed,
27 role_mentions=True,
28 )
29
30 await ctx.respond(
31 f"Announcement posted to <#{channel.id}>!", flags=hikari.MessageFlag.EPHEMERAL
32 )
- Line 2-8 - Specifying the options for our command
You can see that we’ve specified a type for each option, such as
hikari.Role
,hikari.TextableChannel
andhikari.Attachment
Using built-in Python types such as
str
andint
is also valid (Line 7)
- Line 12-15 - We’ve passed our options as parameters to the command’s function
NOTE: The parameters must be named exactly as the options
- You cannot, for example, call your
message
parametermsg
Lightbulb will error if you do so
- Line 17-21 - Create an embed, setting its description to the message our author gave, and the image to the image they chose tooWe’ll go into more detail on creating embeds in the next part (Part 3 - Making a lightbulb extension)
- Line 23-28 - Send the message to the give channel, pinging the role given in the command options
NOTE: To ping everyone with the role, you must have set
role_mentions
toTrue
, and the bot must have theMention All Roles
permission in the guild
Line 30-32 - Respond to the interaction with an
ephemeral
message, stating where the announcement has been posted