slixmpp Add_event_hanlder ('Message') not working - python

I am creating a client with python and "slixmpp" library to connect using xmpp. I have achieved to send a message to a user, but I am not able to recive a message in the program. I am testing with another client (Gajim) to run some test but in that client the message are being recived.
My client has this plugins and this event listeners
class Client(slixmpp.ClientXMPP):
"""
A client class to manage conections an functionalities
Atributes:
jid: string with the JID of the client.
password: string
is_remove: boolean to indicate if need to delete the account
"""
def __init__(self, jid, password, status, status_message):
super().__init__(jid, password)
self.name = jid.split('#')[0]
self.status = status
self.status_message = status_message
self.actual_chat = None
# # plugins
self.register_plugin('xep_0030') # Service Discovery
self.register_plugin('xep_0199') # Ping
self.register_plugin('xep_0045') # MUC
self.register_plugin('xep_0085') # Notifications
self.register_plugin('xep_0004') # Data Forms
self.register_plugin('xep_0060') # PubSub
# events
self.add_event_handler('session_start', self.start)
self.add_event_handler('disco_items', self.print_rooms)
self.add_event_handler('groupchat_message', self.chatroom_message)
self.add_event_handler('message', self.chat_recived)
And this is the function chat_recived
async def chat_recived(self, message):
await aprint('aa')
await aprint('New message', message)
if message['type'] == 'chat':
user = str(message['from']).split('#')[0]
if user == self.actual_chat:
print(f'{message["from"]}: {message["body"]}')
else:
print(f'You have a new message from {message["from"]}')
Does anyone knows why the listener is not reciving the message? This are not even been display in the console when debuger mode is on.

Related

Stuck in Creating a Skype Bot via Python using skpy

I have been trying to make a Skype bot through Python but am stuck at processing events.
I have made a conversation and put the code to get events infinitely. In return, the code is supposed to respond to each message sent to the conversation only once until someone sends another message and so on. But the code runs mad and reproduces its own sent messages.
Here is the code so far:
from skpy import Skype
user = '***'
password = '***'
group_id = '***'
class MySkype(SkypeEventLoop):
def onEvent(self, event):
if (event.type == 'NewMessage'): # and (event.userId is None):
message_content = event.raw['resource']['content']
conversation_link = event.raw['resource']['conversationLink']
message_sender = event.raw['resource']['imdisplayname']
ch = sk.chats.chat(group_id)
ch.sendMsg('The code is responding to {}.\n You sent this message: {}'.format(message_sender, message_content))
sk = MySkype(user, password, autoAck = True)
sk.loop()
As you can see the code has responded to itself!

Cloud function with pubsub trigger executed endlessly when calling gmail API messages.send()

We are using the Atlassian Status Page with email automation, which means that it displays an alert on screen whenever it receives an email with subject 'DOWN' and deletes the same alert when it receives an email with subject 'UP'.
I activated the Gmail Pub/Sub (https://developers.google.com/gmail/api/guides/push) push notifications, which watches the gmail inbox for changes and sends a push notification to a pub/sub topic when a change actually happens.
Then I created a cloud function which is triggered by pub/sub notifications. This cloud function should:
Read the latest unread email
If this email is an alert sent by our 3rd party provider, send a new email to the Status Page with subject 'DOWN' or 'UP' accordingly.
This is the code:
def access_oauth2_json():
### Code
return creds_dict
def create_message(subject):
### Code
return {'raw': b64_string}
def send_message(service, message, user_id = 'me'):
try:
response = service.users().messages().send(userId=user_id, body=message).execute()
return response
except HttpError as error:
logging.error('An error occurred:', error)
def update_status_page(arg1,arg2):
### Initialise creds
try:
service = build('gmail', 'v1', credentials=creds)
request = {
'labelIds': ['INBOX'],
'topicName': 'pubsub_topic_id'
}
service.users().watch(userId='me', body = request).execute()
last_message_info = service.users().messages().list(userId='me', labelIds=['UNREAD'], q = 'in:inbox is:unread', maxResults=1).execute().get('messages', [])
last_message = service.users().messages().get(userId='me', id=last_message_info[0]['id']).execute()
header = last_message['payload']['headers']
sub = ""
for x in header:
if x['name'] == 'Subject':
sub = x['value'] #subject
logging.info(sub)
if 'special_alert_string' in sub:
message = create_message(subject = 'DOWN')
response = send_message(service, message)
elif 'other_special_alert_string' in sub:
message = create_message(subject = 'UP')
response = send_message(service, message)
except HttpError as error:
logging.info(f'An error occurred: {error}')
return 200
What happens is that:
When the function is triggered by an email which is not a 3rd party alert, the if/elif blocks are not executed, and the cloud function is executed 2 or 3 times (instead of 1, but that's fine for me, so not really a problem)
2 - Problem - When the function is triggered by an email which is a 3rd part alert, the if/elif blocks are executed (one of the 2) and the function is executed endlessly! It only stops because it reaches the maximum API requests per interval of time.
What I have tried:
To remove the watch() line, without success
Commenting out the service.users().messages().send() line falls back into case 1, so my guess is that this instruction is triggering a push notification to the pub/sub topic and generates the infinite loop. The issue could maybe solved with another watch() labelId, but I haven't figured out which one.
I hope this is clear, thank you for your help!

Django channels: pass form data to consumer

I'm learning Django and I'm working in a webpage where I need to offer the user the possibility to log in to an external service. I can't simply use the traditional Django views system because otherwise, I would lose the connection with a simple refresh. For that reason, I thought about using Django Channels.
My problem now is how do I send the data to the consumer class? Using the consumers.py given in the tutorial, I would like to send data from a form submission to the connect function and then make the connection if the login to the external service is ok. Then, in that scenario, I could use the clientinstance and the methods from these external services.
So, in short, is it possible to send form data the consumer? And would this be ok, with respect to security in case of sensitive data?
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
######
## login to external service
######
#get login data from form submited when the websockted is initiated
username = ...
pass = ...
self.client = Client(username, password)
if client:
await self.accept()
# Receive message from room group
async def chat_message(self, event):
message = event['message']
self.client.send(event['message'])
Update:
To clear the explanation: I can't save the user username and pass of the external service, and that I want to offer the user the possibility to use this [sms service](https://clxcommunications.github.io/sdk-xms-python/tutorial.html) with a text field and phone number.
So the problem is that even if I create a form and the username and password to log in (in the view) with
client = clx.xms.Client('myserviceplan', 'mytoken')
then in next request, I would lose the client instance. That's why I thought about Django Channels. But I'm not really sure if it is the best solution...
This will help you.
consumers.py
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import json
class EventConsumer(WebsocketConsumer):
def connect(self):
# self.room_name = self.scope['url_route']['kwargs']['room_name']
# self.room_group_name = 'chat_%s' % self.room_name
self.room_name = 'event'
self.room_group_name = self.room_name+"_sharif"
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
print(self.room_group_name)
self.accept()
print("#######CONNECTED############")
def disconnect(self, code):
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
print("DISCONNECED CODE: ",code)
def receive(self, text_data=None, bytes_data=None):
print(" MESSAGE RECEIVED")
data = json.loads(text_data)
message = data['message']
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,{
"type": 'send_message_to_frontend',
"message": message
}
)
def send_message_to_frontend(self,event):
print("EVENT TRIGERED")
# Receive message from room group
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message
}))
then call the function outside/anywhere from your app like
def event_triger():
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'event_sharif',
{
'type': 'send_message_to_frontend',
'message': "event_trigered_from_views"
}
)
# here 'event_sharif' is your room_group_name as i defined before in consumer
# 'type' is like a command, for which method you wants to trigger in your consumer
for more you may take a look Send message using Django Channels from outside Consumer class
Generally, you can call a method in the consumer from an external code in the following way:
from channels.layers import get_channel_layer
channel_layer = get_channel_layer()
await self.channel_layer.send(
'<channel_name>',
{
'type': '<method_name>',
}
)
But as you can see, this requires that you specify the channel name which you can only get after the client has connected. In other words, you should not try to call connect but some other method in the consumer. Also, your client should first connect to the websocket before you eventually access it. I don't understand your use case completey but I hope this gives you an idea

