So, I made some code that takes events from a google calendar and organizes them then posts them on discord. The main problem is this: client.send_message(client.get_channel('483988804370169857'),"None")
When using this code in a #client.event it works fine, the problem begins when i put it in a normal function. I need it in a normal function so that it runs once every 24 hours. No errors, no nothing. The code just goes through the function and doesn't send the message. How can I fix this?
from __future__ import print_function
import json
import datetime
import discord
from discord.ext import commands
from datetime import timedelta
import gspread
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
from discord.ext import commands
import threading
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
client = discord.Client()
def Hw():
print("HW")
now = datetime.datetime.now()
run_at = now + timedelta(hours=3)
delay = (run_at - now).total_seconds()
#Begin Google Calander API
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('calendar', 'v3', http=creds.authorize(Http()))
now = datetime.datetime.utcnow().isoformat() + 'Z'
#Retrieve all Events
events_result = service.events().list(calendarId='CENSORED', timeMin=now,maxResults=250, singleEvents=True,orderBy='startTime').execute()
events = events_result.get('items', [])
#Currentmode stores if searching for tommorow, the week, or other (1,2,3)
Currentmode = 0
UMode=1
none = True
#Gets end of week
dt = datetime.datetime.now()
startweek = dt - timedelta(days=dt.weekday())
endweek = startweek + timedelta(days=6)
dtstring = str(dt.date())
TheMessages = "**" + dtstring + " Report**"
client.send_message(client.get_channel('483988804370169857'),TheMessages)
if not events:
client.send_message(client.get_channel('483988804370169857'), 'No upcoming events found.')
for event in events:
if Currentmode == 0:
client.send_message(client.get_channel('483988804370169857'),"*Due Tommorow*")
Currentmode = 1
thestr = event['start'].get('dateTime')
count = 0
count2 = 0
for x in thestr:
count += 1
if x == "-":
count2 +=1
if count2 == 3:
break
count = count - 1
thestr = thestr[0:count]
start = datetime.datetime.strptime(thestr, "%Y-%m-%dT%H:%M:%S")
if (start - dt).days <= 7 and Currentmode == 1:
if UMode == 1:
client.send_message(client.get_channel('483988804370169857'),"None")
client.send_message(client.get_channel('483988804370169857'),"*Due in the Next 7 Days*")
UMode = 2
Currentmode = 2
elif (start - dt).days >= 7 and (Currentmode == 1 or Currentmode == 2):
if UMode == 1:
client.send_message(client.get_channel('483988804370169857'),"None")
client.send_message(client.get_channel('483988804370169857'),"*Due in the Next 7 Days*")
client.send_message(client.get_channel('483988804370169857'),"None")
client.send_message(client.get_channel('483988804370169857'),"*Longterm*")
Currentmode = 3
UMode = 3
FirstMessage = str(start.date())
SecondMessage = event['summary']
ThirdMessage= FirstMessage + " " + SecondMessage
client.send_message(client.get_channel('483988804370169857'),ThirdMessage)
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!hello'):
msg = 'Hello {0.author.mention}'.format(message)
await client.send_message(message.channel, msg)
#client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
now = datetime.datetime.now()
run_at = now + timedelta(seconds=1)
delay = (run_at - now).total_seconds()
threading.Timer(delay, Hw).start()
#Run client and start daily timer
client.run('CENSORED')
Related
How can I aggregate the levels of the orderbook?
Now it gets streamed every 0.05 tick but I need to stream this every 0.50 interval of price.
How can I unite the various levels on the orderbook?
This is the code:
from time import sleep
from pybit import usdt_perpetual
ws_linear = usdt_perpetual.WebSocket(
test=False,
ping_interval=30, # the default is 30
ping_timeout=10, # the default is 10
domain="bybit" # the default is "bybit"
)
def handle_message(msg):
print(msg)
ws_linear.orderbook_25_stream(
handle_message, "ETHUSDT"
)
while True:
sleep(1)
Thank you
Here you have usable orderbook if it helps.
Note: this code is not the cleanest, but it gets the job done.
import hmac
import json
import threading
import time
import websocket
ws_url = "wss://stream.bybit.com/realtime_public"
api_key = ""
api_secret = ""
order_book = []
orderbook = []
orderbook_size = []
orderbook_array_length = 1000
data = []
# Generate expires.
expires = int((time.time() + 1) * 1000)
# Generate signature.
signature = str(hmac.new(
bytes(api_secret, "utf-8"),
bytes(f"GET/realtime{expires}", "utf-8"), digestmod="sha256"
).hexdigest())
param = "api_key={api_key}&expires={expires}&signature={signature}".format(
api_key=api_key,
expires=expires,
signature=signature
)
url = ws_url + "?" + param
def on_message(ws, message):
global orderbook
global orderbook_size
message = json.loads(message)
for i in range(0, max(len(message['data']['update']), len(message['data']['insert']), len(message['data']['delete'])), 1):
if len(message['data']['update']) != 0 and i < len(message['data']['update']):
orderbook_size.append((message['data']['update'][i]['price'], message['data']['update'][i]['size'], message['data']['update'][i]['symbol']))
if len(orderbook_size) > orderbook_array_length:
del (orderbook_size[0])
data_append = [(message['data']['update'][i]['price'], message['data']['update'][i]['side'], message['data']['update'][i]['symbol'])]
if message['data']['update'][i]['side'] == 'Buy':
data_append_opposite = [(message['data']['update'][i]['price'], 'Sell', message['data']['update'][i]['symbol'])]
else:
data_append_opposite = [(message['data']['update'][i]['price'], 'Buy', message['data']['update'][i]['symbol'])]
if data_append_opposite[0] in orderbook:
orderbook.remove(data_append_opposite[0])
if data_append[0] not in orderbook:
orderbook.append((message['data']['update'][i]['price'], message['data']['update'][i]['side'], message['data']['update'][i]['symbol']))
orderbook.sort(key=lambda x: x[0])
if len(message['data']['insert']) != 0 and i < len(message['data']['insert']):
orderbook_size.append((message['data']['insert'][i]['price'], message['data']['insert'][i]['size'], message['data']['insert'][i]['symbol']))
if len(orderbook_size) > orderbook_array_length:
del (orderbook_size[0])
orderbook.append((message['data']['insert'][i]['price'], message['data']['insert'][i]['side'], message['data']['insert'][i]['symbol']))
orderbook.sort(key=lambda x: x[0])
if len(message['data']['delete']) != 0 and i < len(message['data']['delete']):
data_remove = [(message['data']['delete'][i]['price'], message['data']['delete'][i]['side'], message['data']['delete'][i]['symbol'])]
if data_remove[0] in orderbook:
orderbook.remove(data_remove[0])
def on_error(ws, error):
print(f"Error: {error}")
def on_close(ws):
print(f"Connection close")
def on_open(ws):
ws.send('{"op": "subscribe", "args": ["orderBookL2_25.BTCUSDT"]}')
print("Opened connection")
ws = websocket.WebSocketApp(url, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close)
wst = threading.Thread(target=ws.run_forever)
wst.daemon = True
wst.start()
while True:
time.sleep(1)
order_book = []
try:
for i in range(0, len(orderbook), 1):
# entire orderbook
for s in range(-1,len(orderbook_size)* -1, -1):
if orderbook[i][0] == orderbook_size[s][0]:
order_book.append((orderbook[i][0], orderbook[i][1], orderbook_size[s][1]))
break
# orderbook with depth of 1
if orderbook[i - 1][1] == 'Buy' and orderbook[i][1] == 'Buy' and orderbook[i + 1][1] == 'Sell' and orderbook[i + 2][1] == 'Sell':
for r in range(i, len(orderbook), 1):
if len(orderbook) > r > i+25:
del (orderbook[r])
if r >= len(orderbook):
break
for r in range(i, 0, -1):
if 0 < r < i-25:
del (orderbook[r])
if r >= len(orderbook):
break
for s in range(-1,len(orderbook_size)* -1, -1):
if orderbook[i][0] == orderbook_size[s][0]:
data.append((orderbook[i][0], orderbook[i][1], orderbook_size[s][1]))
break
for s in range(-1,len(orderbook_size)* -1, -1):
if orderbook[i+1][0] == orderbook_size[s][0]:
data.append((orderbook[i + 1][0], orderbook[i + 1][1], orderbook_size[s][1]))
break
print(data)
data = []
print(order_book)
except Exception as error:
print(error)
I want to track the time spent in vc by users but after a while of checking, we see that their time has reduced which makes no sense. I want to check 3 channels every minute for which members are inside those channels and in the member_info list, increase the time stored in member_info[member_index][1] if they are in one of the 3 channels. I can't understand why the total time is reducing if I only add values to the list and if the file is only read to initialise the list.
member_info = []
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix='$', intents = intents)
#bot.event
async def on_ready():
print("We have logged in as {0.user}".format(bot))
global member_info
f = open("times.txt")
content = f.readlines()
for i in range (0, len(content)):
content[i] = content[i].split(", ")
content[i][0] = int(content[i][0])
content[i][1] = int(content[i][1].strip())
member_info.append(content[i])
print(member_info)
track_user_time.start()
update_file.start()
#bot.command()
async def myTime(ctx):
author = ctx.author.id
global member_info
for b in range (0, len(member_info)):
if (member_info[b][0] == author):
time_spent = member_info[b][1]
user_days = time_spent // 3600
user_hours = (time_spent - (user_days*3600)) // 60
user_minutes = time_spent - (user_days*3600) - (user_hours *60)
time_msg = f"""
Time Spent by: {ctx.author.name}
Days Spent Studying: {user_days} day(s)
Hours Spent Studying: {user_hours} hour(s)
Minutes Spent Studying: {user_minutes} minutes
"""
await ctx.send(time_msg)
#tasks.loop(seconds=60)
async def track_user_time():
global member_info
active_members = []
await bot.wait_until_ready()
channel = bot.get_channel(868830478705233993)
members = channel.members
for k in range (0, len(members)):
if (members[k].id not in active_members):
active_members.append(members[k].id)
#find their id for each work channel
#look for corresponding id in member_info
#add 1 minute to their time spent studying
channel = bot.get_channel(868835241958182984)
members = channel.members
for p in range (0, len(members)):
if (members[p].id not in active_members):
active_members.append(members[p].id)
channel = bot.get_channel(868835476147146752)
members = channel.members
for o in range (0, len(members)):
if (members[o].id not in active_members):
active_members.append(members[o].id)
print(active_members)
for f in range (0, len(member_info)):
for y in range(0, len(active_members)):
if (member_info[f][0] == active_members[y]):
member_info[f][1] = member_info[f][1] + 1
print("working")
#tasks.loop(seconds = 90)
async def update_file():
await bot.wait_until_ready()
f = open('times.txt', 'w')
for q in range(0, len(member_info)):
file_info = str(member_info[q][0]) + ", " + str(member_info[q][1]) + "\n"
f.write(file_info)
print("updated")
thats my cog file levelsys.py
import discord
from discord.ext import commands
from pymongo import MongoClient
general = [825768173730660404]
bot_channel = 825871367575830548
level = ["Level 1", "Level 2", "Level 3"]
levelnum = [5, 10, 15]
cluster = MongoClient(
"mongodb+srv://my username:<my password>#bot.orejh.mongodb.net/myFirstDatabase?retryWrites=true&w=majority")
levelling = cluster["discord"], ["levelling"]
class levelsys(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_message(self, message):
if message.channel.id in general:
stats = levelling.find_one({"id": message.author.id})
if not message.author.bot:
if stats is None:
newuser = {"id": message.author.id, "xp": 100}
levelling.insert_one(newuser)
else:
xp = stats["xp"] + 5
levelling.update_one({"id": message.author.id}, {"$set": {"xp": xp}})
lvl = 0
while True:
if xp < ((50 * (lvl ** 2)) + (50 * lvl)):
break
lvl += 1
xp -= ((50 * ((lvl - 1) ** 2)) + (50 * (lvl - 1)))
if xp == 0:
await message.channel.send(
f"well done {message.author.mention}! You leveled up to **level: {lvl}**!")
for i in range(len(level)):
if lvl == levelnum[i]:
await message.author.add_roles(
discord.utils.get(message.author.guild.roles, name=level[i]))
embed = discord.Embed(
description=f"{message.author.mention} you have gotten role **{level[i]}**!!!")
embed.set_thumbnail(url=message.author.avatar_url)
await message.channel.send(embed=embed)
#commands.command()
async def rank(self, ctx):
if ctx.channel.id == bot_channel:
stats = levelling.find_one({"id": ctx.author.id})
if stats is None:
embed = discord.Embed(description="You haven't sent any messages, no rank!!!")
await ctx.channel.send(embed=embed)
else:
xp = stats["xp"]
lvl = 0
rank = 0
while True:
if xp < ((50 * (lvl ** 2)) + (50 * lvl)):
break
lvl += 1
xp -= ((50 * ((lvl - 1) ** 2)) + (50 * (lvl - 1)))
boxes = int((xp / (200 * ((1 / 2) * lvl))) * 20)
rankings = levelling.find().sort("xp", -1)
for x in rankings:
rank += 1
if stats["id"] == x["id"]:
break
embed = discord.Embed(title="{}'s level stats".format(ctx.author.name))
embed.add_field(name="Name", value=ctx.author.mention, inline=True)
embed.add_field(name="XP", value=f"{xp}/{int(200 * ((1 / 2) * lvl))}", inline=True)
embed.add_field(name="Rank", value=f"{rank}/{ctx.guild.member_count}", inline=True)
embed.set_thumbnail(url=ctx.author.avatar_url)
await ctx.channel.send(embed=embed)
#commands.command()
async def leaderboard(self, ctx):
if (ctx.channel.id == bot_channel):
rankings = levelling.find().sort("xp", -1)
i = 1
embed = discord.Embed(title="Rankings:")
for x in rankings:
try:
temp = ctx.guild.get_member(x["id"])
tempxp = x["xp"]
embed.add_field(name=f"{i}: {temp.name}", value=f"Total XP: {tempxp}", inline=False)
i += 1
except:
pass
if i == 11:
break
await ctx.channel.send(embed=embed)
def setup(client):
client.add_cog(levelsys(client))
error message:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\Kacper\.virtualenvs\Nocne_Farfocle\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "D:\Programming\Python\Nocne_Farfocle\levelsys.py", line 25, in on_message
stats = levelling.find_one({"id": message.author.id})
AttributeError: 'tuple' object has no attribute 'find_one'
I'm using python 3.9.1, discord 1.0.1, discord.py 1.6.0, dnspython 2.1.0 and pymongo 3.11.3
I'm trying to make a custom discord bot, and that's one of modules for this bot, i'm stuck wit this error for like 3 days now, soo i would really like to get any tips from you guys :D
I think the answer is that leveling is one variable to which you assigned 2 values. This makes it into a tuple. therefore, when you try to run find_one on the tuple, it can't because it isn't the object you wanted it to be.
sidenote: a similar thing happens if you make a method return value1, value2. In python, that is considered a tuple.
So, I found this question I want to make a multi-page help command using discord.py
But the answer make me a doubt. I tried a similar code to just try this thing, but while the loop is going on I literally can't use any of the other commands. What should I do in order to permit all the commands work while the loop is going on?
import discord
import datetime
from datetime import timedelta
import pytz
from discord.ext import commands
client = discord.Client()
client = commands.Bot(command_prefix = "!")
prefix = "!"
id = client.get_guild(766402039495262218)
#client.event
async def on_ready():
print("Bot is ready")
game = discord.Game("Could I Destroy a Server...?")
await client.change_presence(status=discord.Status.idle, activity=game)
#client.event
async def on_message(message):
await client.process_commands(message)
#client.event
async def on_reaction_add(reaction, user):
channel = reaction.message.channel
if reaction.emoji == '➡':
if reaction.message.embeds == discord.embeds.Embed(title='Corsi Informatica I Anno'):
await channel.send("ok")
print("ok")
else:
print(reaction.message.embeds)
print("not ok")
else:
await channel.send("YOLO")
#client.command(pass_context = True)
async def test(ctx):
await ctx.message.channel.send("this is a testing test")
#client.command(pass_context=True)
async def corsi(ctx):
page = 1
left_arrow = '⬅'
right_arrow = '➡'
first_year = discord.Embed(
title = 'Corsi Informatica I Anno',
description = 'Lista dei corsi:',
colour = discord.Colour.dark_blue()
)
second_year = discord.Embed(
title = 'Corsi Informatica II Anno',
description = 'Lista dei corsi:',
colour = discord.Colour.dark_green()
)
third_year = discord.Embed(
title = 'Corsi Informatica III Anno',
description = 'Lista dei corsi:',
colour = discord.Colour.dark_red()
)
first_year.set_footer(text = datetime.datetime.now().strftime('%d/%m/%Y %H:%M') + "\t\t\t\t\t\t\t\t\t\t\t\t\t" + "pag." + " " + str(page)+"/3")
first_year.set_author(name = ctx.message.author)
first_year.add_field(name = 'Calcolo I', value = 'I Semestre', inline = True)
first_year.add_field(name = 'Algebra Lineare', value='I Semestre', inline = True)
first_year.add_field(name ='Programmazione I', value='I Semestre', inline=True)
first_year.add_field(name='--------------------------------------------------------------------------',value="**--------------------------------------------------------------------------**"
,inline=False)
first_year.add_field(name ='Elaboratori I', value='I Semestre', inline = True)
first_year.add_field(name ='Matematica Discreta', value='I Semestre', inline = True)
first_year.add_field(name ='Programmazione II', value='II Semestre', inline = True)
first_year.add_field(name='--------------------------------------------------------------------------',value="**--------------------------------------------------------------------------**",
inline=False)
first_year.add_field(name ='Elaboratori II', value='II Semestre', inline = True)
first_year.add_field(name ='Calcolo II', value='II Semestre', inline = True)
first_year.add_field(name ='Inglese', value='II Semestre', inline = True)
second_year.set_footer(text = datetime.datetime.now().strftime('%d/%m/%Y %H:%M') + "\t\t\t\t\t\t\t\t\t\t\t\t\t" + "pag." + " " + str(page)+"/3")
second_year.set_author(name = ctx.message.author)
third_year.set_footer(text = datetime.datetime.now().strftime('%d/%m/%Y %H:%M') + "\t\t\t\t\t\t\t\t\t\t\t\t\t" + "pag." + " " + str(page)+"/3")
third_year.set_author(name = ctx.message.author)
while True:
if page == 1:
sent = await ctx.message.channel.send(client.get_channel("795387716967333889"), embed=first_year)
await sent.add_reaction(right_arrow)
page = 4
# Do not do nothing until user use a reaction
elif page == 2:
sent = await ctx.message.channel.send(client.get_channel("795387716967333889"), embed=second_year)
await sent.add_reaction(left_arrow)
await sent.add_reaction(right_arrow)
elif page == 3:
sent = await ctx.message.channel.send(client.get_channel("795387716967333889"), embed=third_year)
await sent.add_reaction(left_arrow)
Instead of using a while True loop that blocks your processing, you should make use of the on_reaction_add event to watch for added reactions. You can identify the embed by checking the embed title & embed poster (your bot).
Documentation can be found here here
I can't use !giveaway command when I use host.
When I'm running this command using cmd, it works great but when I'm trying to run this command using Heroku host, it doesn't work and heroku logs command doesn't returnes me any errors. I don't know what to do.
How to fix that? Help me, please.
Here is the command code:
#bot.command(aliases=["giveaway-start", "розыгрыш-начать"])
async def __giveaway_start(ctx, duration: int, sign: str, channel: discord.TextChannel, *, prize: str):
with open('C:\\bot1\\giveaways.json', 'r') as f:
givs = json.load(f)
async def new_id(givs,g_id):
if g_id in givs:
new_g_id += random.choice(giveaway_id)
giveaway_id = '1234567890'
for n in range(1):
g_id = ''
for i in range(16):
g_id += random.choice(giveaway_id)
if g_id in givs:
await ctx.send("Попробуйте позже")
if sign == "с":
wait = 1 * duration
elif sign == "м":
wait = 60 * duration
elif sign == "ч":
wait = 3600 * duration
elif sign == "д":
wait = 86400 * duration
emoji = "🎉"
if duration == 0:
return
embed = discord.Embed(title=prize, description=f"Автор - {ctx.author.mention}\n"f"**Нажмите на :tada: чтобы принять участие!**\n"f"Времени осталось: {wait} секунд",color=discord.Color.blue(),timestamp=datetime.utcnow())
message = await channel.send(embed=embed)
async def update_data(givs,g_away):
if not g_away in givs:
givs[g_away] = {}
givs[g_away]["msg_id"] = message.id
await ctx.send(f"Розыгрыш в канале {channel.mention} успешно создан! ID розыгрыша: `{g_id}`. Я напишу Вам в ЛС когда розыгрыш закончится.\nТак же можете присоединиться к нашему серверу тех. поддержки! https://discord.gg/YUzE6rB")
await message.add_reaction(emoji)
await update_data(givs,str(g_id))
with open('C:\\bot1\\giveaways.json', 'w') as f:
json.dump(givs,f)
while wait:
await asyncio.sleep(1)
if wait == 0:
await ctx.send("Giveaway is over!")
else:
wait -= 1
if wait > 86400:
cld = wait / 86400
time = "дней"
cooldown = round(cld, 1)
elif wait > 3600:
cld = wait / 3600
time = "часов"
cooldown = round(cld, 1)
elif wait > 60:
cld = wait / 60
time = "минут"
cooldown = round(cld, 1)
else:
cld = wait / 1
time = "секунд"
cooldown = round(cld, 1)
embed.description = f"Автор - {ctx.author.mention}\n"f"**Нажмите на :tada: чтобы принять участие!**\n"f"Времени осталось: {cooldown} {time}"
await message.edit(embed=embed)
await asyncio.sleep(duration)
message = await message.channel.fetch_message(message.id)
reaction = get(message.reactions, emoji=emoji)
users = [user async for user in reaction.users() if user.id != bot.user.id]
if len(users) == 0:
embed.description = f"Автор - {ctx.author.mention}\n"f"Нет победителей"
await message.edit(embed=embed)
return
else:
winner = random.choice(users)
embed.description = f"**Автор - {ctx.author.mention}**\n"f"**Победитель - {winner.mention}**"
await message.edit(embed=embed)
embed_end=discord.Embed(color=discord.Color.gold())
embed_end.add_field(name=f"Розыгрыш окончен!", value=f"[Ссылка на розыгрыш]({message.jump_url})", inline=False)
await ctx.author.send(embed=embed_end)
await channel.send(winner.mention, embed=embed)
win_embed=discord.Embed(title="Вы победили в розыгрыше!", color=discord.Color.gold())
win_embed.add_field(name=f"Вы выйграли: {prize}", value=f"[Ссылка на розыгрыш]({message.jump_url})",inline=False)
await winner.send(embed=win_embed)
Free Heroku does not support JSON writing, so your command would not be executed as it contains json.dump.