Pyrogram telegram API (not bot api) - python

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()

Related

Telethon authorization Python

I have the following problem: I am trying to authorize a telegram client using a session created by telethon. When you run the code in the console, as befits, the phone number associated with the account is requested, followed by the confirmation code received from Telegram. And after entering the confirmation code, nothing happens, although a message about successful authorization should appear. After a few minutes of waiting for the program to work, a message about Incomplete login attempt arrives in the Telegram. Can you tell me what's the matter?
This is my code for making session:
from telethon import TelegramClient, events
api_id = MY_API_ID
api_hash = "MY_API_HASH"
client = TelegramClient('first_session', api_id, api_hash)
#client.on(events.NewMessage(outgoing=True, pattern=None))
async def greeting(event):
chat = await event.get_chat()
await client.send_message(chat, "Hello, World!")
client.start()
client.run_until_disconnected()
And results of launching the program in the terminal in the attached image
Launching in console
Perhaps the problem may be that you are not waiting for the confirmation code request to appear and complete before running the rest of the code. To solve this problem, you need to wrap the run_until_disconnected method in an asynchronous context and use the await keyword to wait for the confirmation code to be requested.
Try the code:
from telethon import TelegramClient, events
api_id = MY_API_ID
api_hash = "MY_API_HASH"
client = TelegramClient('first_session', api_id, api_hash)
#client.on(events.NewMessage(outgoing=True, pattern=None))
async def greeting(event):
chat = await event.get_chat()
await client.send_message(chat, "Hello, World!")
async def main():
await client.start()
await client.run_until_disconnected()
asyncio.run(main())
The question is removed. For full authorization via telethon , you need to enter the method .start() pass the password="12345" parameter, where 12345 is the two-factor authentication password.

Single action script for discord bot with python discord.py

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!'

How to send messages every 5 seconds by aiogram?

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()

How to use NewMessage event of telethon on google colab

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())

Telegram's websocket

I want to connect to the telegram's WebSocket or other protocol, to receive every message. I was inspecting the network tab in dev tools, but I could not find any WebSocket protocol, however, when I entered console, I can see [SW] on message {type: "ping", localNotifications: true, lang: {…}, settings: {…}} Which convince me, that it is sent to maintain connection with the WebSocket. I tried a telethon library for python, but it allows me only to show all messages in the chat.
from telethon import TelegramClient
import asyncio
client = TelegramClient(name, api_id, api_hash)
client.start()
for i in client.iter_dialogs():
if i.name == 'test':
chj = i
async def main():
channel = await client.get_entity(chj)
messages = await client.get_messages(channel, limit= None) #pass your own args
#then if you want to get all the messages text
for x in messages:
print(x) #return message.text
"""for i in client.iter_dialogs():
print(i)"""
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
I want to be getting messages like in WebSocket whenever on the desired chat someone's types something
I have found an answer. This can be achieved using events from telethon library
from telethon import TelegramClient, events
name = 'test'
api_id = 1234
api_hash = 'hash'
client = TelegramClient(name, api_id, api_hash)
#client.on(events.NewMessage())
async def newMessageListener(event):
newMessage = event.message.message
print(newMessage)
with client:
client.run_until_disconnected()

Categories