This is my first trying creating a discord bot. I want it to work like this:
User:
/roll 2d20+4
Then my bot will roll 2d20, save the sum and the bigger. Finally, it will print like this:
Output:
Bigger: 16+4=20 | Sum: 23+4=27.
This is the code I have:
import hikari
import lightbulb
import random
disc_token="..."
server_id="..."
bot=lightbulb.BotApp(
token=disc_token,
default_enabled_guilds=int(server_id)
)
#bot.command
#lightbulb.command('roll',"Role dados (exemplo: 2d20+5)")
#lightbulb.implements(lightbulb.SlashCommand)
async def roll(ctx,play):
die_split=play.split("d")
final_split=die_split[1].split("+")
n_die=int(die_split[0])
die=int(final_split[0])
extra=int(final_split[1])
play=[n_die,die,extra]
best_roll=0
sum_roll=0
for i in range(n_die):
actual_roll=random.randint(1,die)
sum_roll=sum_roll+actual_roll
if(actual_roll>best_roll):
best_roll=actual_roll
sum_roll=sum_roll+extra
extra_roll=best_roll+extra
play_print='Bigger: '+str(best_roll)+'+'+str(extra)+'='+str(extra_roll)+' | Sum: '+str(sum_roll)
await ctx.respond(play_print)
bot.run()
What is happening:
The bot is working (I tested some basic commands, like "Hello World" and works fine), but when I try to run the /roll command, for the discord user it shows:
"! The app did not answered".
At my terminal, the error was displayed like this:
Traceback (most recent call last):
File "C:\Users\MateusRochaQSOFT\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\lightbulb\app.py", line 1163, in invoke_application_command
await context.invoke()
File "C:\Users\MateusRochaQSOFT\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\lightbulb\context\base.py", line 328, in invoke
await self.command.invoke(self)
File "C:\Users\MateusRochaQSOFT\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\ligh raise new_exc
lightbulb.errors.CommandInvocationError: An error occurred during command 'roll' invocation
What could be wrong?
I think you're defining your options wrong for using the lightbulb package. You have to define the options using the #lightbulb.option decorator and can then access them via ctx.options. Where the name of the option is the property you can get.
#bot.command
#lightbulb.option("play", "dice roll")
#lightbulb.command('roll',"Role dados (exemplo: 2d20+5)")
#lightbulb.implements(lightbulb.SlashCommand)
async def roll(ctx):
play = ctx.options.play
die_split = play.split("d")
final_split = die_split[1].split("+")
n_die = int(die_split[0])
die = int(final_split[0])
extra = int(final_split[1])
play = [n_die,die,extra]
best_roll = 0
sum_roll = 0
for i in range(n_die):
actual_roll = random.randint(1, die)
sum_roll = sum_roll + actual_roll
if actual_roll > best_roll:
best_roll = actual_roll
sum_roll = sum_roll + extra
extra_roll = best_roll + extra
play_print = f"Bigger: {best_roll} + {extra} = {extra_roll} | Sum: {sum_roll}"
await ctx.respond(play_print)
bot.run()
Found in the documentation here. You can access the play variable using ctx.options.play.
I've also formatted the code to use PEP8 formatting and I used f-strings in place of the string concatenation that you were doing.
You can also use the pass_options parameter in #lightbulb.command to pass all the defined options (via decorators) as keyword arguments.
Like this:
#bot.command
#lightbulb.option("play", "dice roll")
#lightbulb.command('roll',"Role dados (exemplo: 2d20+5)", pass_options=True)
#lightbulb.implements(lightbulb.SlashCommand)
async def roll(ctx, play):
This way you don't need to do play = ctx.options.play.
Related
I am running a python script to fetch all the current order books for all symbols that ends with USDT.
Whenever I try to run it, it fetches the orderbook for the first three symbols (in this case BTCUSDT, ETHUSDT and BNBUSDT). Any takers on what I am messing up here?
I am using this logic to get a list of the symbols and the order book;
import asyncio
import config as c #from config.py
import infinity as inf #userdefined function for infinity (probably not needed)
from binance import AsyncClient, DepthCacheManager, Client
client = Client(c.API_KEY, c.API_SECRET, tld = 'com')
info = client.get_exchange_info()
symbols = info['symbols']
ls = []
for s in symbols:
if 'USDT' in s['symbol']:
#if 'BUSD' not in s['symbol']:
ls.append(s['symbol'])
async def main():
# initialise the client
client = await AsyncClient.create()
for i in ls:
async with DepthCacheManager(client, symbol= i, limit = 10000) as dcm_socket:
depth_cache = await dcm_socket.recv()
symbol = i
asks = depth_cache.get_asks()[:5]
bids = depth_cache.get_bids()[:5]
full = [symbol, asks, bids]
print(full)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
It wouldn't complete, because it's not supposed to.
DepthCacheManager is designed to establish a connection (WebSockets), get a snapshot of the order information, and then subscribes to a stream of updates to the current outstanding orders that it applies locally in it's "DepthCache". Each time that gets updated, it deliver the updated set of current asks/bids as you can see.
The trading and orders never stop, so why would it stop?
Maybe you wana try: https://github.com/LUCIT-Systems-and-Development/unicorn-binance-local-depth-cache
import unicorn_binance_local_depth_cache
ubldc = unicorn_binance_local_depth_cache.BinanceLocalDepthCacheManager(exchange="binance.com")
ubldc.create_depth_cache("LUNABTC")
asks = ubldc.get_asks("LUNABTC")
bids = ubldc.get_bids("LUNABTC")
Thats it :)
so currently I try to program a calculator but I hit a roadblock. Well, I watched a tutorial by Glowstik on how to make calculator discord bot but it seems that his code doesn't work anymore. So, can anybody suggest changes that I can make to the code to make the bot work? Thanks in advance.
Here is the code :
import discord
import os
from discord.ext import commands, tasks
from online import keep_alive
from discord_slash import SlashCommand
from itertools import cycle
from discord_components import *
import datetime
client = commands.Bot(command_prefix="!")
slash = SlashCommand(client, sync_commands=True)
status = cycle([
" Unanswered Question of Life", " Self - Referential Paradox",
" Near-infinite density?", " Dark matter ?",
" Measurement of the speed of light in one straight line",
" Schrodinger's cat ???",
"The light side of Discord is the path of many unnatural abilities"
])
#client.event
async def on_ready():
print("I have logged in as {0.user}".format(client))
status_swap.start()
DiscordComponents(client)
buttons = [[
Button(style=ButtonStyle.grey, label='1'),
Button(style=ButtonStyle.grey, label='2'),
Button(style=ButtonStyle.grey, label='3'),
Button(style=ButtonStyle.blue, label='+'),
Button(style=ButtonStyle.red, label='Clear')
],
[
Button(style=ButtonStyle.grey, label='4'),
Button(style=ButtonStyle.grey, label='5'),
Button(style=ButtonStyle.grey, label='6'),
Button(style=ButtonStyle.blue, label='-'),
Button(style=ButtonStyle.red, label='Exit')
],
[
Button(style=ButtonStyle.grey, label='7'),
Button(style=ButtonStyle.grey, label='8'),
Button(style=ButtonStyle.grey, label='9'),
Button(style=ButtonStyle.blue, label='×'),
Button(style=ButtonStyle.red, label='←')
],
[
Button(style=ButtonStyle.grey, label='00'),
Button(style=ButtonStyle.grey, label='0'),
Button(style=ButtonStyle.grey, label='.'),
Button(style=ButtonStyle.blue, label='÷'),
Button(style=ButtonStyle.red, label='=')
]]
def calculator(exp):
o = exp.replace('×', '*')
o = o.replace('÷', '/')
result = " "
try:
result = str(eval(o))
except:
result = "An error occurs"
return result
#client.command()
async def operator(ctx):
m = await ctx.send(content="Loading calculator")
expression = "None"
delta = datetime.datetime.utcnow() + datetime.timedelta(minutes = 5)
e = discord.Embed(title="Basic Operation Calculator",description=expression)
await m.edit(components=buttons, embed=e)
while True :
res = await client.wait_for("button click")
while m.created_at < delta :
if res.author.id == int(res.message.embeds[0].title.split("|")[1]) and res.message.embeds[0].timestamp < delta:
expression = res.message.embeds[0].description
if expression == "None" or expression == 'An error occurs':
expression = ''
elif res.component.label == 'Exit':
await res.respond(content='Calculator Closed. Thanks for using Basic Operation Calculator.',type=7)
break
elif res.component.label == "←":
expression = expression[:-1]
elif res.component.label == 'Clear':
expression = None
elif res.component.label == '=':
expression += calculator(expression)
else:
expression = res.component.label
f = discord.Embed(title='Basic Operation Calculator',description=expression)
await res.respond(content='', embed = f, component=buttons, type=7)
# tasks.loop(minutes=5)
async def status_swap():
await client.change_presence(activity=discord.Game(next(status)))
keep_alive()
client.run(os.getenv('MATH_VAR'))
This code looks like it was taken from https://www.youtube.com/watch?v=3BGcgSm9sv0
which coincidentally I have also used.
Your problem arises from your embed title because it's based around your title having a '|' followed by the user's ID.
try changing the embed title from "Basic Operation Calculator" to f"{ctx.message.author}'s calculator|{ctx.message.author.id}" and tell me if that works. I've modified the code I'm using slightly, so this might be wrong, I'm going off of memory here. If that does work, also try f"Basic Operation Calculator|{ctx.message.author.id}" if you want to keep your title name.
This isn't needed but if you also want to add a sliver of text after the '|', you need to change the split statement in
if res.author.id == int(res.message.embeds[0].title.split("|")[1]) and res.message.embeds[0].timestamp < delta:
to the '|' and any text (thats not the ID) directly after.
so if I want to add "ID: " after, then the split statement would be "| ID: ". Sorry if this sounds confusing, the way this code works is very specific, and I'm pretty new to Stack Overflow. Let me know if you run into any errors or have any questions. If nothing else works I'm happy to send you my current code I'm using since It's only slightly modified. Next time you post a question, try your best to be as specific as possible with your question.
I'm coding 10 discord bots for fun, all of these have the same code, (but different token) how can I run all bots with 1 code? Thank you.
import random
import time
import discord
from discord.ext import commands
messaggio = "ti sto dando fastidio?"
client = client = commands.Bot(command_prefix = "()")
Client = discord.Client()
#client.event
async def on_ready():
print("Sono online e pronto ad infastidire")
#client.command() #Invia messaggi in privato ad un utente taggato.
async def infastidisci(ctx, member : discord.Member, numero_di_messaggi = 1):
for x in range(numero_di_messaggi):
y = random.uniform(0.25, 1.50)
time.sleep(y)
print(f"Messaggio inviato a {member}. Messaggi restanti: ", numero_di_messaggi - x - 1)
await member.send(messaggio)
#client.command()
async def infastidisci_chat(ctx, numero_di_messaggi = 1):
for x in range(numero_di_messaggi):
messaggio_fastidioso = "#everyone vi sto dando fastidio?"
canali = ctx.message.guild.text_channels
y = random.uniform(0.25, 1.50)
time.sleep(y)
for canale in canali:
await canale.send(messaggio_fastidioso)
print(f"Messaggio inviato in {canale}. Messaggi restanti: {numero_di_messaggi - x -1}")
client.run(token)
One method:
You retrieve the token from an environment variable:
import os
token = os.environ.get("TOKEN", None)
You execute your program from command line with:
TOKEN=mytoken python3 main.py
What changed here is you have to define the environment variable TOKEN.
Now you can just execute the process multiple time. You can also wrap it in a single command line
TOKEN=mytoken1 python3 main.py & TOKEN=mytoken2 python3 main.py
Writing a python script that sets up pickup games. srv.connect() will time out if the IP/RCON are put in wrong and/or the server is down altogether. I do not want the discord bot to crash just because a server is down so I am trying to use a try/except to keep the bot going. A person can start a pickup by typing !pickup size 4 servername ... and if srv.connect() can not get a handshake with the server, itll time out and send a message in discord saying it can not find the server. Then they could do !pickup size 4 servername2 and itll work. Problem right now is that after doing !pickup size 4 servername it seems stuck on saying the rcon/ip is down even though servername2 should be running just fine. Any help?
if(message.content.startswith('!pickup size')):
if(pickupActive == 0):
x = message.content.split()
if(len(x) >= 4):
pServer = x[3]
if(pServer in servers):
srv = Console(host=servers[pServer][0], port= servers[pServer][1], password=servers[pServer][2])
try:
srv.connect()
servercfg = srv.execute("servercfgfile")
#print(servers[pServer][3])
if (servers[pServer][3] in servercfg): #and (pickupActive == 0)): #change "server.cfg" to whatever your server configurtion filename is for pickup play. keep the quotations
totalPlayers = [" "] * int(x[2])
initialPlayerCount = len(totalPlayers)
pickupLeader = message.author.name
totalPlayers.insert(playerCount, pickupLeader)
totalPlayers.remove(" ")
PopulateTable()
await message.channel.send("```Pickup Game Starting! " + pickupLeader + " is the leader for the Pickup Game! Come join in! type '!pickup add' to join```")
await message.channel.send("```" + msg + "```")
pickupActive = 1
else:
await message.channel.send("`" + servers[pServer][4] + "`")
except:
await message.channel.send("Can not connect to the server for rcon..")
srv.disconnect()
else:
await message.channel.send("`Please specify the size of the pickup and a valid server name..`")
else:
await message.channel.send("`Proper formatting not used, please say !pickup size # server (Example: !pickup size 3 nwo)`")
else:
await message.channel.send("`Already a pickup game in progress, please add up to the current pickup game..`")
Not sure if its the lack of coffee, but I'm having a slight issue with uploading random images.
#client.command(aliases=['cuddle'])
async def _cuddle(ctx, *, user):
image= [
'file_1.gif',
'file_2.gif',
'file_3.gif',
'file_4.gif',
'file_5.gif',
'file_6.gif',
'file_7.gif']
await ctx.send(f'You got a Cuddle from{ctx.message.author.mention}, {user}!\n {random.choice(file =discord.file(image))}')
its mostly the
{random.choice(file =discord.file(image))}
ive tryed
discord.file'file_1.gif', method but with no prevail.
I've solved it for anyone who wants to know
import os
#commands.command(aliases=['image'])
async def images(self, ctx):
image = os.listdir('./cogs/image/')
imgString = random.choice(image) # Selects a random element from the list
path = "./cogs/image/" + imgString
await ctx.send(file=discord.File(path))