How to fix a coroutine was expected error? - python

I try to start pyrogram client with loop.create_task(app.start()) but get an error TypeError: a coroutine was expected, got <pyrogram.client.Client object at 0x7f8bb7580520>, how can I fix it? It worked fine year ago but now it doesnt
import asyncio
from pyrogram import Client
loop = asyncio.get_event_loop()
app = Client(
"aaaaa",
bot_token="token",
api_id=12,
api_hash="a"
)
loop.create_task(app.start())

Pyrogram Client already has an event loop, you don't need to create again. If you follow the documentation it's clear how to run the bot.
Also you can use the Pyrostarter to create a bot project.

Related

Concurrent execution of two python methods

I'm creating a script that is posting a message to both discord and twitter, depending on some input. I have to methods (in separate .py files), post_to_twitter and post_to_discord. What I want to achieve is that both of these try to execute even if the other fails (e.g. if there is some exception with login).
Here is the relevant code snippet for posting to discord:
def post_to_discord(message, channel_name):
client = discord.Client()
#client.event
async def on_ready():
channel = # getting the right channel
await channel.send(message)
await client.close()
client.run(discord_config.token)
and here is the snippet for posting to twitter part (stripped from the try-except blocks):
def post_to_twitter(message):
auth = tweepy.OAuthHandler(twitter_config.api_key, twitter_config.api_key_secret)
auth.set_access_token(twitter_config.access_token, twitter_config.access_token_secret)
api = tweepy.API(auth)
api.update_status(message)
Now, both of these work perfectly fine on their own and when being called synchronously from the same method:
def main(message):
post_discord.post_to_discord(message)
post_tweet.post_to_twitter(message)
However, I just cannot get them to work concurrently (i.e. to try to post to twitter even if discord fails or vice-versa). I've already tried a couple of different approaches with multi-threading and with asyncio.
Among others, I've tried the solution from this question. But got an error No module named 'IPython'. When I omitted the IPython line, changed the methods to async, I got this error: RuntimeError: Cannot enter into task <ClientEventTask state=pending event=on_ready coro=<function post_to_discord.<locals>.on_ready at 0x7f0ee33e9550>> while another task <Task pending name='Task-1' coro=<main() running at post_main.py:31>> is being executed..
To be honest, I'm not even sure if asyncio would be the right approach for my use case, so any insight is much appreciated.
Thank you.
In this case running the two things in completely separate threads (and completely separate event loops) is probably the easiest option at your level of expertise. For example, try this:
import post_to_discord, post_to_twitter
import concurrent.futures
def main(message):
with concurrent.futures.ThreadPoolExecutor() as pool:
fut1 = pool.submit(post_discord.post_to_discord, message)
fut2 = pool.submit(post_tweet.post_to_twitter, message)
# here closing the threadpool will wait for both futures to complete
# make exceptions visible
for fut in (fut1, fut2):
try:
fut.result()
except Exception as e:
print("error: ", e)

Telegram is having internal issues RpcCallFailError

I'm trying to get the latest message from a telegram channel with telethon and the following code:
import t_api,time,asyncio
from telethon import TelegramClient
from telethon.tl.functions.messages import GetHistoryRequest
async def get_message():
license_b="allow"
flag=0
try:
async with TelegramClient(t_api.username,t_api.api_id,t_api.api_hash) as client:
my_channel=await client.get_entity("channel_name")
while license_b=="allow":
history=await client(GetHistoryRequest(peer=my_channel,offset_id=0,offset_date=None,add_offset=0,limit=1,max_id=0,min_id=0,hash=0))
t1=history.messages[0].message
if flag==0:
sub_t1=t1
flag+=1
if sub_t1!=t1:
flag=0
checking_b(t1)
time.sleep(2)
except:
return False
asyncio.run(get_message())
I have to use this method due to the delay of about 30 seconds in receiving messages via streaming channels with many members.
And this code works well, but sometimes after a few hours, despite the try except function, program gets following error.
Telegram is having internal issues RpcCallFailError: Telegram is having internal issues, please try again later. (caused by GetHistoryRequest)
My question is how to prevent this error from occurring and how to handle it if it occurs, because try except dose not work.
Someone can help me?

Discord's new support for slash commands | AttributeError with discord-py-slash-command

