Pyrogram stops handle updates after "updatesTooLong" response - python

I would like to write a bot that will listen to the specific chat and save messages to the local storage.
After starting the bot app, everything works properly, but after some time I can see such information in the logs:
pyrogram.client {
'_': 'types.UpdatesTooLong'
}
Immediately after this log, my userbot stops hearing any message from any user.
How can I fix this and handle such case updatesTooLong ?

Related

GoneException when calling post_to_connection on AWS lambda and API gateway

I want to send a message to a websocket client when it connects to the server on AWS lambda and API gateway. Currently, I use wscat as a client. Since the response 'connected' is not shown on the wscat console when I connect to the server, I added post_to_connection to send a message 'hello world' to the client. However, it raises GoneException.
An error occurred (GoneException) when calling the PostToConnection
operation
How can I solve this problem and send some message to wscat when connecting to the server?
My python code is below. I use Python 3.8.5.
import os
import boto3
import botocore
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table(os.environ['TABLE_NAME'])
def lambda_handler(event, context):
domain_name = event.get('requestContext',{}).get('domainName')
stage = event.get('requestContext',{}).get('stage')
connection_id = event.get('requestContext',{}).get('connectionId')
result = connections.put_item(Item={ 'id': connection_id })
apigw_management = boto3.client('apigatewaymanagementapi',
endpoint_url=F"https://{domain_name}/{stage}")
ret = "hello world";
try:
_ = apigw_management.post_to_connection(ConnectionId=connection_id,
Data=ret)
except botocore.exceptions.ClientError as e:
print(e);
return { 'statusCode': 500,
'body': 'something went wrong' }
return { 'statusCode': 200,
"body": 'connected'};
Self-answer: you cannot post_to_connection to the connection itself in onconnect.
I have found that the GoneException can occur when the client that initiated the websocket has disconnected from the socket and its connectionId can no longer be found. Is there something causing the originating client to disconnect from the socket before it can receive your return message?
My use case is different but I am basically using a DB to check the state of a connection before replying to it, and not using the request context to do that. This error's appearance was reduced by writing connectionIds to DynamoDB on connect, and deleting them from the table upon disconnect events. Messaging now writes to connectionIds in the table instead of the id in the request context. Most messages go through but some errors are still emitted when the client leaves the socket but does not emit a proper disconnect event which leaves orphans in the table. The next step is to enforce item deletes when irregular disconnections occur. Involving a DB may be overkill for your situation, just sharing what helped me make progress on the GoneException error.
We need to post to connection after connecting (i.e. when the routeKey is not $connect)
routeKey = event.get('requestContext', {}).get('routeKey')
print(routeKey) # for debugging
if routeKey != '$connect': # if we have defined multiple route keys we can choose the right one here
apigw_management.post_to_connection(ConnectionId=connection_id, Data=ret)
#nemy's answer is totally true but it doesn't explain the reason. So, I just want to explain...
So, first of all What is GoneException or GoneError 410 ?
A 410 Gone error occurs when a user tries to access an asset which no longer exists on the requested server. In order for a request to return a 410 Gone status, the resource must also have no forwarding address and be considered to be gone permanently.
you can find more details about GoneException in this article.
In here, GoneException has occured; it means that the POST connection we are trying to make, doesn't exist - which fits perfectly in the scenario. Because we still haven't established the connection between Client and Server. The way APIGatewayWebsocketAPIs work is that you request an Endpoint(Route) and that Endpoint will invoke that Lambda Function (In our case it is ConnectionLambdaFunction for $connect Route).
Now, if The Lambda function resolves with statusCode: 200 then and only then the API Gateway will allow the connection to be established. So, basically untill we return statusCode: 200 from our Lambda Function we are not connected and untill then we are totally unknown to server and thats why the Post call that has been made before the return statement itself will throw an error.

How to trigger notification sound when onmessage event occur using django channels?

I have created a chat website using django channels and want to play some audio as notification alert when any message was send / received between users.
can anyone could help me in resolving it ?
Call this function in javascrict in your "message received" event.
function playSound() {
var audio = new Audio('audio_file.mp3');
audio.play();
}

SlackClient Python RTM not capturing messages