Python PubNub subscriber doesn't print out the message

This is my publisher:
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
def publish_callback(result, status):
print(result)
print(status)
# Handle PNPublishResult and PNStatus
pnconfig = PNConfiguration()
pnconfig.subscribe_key = 'sub-c-ec413276-b805-11e6-b737-xxxxx'
pnconfig.publish_key = 'pub-c-528502df-76a6-4f07-8636-xxxxx'
pubnub = PubNub(pnconfig)
pubnub.publish().channel("awesomeChannel").message("hello!!").async(publish_callback)
This is my subscriber
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnubtets import MySubscribeCallback
pnconfig = PNConfiguration()
pnconfig.subscribe_key = 'sub-c-ec413276-b805-11e6-b737-xxxxx'
pnconfig.publish_key = 'pub-c-528502df-76a6-4f07-8636-xxxxx'
pubnub = PubNub(pnconfig)
pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels('awesomeChannel').execute()
This is my callback:
from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
class MySubscribeCallback(SubscribeCallback):
def presence(self, pubnub, presence):
print(presence)
def status(self, pubnub, status):
if status.category == PNStatusCategory.PNUnexpectedDisconnectCategory:
pass # This event happens when radio / connectivity is lost
elif status.category == PNStatusCategory.PNConnectedCategory:
# Connect event. You can do stuff like publish, and know you'll get it.
# Or just use the connected event to confirm you are subscribed for
# UI / internal notifications, etc
pass
elif status.category == PNStatusCategory.PNReconnectedCategory:
pass
# Happens as part of our regular operation. This event happens when
# radio / connectivity is lost, then regained.
elif status.category == PNStatusCategory.PNDecryptionErrorCategory:
pass
# Handle message decryption error. Probably client configured to
# encrypt messages and on live data feed it received plain text.
def message(self, pubnub, message):
print(message)
The problem I have is when I run the subscriber it listens and when I run the publisher to send the message hello!! my callback gets it but when i print the message it prints out <pubnub.models.consumer.pubsub.PNMessageResult object at 0x108453278>. I want it to actually show me my message hello!!.
Is there something I am missing?
From the pubnub python sdk docs:
So try
print(message.message)

APNSWrapper push notification fails to other devices if one device token is invalid

We are using the following code to deliver APNS notifications
iHPush:
def __init__(self):
self.wrapper = APNSWrapper.APNSNotificationWrapper('/path/to/my/production.pem', False)
def push(self, token='', alertmessage='', ubadge=0):
deviceToken = binascii.unhexlify(token)
message = APNSWrapper.APNSNotification()
message.token(deviceToken)
message.badge(1)
message.alert(alertmessage)
message.sound()
self.wrapper.append(message)
def notify(self):
self.wrapper.notify()
pushObj = iHPush()
#this token is used for sandbox test
pushObj.push("b9236...x0", "haha", 0)
#this one is production token
pushObj.push("b9236...40", "haha", 0)
pushObj.notify()
Combining the sandbox and production tokens in the one notification message result in no notifications being delivered. If we add the second one twice, messages are sent successfully.
I understand that if the token is valid or not should be handled by the APNS. Why can't we send message this way?

Categories