Is there any official support for the new Discord slash commands; if not, how do you use the discord-py-slash-command module as I couldn't get that to work
I've been spending a while trying to work out how to use the new slash commands and I couldn't find Discord saying how to use it on discord.py.
After a bit of searching I've found a module called discord-py-slash-command but I couldn't figure out how to use this either.
When I tried to implement it into the main code of my bot nothing happened, so I tried to just run the example they showed on their website here (The top example) without modifying it and that also didn't work, and return this error message:
Traceback (most recent call last):
File "/snap/pycharm-community/224/plugins/python-ce/helpers/pydev/pydevd.py", line 2167, in <module>
main()
File "/snap/pycharm-community/224/plugins/python-ce/helpers/pydev/pydevd.py", line 2034, in main
debugger = PyDB()
File "/snap/pycharm-community/224/plugins/python-ce/helpers/pydev/pydevd.py", line 407, in __init__
self._cmd_queue = defaultdict(_queue.Queue) # Key is thread id or '*', value is Queue
AttributeError: module 'queue' has no attribute 'Queue'
Process finished with exit code 1
Here's my copy and pasted code from their example:
import discord
from discord.ext import commands
from discord_slash import SlashCommand
from discord_slash import SlashContext
bot = commands.Bot(command_prefix="!", intents=discord.Intents.all())
slash = SlashCommand(bot)
#slash.slash(name="test")
async def _test(ctx: SlashContext):
embed = discord.Embed(title="embed test")
await ctx.send(content="test", embeds=[embed])
bot.run(".token.txt")
I'm not very qualified with discord-py-slash-command but as far as I know, you have to pass some arguments in #slash.slash() such as description etc.
guild_ids = [<your guild id>]
slash = SlashCommand(bot, auto_register=True)
#slash.slash(
name="ttest",
description="Sends message.",
guild_ids=guild_ids
)
async def _test(ctx: SlashContext):
embed = discord.Embed(title="embed test")
await ctx.send(content='test', embeds=[embed])
This will work but I don't recommend you to use this module until it's references became more clear. It's so unclear and unhandy also it's syntax is so complicated compared to discord.py.
Also, you have to enable applications.commands scope from Discord Developer Portal -> OAuth2 -> Scopes.
I've recently been building a bot with discord-py-slash-command. I've figured out that the best way to make a command would be to read their documentation (below).
With your command, what I notice first that I haven't used is ctx: SlashContext, instead, try using just ctx. Your script is also probably you used Embeds=[embed], and I am not sure how multiple embeds would work, but for a single one, embed= is lowercase. I'm pretty sure you don't need the content=''.
The errors seems to be coming from pycharm and not the script itself, maybe try another IDE.
Documentation:
https://discord-py-slash-command.readthedocs.io/en/latest/
Option Types (I found this really useful):
https://discord-py-slash-command.readthedocs.io/en/latest/discord_slash.model.html?highlight=USER#discord_slash.model.SlashCommandOptionType.USER
My discord is _stefthedoggo#1698, DM me if you want more help, I have a working bot running solely on discord-py-slash-commands

Sending DM to user in Flask python with discord.py

So I am trying to create a vote webhook for my discord bot with the flask module, but apparently importing discord.py and flask in the same file don't really go good together. When I run my code, it just shows RuntimeError: Event loop stopped before Future completed.. Here is my code:
#setup code
#app.route('/webhook', methods=['POST'])
def respond():
data = request.json
auth = request.headers
if auth["Authorization"] == "my_auth":
user = client.get_user(user_id)
await user.send('Thank you for voting for me! Make sure you vote again in 12 hours!')
return Response(status=200)
That doesn't work, because you can't do await outside of a async function, so I replaced await user.send('Thank you for voting for me! Make sure you vote again in 12 hours!') with client.loop.create_task(user.send('Thank you for voting for me! Make sure you vote again in 12 hours!')) which is what gave me the error RuntimeError: Event loop stopped before Future completed.. I was told that using Flask is not letting discord.py run, and I do not know how to fix that. So can you please help me figure out how to DM a user when the webhook is fired?
Information about webhook:
Click Here to see the request
Versions:
Python: 3.8.5
Discord.py: 1.4.1
Flask: 1.1.2
EDIT: I realized that this actually works when I type flask run in terminal, but it doesn't work with gunicorn app:app. Since typing flask run runs a development server and not what I should actually use , I run gunicorn app:app which is what gives me RuntimeError: Event loop stopped before Future completed.
Try adding async in function definition.
async def respond():

Telegram Quiz Bot with pyTelegramBotAPI

Trying to build a Telegram Quiz Bot using pyTelegramBotAPI. I'm using sched to schedule the message Handler but i don't know how to stop the Message Handler and return to my Main Script which will scheudle the next Round.
Tryed to use timeout but it is not working!
My Code:
import telebot
import sched, time
def listen():
print("Send my your Answer")
#bot.message_handler(func=lambda message: True, content_types=['text'])
def command_default(m):
print(m.text)
bot.polling()
API_TOKEN = 'xxxx'
s = sched.scheduler(time.time, time.sleep)
bot = telebot.TeleBot(API_TOKEN)
s.enter(50, 1, listen)
s.run()
In this use case you have to use something called a Finite State Machine (FSM). You keep track of user states, such as one where the user is ready to send an answer.
This is already implemented in pyTelegramBotAPI, with the next_step_handler(). However, I suggest you instead create your own solution, as the one provided by the wrapper is quite buggy.
Here is an example (you can translate the page): https://groosha.gitbooks.io/telegram-bot-lessons/content/chapter11.html

Categories