I want to write a simple slack bot, which responds a given string to # mentions, however I am not able to make the official documentation code to work.
I gave all OAuth permission to the bot and have the following code:
from slack import RTMClient
#RTMClient.run_on(event="message")
def gravity_bot(**payload):
data = payload['data']
print(data.get('text'))
try:
rtm_client = RTMClient(
token="my_token_auth_code",
connect_method='rtm.start'
)
print("Bot is up and running!")
rtm_client.start()
except Exception as err:
print(err)
I think the connection is established, as the "Bot is up and running" message appears, however on the slack channel to bot seems to be offline, also I am not able to get any response in the terminal, not for direct messages, not for channel messages even after inviting the bot to given channels.
Sorry couldn't let this one go.. I figured it out and here are the steps:
Create a "Classic" app in Slack (this is the only way to get the appropriate scopes), just click this link: https://api.slack.com/apps?new_classic_app=1
From the "Add features and functionality" tab click on "bots":
Click the "Add Legacy Bot User" button (this will add the "rtm.stream" scope that you need, but that you cannot add manually)
From the basic information page, install your app in a workspace
From the OAuth & Permissions page, copy the "Bot User OAuth Access Token" (the bottom one)
Run the following code (slightly modified version of the code in the docs)
from slack_sdk.rtm import RTMClient
# This event runs when the connection is established and shows some connection info
#RTMClient.run_on(event="open")
def show_start(**payload):
print(payload)
#RTMClient.run_on(event="message")
def say_hello(**payload):
print(payload)
data = payload['data']
web_client = payload['web_client']
if 'Hello' in data['text']:
channel_id = data['channel']
thread_ts = data['ts']
user = data['user']
web_client.chat_postMessage(
channel=channel_id,
text=f"Hi <#{user}>!",
thread_ts=thread_ts
)
if __name__ == "__main__":
slack_token = "<YOUR TOKEN HERE>"
rtm_client = RTMClient(token=slack_token)
rtm_client.start()
Previous answer:
Hmm, this is tricky one... According to the docs this only works for "classic" Slack apps, so that might be the first pointer. It explicitly says that you should not upgrade your app. Furthermore, you'll need to set the right permissions (god knows which ones) by selecting the "bot" scope.
Honestly, I haven't been able to get this running. Looks like Slack is getting rid of this connection method, so you might have more luck looking into the "Events API". I know it's not the ideal solution because its not as real-time, but it looks better documented and it will stay around for a while. Another approach could be polling. Its not sexy but it works...
My guess is that your problem is that there is not a valid connection, but there is no proper error handling in the Slack library. The message is printed before you actually connect, so that doesn't indicate anything.

Write Admin Messages in Bearle / Django-Private-Chat (Django 2/Python)

I was wondering, if it is possible to connect (as an admin) with a user and to write messages? I already modified the message-table in the database, however, the message does only appear after reloading the whole website - which is not the optimal outcome. I appreciate every hint. Thank you.
You have to use a pub/sub service to get notification on the client side when a message is sent in server side
A good start is pusher.com service, in your server side code, you will run this example code whenever you send a message to your user:
pusher.trigger('my-channel', 'my-event', {
'message': 'hello world'
})
and in your client side, you add a code that listen to the above channel/topic and act accordingly
var channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
alert('Received my-event with message: ' + data.message);
});

App engine Channel API returns no messages

Problem description: channel messages no returned to ajax script.
Initially, messages are delivered to clietn side, but the problem appears when I set larger timeout in js:
goog.appengine.Socket.POLLING_TIMEOUT_MS = 5000; //poll every 5 seconds
I've added a very basic Python code to test if Channel API works in my Google App Engine app.
index:
token = channel.create_channel(CHANNEL_NAME)
channel.send_message(CHANNEL_NAME, message)
#token is passed to template
additional_view:
#is another view, trigger manually from browser after index
from django.utils import simplejson
channel.send_message(CHANNEL_NAME, simplejson.dumps(data))
At client side I have a regular js with onMessage code.
The problem is that no messages are returned to client-side requests. They all come empty to polling ajax (as seen in Firebug). In application log I can see that channel is created:
"Creating channel token channel-2382918168-broadcast with client id broadcast"
and later message is sent but with a comment:
in between come these requests:
INFO 2011-08-03 14:33:32,000 dev_appserver.py:4248] "POST /_ah/channel/connected/ HTTP/1.1" 404 -
INFO 2011-08-03 14:33:33,780 dev_appserver.py:4248] "POST /_ah/channel/disconnected/ HTTP/1.1" 404 -
** ....message text...to channel with key (broadcast): no clients connected***
How does channel/message function at deeper level? Are messages lost if no clients are connected or they are retrived by newly connect clients?
If for some reason I create a channel with the same name, would it distroy undelivered messages it has inside?
Stay away from setting the POLLING_TIMEOUT_MS higher than 1.5 sec, the dev_appserver will assume you have disconnected.
It does not work via polling in production, so you do not have to worry about the timeout really.
Edit: just saw Robert's comment; personally I have even had issues if I set the polling to 3sec in Chrome/Safari/Firefox. I now just have ?disable_channel=true query strings on my apps so that I can run them without setting my laptop on fire with the CPU usage.

Categories