I need a telegram bot which can send "Hello" every 5 seconds. I tried, but my script does totally nothing. Help me, please
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
import schedule
bot = Bot(token) #here is my token
dp = Dispatcher(bot)
async def send(message : types.Message):
await message.answer('Hello')
schedule.every(5).seconds.do(send)
executor.start_polling(dp, skip_updates=True)
from time import sleep
This code calls the send function every 5th second 10 times
for _ in range(10):
send()
sleep(5)
This code calls the send function basically forever but still in a five-second interval.
while True:
send()
sleep(5)
have you try websockets?
import websockets
import asyncio
async def server(ws:str, path:int):
while True:
message = await ws.recv() # or "Hello"
print(f'Msg [{message}]')
message_to_send = main(message)
schedule.every(5).seconds.do(await ws.send(message_to_send))
server = websockets.serve(server, '127.0.0.1', 5678)
asyncio.get_event_loop().run_until_complete(server)
asyncio.get_event_loop().run_forever()
Related
I understand that usually the discord bots are in a listening (blocking) loop, but how can I create a function that connects, send a message or perform any action and disconnect in a non blocking flow?
I'm using discord.py and I'm looking for something like:
import discord
TOKEN = "mYtOkEn"
discord.connect(TOKEN)
discord.send("I'm sending this message")
discord.disconnect()
I already tryied playing with the async but have problems with the threading, so was wondering if there is something more simple.
It is for a button that when clicked, perform that action but after that it can continue working on other tasks
Thanks beforehand
One way you could accomplish this is by using a custom event loop.
Example:
import discord
import asyncio
from threading import Thread
TOKEN = "secret"
client = discord.Client()
def init():
loop = asyncio.get_event_loop()
loop.create_task(client.start(TOKEN))
Thread(target=loop.run_forever).start()
#client.event
async def on_message(message):
if message.author == client.user:
return
await message.channel.send('Hello!')
#client.event
async def on_ready():
print("Discord bot logged in as: %s, %s" % (client.user.name, client.user.id))
init()
print("Non-blocking")
Take a look at this for more info: C-Python asyncio: running discord.py in a thread
Thank you for your help and support. With the SleepyStew answer I could find the path to solve it and went this way:
import discord
import asyncio
def discord_single_task():
# Define Coroutine
async def coroutine_to_run():
TOKEN = "Secret"
# Instantiate the Client Class
client = discord.Client()
# # Start (We won't use connect because we don't want to open a websocket, it will start a blocking loop and it is what we are avoiding)
await client.login(TOKEN)
# Do what you have to do
print("We are doing what we want to do")
# Close
await client.close()
# Create Loop to run coroutine
loop = asyncio.new_event_loop()
llll = loop.create_task(coroutine_to_run())
loop.run_until_complete(llll)
return 'Action performed successfully without a blocking loop!'
i am using Pyrogram to work with telegram API.
I have succeed to join channel.
I have a task to add message handler and receive messages in channel.
But the message handler is not invoked when message arrives (i am the owner of channel)
The code:
import asyncio
from pyrogram import Client
import time
from pyrogram.handlers import MessageHandler, RawUpdateHandler
api_id = "xx"
api_hash = "xx"
def my_handler(client, message):
message.forward("me")
print('sent msg')
async def main():
async with Client("my_account", api_id, api_hash) as app:
a = await app.get_chat('test2k3')
msg_handler = MessageHandler(my_handler)
app.add_handler(msg_handler)
await app.join_chat(str(a.id))
print(f'joined chat ' + str(a.id))
while True:
time.sleep(2.4)
asyncio.get_event_loop().run_until_complete(main())
Sleeping while the client runs halts it until the sleep is over. Pyrogram itself will already keep itself alive until Ctrl and C is pressed. Remove your while True sleep loop.
as recommended by sudden_appearance
use asyncio.sleep() inside async functions instead of time.sleep()
I have this code and I want to run it on google colab. It works great on my PC but on colab I always get errors like these:
SyntaxError: 'async with' outside async function
or
RuntimeError: You must use "async with" if the event loop is running (i.e. you are inside an "async def")
sometimes it does not wait for getting new messages and finish after one running.
import json
import time
import telethon as tlt
import asyncio
from telethon import events,TelegramClient
chat_name = "sample"
telegram_session="sample_1"
api_id = "0000000"
api_hash = ""
client = TelegramClient(None , api_id, api_hash)
#client.on(events.NewMessage(chats=chat_name))
async def handler(event):
get_message = event.message.to_dict()
get_message['date'] = get_message['date'].strftime("%Y-%m-%d %H:%M:%S")
message_json = json.dumps(get_message)
print(message_json)
async with client:
client.run_until_disconnected()
You need to put async with inside of async def:
...
async def main():
async with client:
await client.run_until_disconnected()
client.loop.run_until_complete(main())
I have a discord bot that sends a message every once in a while based on a web scraping application (won't show that here because it is 500 lines long and someone else could compete for something with it) This is the code that sends the message:
import discord
import time
import asyncio
#the reason it is in while true is so it sends more frequently than once every 30 minutes for testing
while True:
bot = discord.Client()
#bot.event
async def on_ready():
channel = bot.get_channel(866363006974820355)
await channel.send("Test")
print("Sent")
await bot.close()
print("started")
bot.run('hiddentoken')
After the bot closes the loop it goes back to the bot.run() and gives the following exception: Event loop is closed. How do I reopen the event loop before I do bot.run()? Do I need to or is there a workaround I can use.
Note: I tried just keeping the bot open all of the time but it logs out of discord after a bit.
This is not my response, this is #Benjin. This is where he answered.
praw relies on the requests library, which is synchronous meaning that the code is blocking. This can cause your bot to freeze if the blocking code takes too long to execute.
To get around this, a separate thread can be created that handles the blocking code. Below is an example of this. Note how blocking_function will use time.sleep to block for 10 minutes (600 seconds). This should be more than enough to freeze and eventually crash the bot. However, since the function is in it's own thread using run_in_executor, the bot continues to operate as normal.
import time
import asyncio
from discord.ext import commands
from concurrent.futures import ThreadPoolExecutor
def blocking_function():
print('entering blocking function')
time.sleep(600)
print('sleep has been completed')
return 'Pong'
client = commands.Bot(command_prefix='!')
#client.event
async def on_ready():
print('client ready')
#client.command()
async def ping():
loop = asyncio.get_event_loop()
block_return = await loop.run_in_executor(ThreadPoolExecutor(), blocking_function)
await client.say(block_return)
client.run('token')
I want to send values from a for loop from the client-server but the server only receives the first value and the connection is cut shortly
Client
import asyncio
import websockets
import time
async def message():
async with websockets.connect("ws://-------:5051") as socket:
for i in range(20):
await socket.send(f"{i}")
print(i)
time.sleep(4)
asyncio.get_event_loop().run_until_complete(message())
Server
import asyncio
import websockets
async def consumer_handler(websocket,path):
client_type = await websocket.recv()
print(client_type)
start_server = websockets.serve(consumer_handler,"ws://-------:5051", 5051)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
So, your consumer_handler receives message once and finishes.
You need to add loop.
Try something like this:
async def consumer_handler(websocket, path):
async for msg in websocket:
print(msg)