I'm new to programming and I'm trying to implement function to my Telegram bot, which should check data from database, compare time and send notification if time has come.
However I have this type of mistake:
DeprecationWarning: There is no current event loop loop =
asyncio.get_event_loop()
Here is a function code:
async def run_notify():
while True:
base = sq.connect("actions.db")
cur = base.cursor()
all_data = cur.execute("SELECT * FROM actions").fetchall()
delta = timedelta(days=1)
for each_train in all_data:
each_train = str(each_train)
each_train = re.sub("[(|)|'|,]", "", each_train)
data_info = datetime.strptime(each_train, "%d %m %Y %H:%M")
today = datetime.now()
if today == (data_info - delta):
await bot.send_message(chat_id=-530468333, text= f"Reminder {data_info}")
await asyncio.sleep(1)
And the main part:
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.create_task(run_notify())
executor.start_polling(dp, skip_updates=True, on_startup=on_startup)
How can I fix this Error and are there any other possible ways to implement Notifications?
Thanks
Related
After the start of the bans of accounts connected to my project, I changed the system for receiving new messages in the telegram account. Previously, I implemented it through a handler, now it is possible to connect several accounts, performing actions with unread messages on each one in turn. Code:
async def start_wtf_blyat():
global client, current_session_account
while True:
for cl in clients:
current_session_account = cl[0]
client = cl[1]
print(f'Choosing {current_session_account.session_name}')
if current_session_account.start_time is not None:
if current_session_account.start_time > dt.datetime.utcnow():
print(
f"{current_session_account.session_name}: {current_session_account.start_time.strftime('%d.%m.%Y %H:%M:%S')} > {dt.datetime.utcnow().strftime('%d.%m.%Y %H:%M:%S')}")
s_d = (current_session_account.start_time - dt.datetime.utcnow().replace(
microsecond=0)) * random.randrange(
1, 3)
print(f'{current_session_account.session_name} needs to sleep {s_d.seconds} seconds')
await asyncio.sleep(s_d.seconds)
print(f'{current_session_account.session_name}: Sleep complete!')
current_session_account.start_time = dt.datetime.utcnow().replace(microsecond=0)
current_session_account.activate()
async with client:
print(f'Starting {current_session_account.session_name}')
await check_news()
print(
f'{current_session_account.session_name}: Work complete! END: {current_session_account.end_time.strftime("%d.%m.%Y %H:%M:%S")}')
Then the necessary messages are selected in the check_news():
async def check_news():
global current_session_account, ME
ME = await client.get_me()
await asyncio.sleep(random.randrange(1, 5, 1))
# try:
x = [[d.unread_count, d.entity.id, d.title] for d in await client.get_dialogs() if
not getattr(d.entity, 'is_private', False) and type(d.entity) == Channel
and d.unread_count != 0 and d.entity.id in INPUT_CHANNELS_IDS]
if not x:
rnd_sleep = random.randrange(180, 300)
print(f'{current_session_account.session_name}: No channels, sleep for {rnd_sleep} seconds')
end_time = dt.datetime.utcnow().replace(microsecond=0)
start_time = current_session_account.start_time
if start_time is not None:
if start_time < end_time:
delta = end_time - start_time + dt.timedelta(seconds=rnd_sleep)
else:
delta = dt.timedelta(seconds=rnd_sleep)
print(f'{current_session_account.session_name} START: {start_time.strftime("%d.%m.%Y %H:%M:%S")}, '
f'END: {end_time.strftime("%d.%m.%Y %H:%M:%S")}, '
f'DELTA: {delta}, '
f'NEXT START {(end_time + delta).strftime("%d.%m.%Y %H:%M:%S")}')
current_session_account.set_times(delta)
current_session_account.deactivate()
return
for da in x:
print(f'{current_session_account.session_name}: {x.index(da) + 1} of {len(x)}')
await asyncio.sleep(random.randrange(1, 5, 1))
async for msg in client.iter_messages(da[1], limit=da[0]):
await asyncio.sleep(random.randrange(3, 5, 1))
await msg.mark_read()
if msg.text is None:
continue
comm_result_true = await Magic.detect_commercial(msg.text)
antiplagiat_result = await antiplagiat(msg)
if not comm_result_true and antiplagiat_result:
await send_this_post(msg, da[1])
else:
print(f'{current_session_account.session_name}: Commercial or plagiat!')
# finally:
end_time = dt.datetime.utcnow().replace(microsecond=0)
start_time = current_session_account.start_time
if start_time is not None:
if start_time < end_time:
delta = end_time - start_time + dt.timedelta(seconds=1)
else:
delta = dt.timedelta(seconds=2)
print(f'{current_session_account.session_name} START: {start_time.strftime("%d.%m.%Y %H:%M:%S")}, '
f'END: {end_time.strftime("%d.%m.%Y %H:%M:%S")}, '
f'DELTA: {delta}, '
f'NEXT START {(end_time + delta).strftime("%d.%m.%Y %H:%M:%S")}')
current_session_account.set_times(delta)
current_session_account.deactivate()
return
Finally, the message is processed, the media is downloaded, if any, the text is saved. And other actions are no longer related to the telegram api.
async def send_this_post(msg, result):
chan = db.get_input_channel(result)
if db.using_ai(chan[1]):
check = await Magic.detect_theme(msg.text)
if check:
msg_category = CAT_DEF[f'{check}']
else:
return
else:
msg_category = db.get_category_by_input_channel_name(chan[1])
print(f'Theme - {msg_category}')
test = await MSG(msg_cat=msg_category, txt=msg.text, title=chan[2], username=chan[1], datetime=msg.date)
await test.create_media(msg)
await test.create_voice()
await test.create_translates()
await send_to_users_test(test)
return
Everything starts as follows:
if __name__ == '__main__':
logging.warning('IZVESTNIK STARTED.')
loop = asyncio.get_event_loop()
bot.start(bot_token=settings.bot_TOKEN)
logging.warning(f'BOT {settings.bot_username} just launched.')
loop.create_task(usr_periods_activity())
loop.create_task(usr_msg_queue_activity())
loop.create_task(start_wtf_blyat())
bot.loop.run_forever()
In fact, all that each account does is receive unread messages, download media, mark them as read, but even the launch of 8 accounts resulted in the ban of each of them for 3 days, either in general without an error, or with an Account deactivated/deleted error (Caused get_dialogs request).
Although many users of the telegram application do many times more actions. Recently rereading the documentation, I came across this:
Text from documentation.
Perhaps the reason is that I am from Russia, and I use Russian SIM cards to register accounts, but a friend from England bought SIM cards for me there several times, but they also received a ban. The project release is located on the WDM server, the ip is also Russian, maybe that's the problem?
I also recommend to use different version
pip install Telethon==1.1
this version can't ban your account
The solution of this issue is just write an "impulse" activity script against pooling script. Also use SIM cards from another country for telegram accounts and proxy.
I'm getting this error after my code runs for a few minutes:
future: <Task finished name='Task-1' coro=<timer() done, defined at c:\Users(my name)\Desktop\DiscordBot\roblox test copy.py:12> exception=KeyError('data')>
I'm pretty new to python so I can't get this to work. Any help would be appreciated.
Here is my code:
from time import sleep
from discord.ext import commands
import datetime
import asyncio
import requests
import json
import time
bot = commands.Bot(command_prefix='!')
async def timer():
await bot.wait_until_ready()
channel = bot.get_channel(my discord channel, not sending in case it can be traced to my server)
msg_sent = False
while True:
r = requests.get('https://badges.roblox.com/v1/users/2642375267/badges?limit=10&sortOrder=Desc')
badgedata = r.json()['data']
risetimes = []
for d in badgedata:
badgeid = d['id']
risetimes.append(badgeid)
firstThing = risetimes[0]
times = []
for rt in risetimes:
eztime = (str(rt))
times.append(eztime)
xd = requests.get('https://badges.roblox.com/v1/users/2642375267/badges/awarded-dates?badgeIds=' + str(firstThing))
badgegaineddata = xd.json()['data']
badgegainedtime = []
for ig in badgegaineddata:
badgegaineduwu = ig['awardedDate']
badgegainedtime.append(badgegaineduwu)
firstElement = badgegainedtime[0]
date_string = str(firstElement)
Thedatetime = date_string
date_string = date_string[:26]
date_format = datetime.datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%f")
unix_time = datetime.datetime.timestamp(date_format)
unix_time = unix_time - 18000
dt = datetime.datetime.fromtimestamp(unix_time)
currentunixtime = time.time()
if unix_time > currentunixtime -3:
await channel.send("https://www.roblox.com/badges/" + str(firstThing))
await channel.send(dt)
msg_sent = True
sleep(3)
await asyncio.sleep(1)
bot.loop.create_task(timer())
bot.run('token')
I've inherited some code that utilizes Python Bleak to scan for advertisements emitted from a certain device. Whenever an advertisement from the Bluetooth mac address and service id we're looking for is detected and a certain condition from the extracted payload information is true, we want to terminate and return. In the attached code, I've masked the Bluetooth and service ID:s.
Not being too familiar with the event loop, is there a way to exit before the timer runs out? I suppose there's probably a better way to approach this problem.
Sample code:
import asyncio
import struct
from bleak import BleakScanner
timeout_seconds = 10
address_to_look_for = 'masked'
service_id_to_look_for = 'masked'
def detection_callback(device, advertisement_data):
if device.address == address_to_look_for:
byte_data = advertisement_data.service_data.get(service_id_to_look_for)
num_to_test = struct.unpack_from('<I', byte_data, 0)
if num_to_test == 1:
print('here we want to terminate')
async def run():
scanner = BleakScanner()
scanner.register_detection_callback(detection_callback)
await scanner.start()
await asyncio.sleep(timeout_seconds)
await scanner.stop()
if __name__=='__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
I'm sure there are many ways this can be done. A small mod to your code would be rather than having the asyncio.sleep for the full period before you stop the scan, you could could have a while loop that ends on time elapsed or device found event.
For example:
import asyncio
import struct
from bleak import BleakScanner
timeout_seconds = 20
address_to_look_for = 'F1:D9:3B:39:4D:A2'
service_id_to_look_for = '0000feaa-0000-1000-8000-00805f9b34fb'
class MyScanner:
def __init__(self):
self._scanner = BleakScanner()
self._scanner.register_detection_callback(self.detection_callback)
self.scanning = asyncio.Event()
def detection_callback(self, device, advertisement_data):
# Looking for:
# AdvertisementData(service_data={
# '0000feaa-0000-1000-8000-00805f9b34fb': b'\x00\xf6\x00\x00\x00Jupiter\x00\x00\x00\x00\x00\x0b'},
# service_uuids=['0000feaa-0000-1000-8000-00805f9b34fb'])
if device.address == address_to_look_for:
byte_data = advertisement_data.service_data.get(service_id_to_look_for)
num_to_test, = struct.unpack_from('<I', byte_data, 0)
if num_to_test == 62976:
print('\t\tDevice found so we terminate')
self.scanning.clear()
async def run(self):
await self._scanner.start()
self.scanning.set()
end_time = loop.time() + timeout_seconds
while self.scanning.is_set():
if loop.time() > end_time:
self.scanning.clear()
print('\t\tScan has timed out so we terminate')
await asyncio.sleep(0.1)
await self._scanner.stop()
if __name__ == '__main__':
my_scanner = MyScanner()
loop = asyncio.get_event_loop()
loop.run_until_complete(my_scanner.run())
I have a code to receive data from binance, about current prices:
import asyncio
from binance import AsyncClient, BinanceSocketManager
import time
from datetime import datetime
def analyze(res):
kline = res['k']
if kline['x']: #candle is compleated
print('{} start_sleeping {} {}'.format(
datetime.now(),
kline['s'],
datetime.fromtimestamp(kline['t'] / 1000),
))
time.sleep(5)
print('{} finish_sleeping {}'.format(datetime.now(), kline['s']))
async def open_binance_stream(symbol):
client = await AsyncClient.create()
bm = BinanceSocketManager(client)
ts = bm.kline_socket(symbol)
async with ts as tscm:
while True:
res = await tscm.recv()
analyze(res)
await client.close_connection()
async def main():
t1 = asyncio.create_task(open_binance_stream('ETHBTC'))
t2 = asyncio.create_task(open_binance_stream('XRPBTC'))
await asyncio.gather(*[t1, t2])
if __name__ == "__main__":
asyncio.run(main())
How to make analyze function to be called concurently.
Binance sends info in the same time with both streams data (ETHBTC and XRPBTC)
But function analyze will be called only once previous analyze (sleep) is completed.
I wish function analyze is called immediately and independently.
Have you tried to put analyze in a thread. I think it will achieve what you want.
import asyncio
from binance import AsyncClient, BinanceSocketManager
import time
from datetime import datetime
from threading import Thread
def analyze(res):
kline = res['k']
if kline['x']: #candle is compleated
print('{} start_sleeping {} {}'.format(
datetime.now(),
kline['s'],
datetime.fromtimestamp(kline['t'] / 1000),
))
time.sleep(5)
print('{} finish_sleeping {}'.format(datetime.now(), kline['s']))
async def open_binance_stream(symbol):
client = await AsyncClient.create()
bm = BinanceSocketManager(client)
ts = bm.kline_socket(symbol)
async with ts as tscm:
while True:
res = await tscm.recv()
Thread(target= analyze, args = (res)).start()
await client.close_connection()
async def main():
t1 = asyncio.create_task(open_binance_stream('ETHBTC'))
t2 = asyncio.create_task(open_binance_stream('XRPBTC'))
await asyncio.gather(*[t1, t2])
if __name__ == "__main__":
asyncio.run(main())
This should work as expected.
I need to change the format to compare the time to bot send the message, i think it's just change the format strptime() to strftime() or vice-versa, but i dkn how do this, and i want to send this message with the discord bot, but i think it's wrong because if i test just the code of discord bot the (WHILE TRUE:) stop
import discord
from datetime import datetime, date
import datetime
import requests
from time import sleep
import time
url = 'https://www.bdohelper.me/gamez/schedule/EU'
params = dict()
TOKEN = ""
while True:
resp = requests.get(url=url, params=params)
data = resp.json()
boss = data[0]['boss']
time_spawn = data[0]['spawnat']
channel = data[0]['channel']
time_spawn = time_spawn.split('T')
time_spawn = time_spawn.pop(1)
time_spawn = time_spawn.split('.')
time_spawn = time_spawn.pop(0)
time_spawn = datetime.datetime.strptime(time_spawn, '%H:%M:%S').time()
now = datetime.datetime.utcnow().strftime('%H:%M:%S')
now = datetime.datetime.strptime(now, '%H:%M:%S').time()
until_spawn = datetime.datetime.combine(date.today(), time_spawn) - datetime.datetime.combine(date.today(), now)
print(until_spawn)
time.sleep(1)
for_spawn = datetime.time()
print(for_spawn)
if time_spawn == for_spawn:
def sendMessage(message):
client = discord.Client()
#client.event
async def on_ready():
channel = client.get_channel(MY CHANNEL ID)
await channel.send(message)
print("done")
client.run(TOKEN)
if __name__ == '__main__':
sendMessage(time_spawn)```
OUTPUT:
0:04:21 <------- change
00:05:45
Try this (inserted hyphen between % and H):
time_spawn = datetime.datetime.strptime(time_spawn, '%-H:%M:%S').time()
That generally removes leading zeroes when formatting datetimes.