#bot.command()
async def timer(ctx,minutes:int):
import datetime
start_time = datetime.datetime.now()
end_time = start_time + datetime.timedelta(minutes=minutes)
previous_time = datetime.datetime.now()
message = await ctx.channel.send('start timer!')
try:
while datetime.datetime.now() <= end_time:
current_time = datetime.datetime.now()
if current_time.minute != previous_time.minute:
previous_time = current_time
diff = end_time - datetime.datetime.now()
diff_seconds = diff.seconds
end_time_formatted = end_time.strftime('%I:%M:%S %p')
await message.edit(
content=f'> timer\n```⏰end time:{end_time_formatted}\n⏰{diff_seconds // 60}minute {diff_seconds%60}second left```'
)
except:
await ctx.channel.send('timer reset')
await message.edit(content='> time out!')
await ctx.channel.send('on time now')
The current timer is using message deletion because there is no other way to end it. However, when deleting the message, an error message appears after a one-minute interval. However, other commands are not available until error message appears.
i looking for way to solve it.
I am making a discord bot in which an auction could take place.So I want someone to bid only once unless someone bids after him/her.
`async def bid(ctx):
embed1=discord.Embed(description= f'Bid has been placed by {ctx.author}', title='bid placed')
await ctx.send(embed=embed1)
`
That's what I have so far made.
You could put the author id in a variable:
bidderid = 0 #this will reset whenever your bot restarts
#client.command()
async def bid(ctx):
global bidderid
if ctx.author.id != bidderid: #if it is not the same bidder
bidderid = ctx.author.id
embed1=discord.Embed(description= f'Bid has been placed by {ctx.author}', title='bid placed')
await ctx.send(embed=embed1)
else: #if it is the same bidder
await ctx.send('You cannot bid twice in a row!') #replace with whatever message
note: It doesn't have to be the id, you could store ctx.author instead, idea is the same
I want my discord.py bot to go through a text file and if a user says a word in that file it will delete that message
elif msg.content == '***':
await msg.channel.send("Dont curse")
await msg.delete()
that is my code but i want to replace *** with a text document
And also another question i have some issues with an uptime command
async def on_ready():
print("Bot is running")
activity = discord.Game(name="!test", type=3)
await client.change_presence(status=discord.Status.idle, activity=activity)
channel = client.get_channel(944665750453497886)
myid = '<#516236429689618467>'
await channel.send("I am online "+myid)
#Uptime code starts
global startdate
startdate = datetime.now()
#client.command()
async def uptime(ctx):
now = datetime.now()
uptime = startdate - now
uptime = uptime.strftime('%d/%h/%M')
await ctx.send(f'Uptime: {uptime}')
I am trying to set up a command to print the information of the server the bot is in. The code below gives the error AttributeError: 'Context' object has no attribute 'guild_icon'
#commands.command()
async def serverinfo(self,ctx):
name = str(ctx.guild.name)
description = str(ctx.guild.description)
owner = str(ctx.guild.owner)
id = str(ctx.guild.id)
region = str(ctx.guild.region)
memberCount = str(ctx.guild.member_count)
embed = discord.Embed(
title=name + " Server Information",
description=description,
color=discord.Color.blue()
)
embed.set_thumbnail(ctx.guild_icon)
embed.add_field(name="Owner", value=owner, inline=True)
embed.add_field(name="Server ID", value=id, inline=True)
embed.add_field(name="Region", value=region, inline=True)
embed.add_field(name="Member Count", value=memberCount, inline=True)
await ctx.send(embed=embed)
When trying to find the solution I tried to change the code to be
#commands.command()
async def serverinfo(self,ctx):
name = str(ctx.guild.name)
description = str(ctx.guild.description)
owner = str(ctx.guild.owner)
id = str(ctx.guild.id)
region = str(ctx.guild.region)
memberCount = str(ctx.guild.member_count)
embed = discord.Embed(
title=name + " Server Information",
description=description,
color=discord.Color.blue()
)
embed.set_thumbnail(ctx.guild.icon)
embed.add_field(name="Owner", value=owner, inline=True)
embed.add_field(name="Server ID", value=id, inline=True)
embed.add_field(name="Region", value=region, inline=True)
embed.add_field(name="Member Count", value=memberCount, inline=True)
await ctx.send(embed=embed)
But then I get the error discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: set_thumbnail() takes 1 positional argument but 2 were given
Could someone tell me what I have done wrong and point me in the right direction?
Problem 1
ctx.guild_icon does not exist, you fix this in your second code by using ctx.guild.icon
Problem 2
discord.Embed.set_thumbnail takes in a named argument for the image.
In fact, it doesn't take in an image at all, but rather a url
Solution
To solve your issue, you should use the following:
embed.set_thumbnail(url=ctx.guild.icon.url)
More info
discord.ext.commands.Context
discord.Embed.set_thumbnail
I am currently working on a google cloud project in free trial mode. I have cron job to fetch the data from a data vendor and store it in the data store. I wrote the code to fetch the data couple of weeks ago and it was all working fine but all of sudden , i started receiving error "DeadlineExceededError: The overall deadline for responding to the HTTP request was exceeded" for last two days. I believe cron job is supposed to timeout only after 60 minutes any idea why i am getting the error?.
cron task
def run():
try:
config = cron.config
actual_data_source = config['xxx']['xxxx']
original_data_source = actual_data_source
company_list = cron.rest_client.load(config, "companies", '')
if not company_list:
logging.info("Company list is empty")
return "Ok"
for row in company_list:
company_repository.save(row,original_data_source, actual_data_source)
return "OK"
Repository code
def save( dto, org_ds , act_dp):
try:
key = 'FIN/%s' % (dto['ticker'])
company = CompanyInfo(id=key)
company.stock_code = key
company.ticker = dto['ticker']
company.name = dto['name']
company.original_data_source = org_ds
company.actual_data_provider = act_dp
company.put()
return company
except Exception:
logging.exception("company_repository: error occurred saving the company
record ")
raise
RestClient
def load(config, resource, filter):
try:
username = config['xxxx']['xxxx']
password = config['xxxx']['xxxx']
headers = {"Authorization": "Basic %s" % base64.b64encode(username + ":"
+ password)}
if filter:
from_date = filter['from']
to_date = filter['to']
ticker = filter['ticker']
start_date = datetime.strptime(from_date, '%Y%m%d').strftime("%Y-%m-%d")
end_date = datetime.strptime(to_date, '%Y%m%d').strftime("%Y-%m-%d")
current_page = 1
data = []
while True:
if (filter):
url = config['xxxx']["endpoints"][resource] % (ticker, current_page, start_date, end_date)
else:
url = config['xxxx']["endpoints"][resource] % (current_page)
response = urlfetch.fetch(
url=url,
deadline=60,
method=urlfetch.GET,
headers=headers,
follow_redirects=False,
)
if response.status_code != 200:
logging.error("xxxx GET received status code %d!" % (response.status_code))
logging.error("error happend for url: %s with headers %s", url, headers)
return 'Sorry, xxxx API request failed', 500
db = json.loads(response.content)
if not db['data']:
break
data.extend(db['data'])
if db['total_pages'] == current_page:
break
current_page += 1
return data
except Exception:
logging.exception("Error occured with xxxx API request")
raise
I'm guessing this is the same question as this, but now with more code:
DeadlineExceededError: The overall deadline for responding to the HTTP request was exceeded
I modified your code to write to the database after each urlfetch. If there are more pages, then it relaunches itself in a deferred task, which should be well before the 10 minute timeout.
Uncaught exceptions in a deferred task cause it to retry, so be mindful of that.
It was unclear to me how actual_data_source & original_data_source worked, but I think you should be able to modify that part.
crontask
def run(current_page=0):
try:
config = cron.config
actual_data_source = config['xxx']['xxxx']
original_data_source = actual_data_source
data, more = cron.rest_client.load(config, "companies", '', current_page)
for row in data:
company_repository.save(row, original_data_source, actual_data_source)
# fetch the rest
if more:
deferred.defer(run, current_page + 1)
except Exception as e:
logging.exception("run() experienced an error: %s" % e)
RestClient
def load(config, resource, filter, current_page):
try:
username = config['xxxx']['xxxx']
password = config['xxxx']['xxxx']
headers = {"Authorization": "Basic %s" % base64.b64encode(username + ":"
+ password)}
if filter:
from_date = filter['from']
to_date = filter['to']
ticker = filter['ticker']
start_date = datetime.strptime(from_date, '%Y%m%d').strftime("%Y-%m-%d")
end_date = datetime.strptime(to_date, '%Y%m%d').strftime("%Y-%m-%d")
url = config['xxxx']["endpoints"][resource] % (ticker, current_page, start_date, end_date)
else:
url = config['xxxx']["endpoints"][resource] % (current_page)
response = urlfetch.fetch(
url=url,
deadline=60,
method=urlfetch.GET,
headers=headers,
follow_redirects=False,
)
if response.status_code != 200:
logging.error("xxxx GET received status code %d!" % (response.status_code))
logging.error("error happend for url: %s with headers %s", url, headers)
return [], False
db = json.loads(response.content)
return db['data'], (db['total_pages'] != current_page)
except Exception as e:
logging.exception("Error occured with xxxx API request: %s" % e)
return [], False
I would prefer to write this as a comment, but I need more reputation to do that.
What happens when you run the actual data fetch directly instead of
through the cron job?
Have you tried measuring a time delta from the start to the end of
the job?
Has the number of companies being retrieved increased dramatically?
You appear to be doing some form of stock quote aggregation - is it
possible that the provider has started blocking you?