Add receiveing of images, videos and sound files
When a whatsapp buddy sends an image, video or sound to the spectrum user, the spectrum user will receive a URL that links to the media. FileTranfer in spectrum is not working, apparently. Thus media cannot be sent yet.
This commit is contained in:
parent
a6971ad889
commit
4c365e3f81
|
@ -204,7 +204,7 @@ class SpectrumBackend:
|
||||||
|
|
||||||
def handleFTData(self, ftID, data):
|
def handleFTData(self, ftID, data):
|
||||||
d = protocol_pb2.FileTransferData()
|
d = protocol_pb2.FileTransferData()
|
||||||
d.ftid = ftID
|
d.ftID = ftID
|
||||||
d.data = data
|
d.data = data
|
||||||
|
|
||||||
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_DATA);
|
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_DATA);
|
||||||
|
|
80
session.py
80
session.py
|
@ -204,26 +204,69 @@ class Session(YowsupApp):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Called by superclass
|
# Called by superclass
|
||||||
def onMessage(self, messageEntity):
|
def onTextMessage(self, _id, _from, to, notify, timestamp, participant, offline, retry, body):
|
||||||
self.logger.debug(str(messageEntity))
|
self.logger.debug('received TextMessage' +
|
||||||
buddy = messageEntity.getFrom().split('@')[0]
|
' '.join(map(str, [
|
||||||
messageContent = utils.softToUni(messageEntity.getBody())
|
_id, _from, to, notify, timestamp,
|
||||||
timestamp = messageEntity.getTimestamp()
|
participant, offline, retry, body
|
||||||
|
]))
|
||||||
self.sendReceipt(messageEntity.getId(), messageEntity.getFrom(), None,
|
)
|
||||||
messageEntity.getParticipant())
|
buddy = _from.split('@')[0]
|
||||||
|
messageContent = utils.softToUni(body)
|
||||||
if messageEntity.isBroadcast():
|
self.sendReceipt(_id, _from, None, participant)
|
||||||
self.logger.info("Broadcast received from %s to %s: %s (at ts=%s)",\
|
|
||||||
buddy, self.legacyName, messageContent, timestamp)
|
|
||||||
messageContent = "[Broadcast] " + messageContent
|
|
||||||
else:
|
|
||||||
self.logger.info("Message received from %s to %s: %s (at ts=%s)",
|
self.logger.info("Message received from %s to %s: %s (at ts=%s)",
|
||||||
buddy, self.legacyName, messageContent, timestamp)
|
buddy, self.legacyName, messageContent, timestamp)
|
||||||
self.sendMessageToXMPP(buddy, messageContent, timestamp)
|
self.sendMessageToXMPP(buddy, messageContent, timestamp)
|
||||||
|
# isBroadcast always returns false, I'm not sure how to get a broadcast
|
||||||
|
# message.
|
||||||
|
#if messageEntity.isBroadcast():
|
||||||
|
# self.logger.info("Broadcast received from %s to %s: %s (at ts=%s)",\
|
||||||
|
# buddy, self.legacyName, messageContent, timestamp)
|
||||||
|
# messageContent = "[Broadcast] " + messageContent
|
||||||
|
|
||||||
# if receiptRequested: self.call("message_ack", (jid, messageId))
|
# Called by superclass
|
||||||
|
def onImage(self, image):
|
||||||
|
self.logger.debug('Received image message %s', str(image))
|
||||||
|
buddy = image._from.split('@')[0]
|
||||||
|
message = image.url + ' ' + image.caption
|
||||||
|
self.sendMessageToXMPP(buddy, message, image.timestamp)
|
||||||
|
self.sendReceipt(image._id, image._from, None, image.participant)
|
||||||
|
|
||||||
|
# Called by superclass
|
||||||
|
def onAudio(self, audio):
|
||||||
|
self.logger.debug('Received audio message %s', str(audio))
|
||||||
|
buddy = audio._from.split('@')[0]
|
||||||
|
message = audio.url
|
||||||
|
self.sendMessageToXMPP(buddy, message, audio.timestamp)
|
||||||
|
self.sendReceipt(audio._id, audio._from, None, audio.participant)
|
||||||
|
|
||||||
|
# Called by superclass
|
||||||
|
def onVideo(self, video):
|
||||||
|
self.logger.debug('Received video message %s', str(video))
|
||||||
|
buddy = video._from.split('@')[0]
|
||||||
|
message = video.url
|
||||||
|
self.sendMessageToXMPP(buddy, message, video.timestamp)
|
||||||
|
self.sendReceipt(video._id, video._from, None, video.participant)
|
||||||
|
|
||||||
|
# Called by superclass
|
||||||
|
def onVCard(self, _id, _from, name, card_data, to, notify, timestamp, participant):
|
||||||
|
self.logger.debug('received VCard' +
|
||||||
|
' '.join(map(str, [
|
||||||
|
_id, _from, name, card_data, to, notify, timestamp, participant
|
||||||
|
]))
|
||||||
|
)
|
||||||
|
buddy = _from.split("@")[0]
|
||||||
|
self.sendMessageToXMPP(buddy, "Received VCard (not implemented yet)")
|
||||||
|
self.sendMessageToXMPP(buddy, card_data)
|
||||||
|
self.transferFile(buddy, str(name), card_data)
|
||||||
|
self.sendReceipt(_id, _from, None, participant)
|
||||||
|
|
||||||
|
def transferFile(self, buddy, name, data):
|
||||||
|
# Not working
|
||||||
|
self.logger.debug('transfering file %s', name)
|
||||||
|
self.backend.handleFTStart(self.user, buddy, name, len(data))
|
||||||
|
self.backend.handleFTData(0, data)
|
||||||
|
self.backend.handleFTFinish(self.user, buddy, name, len(data), 0)
|
||||||
|
|
||||||
# Called by superclass
|
# Called by superclass
|
||||||
def onContactTyping(self, buddy):
|
def onContactTyping(self, buddy):
|
||||||
|
@ -408,11 +451,6 @@ class Session(YowsupApp):
|
||||||
self.sendMessageToXMPP(buddy, utils.shorten(url))
|
self.sendMessageToXMPP(buddy, utils.shorten(url))
|
||||||
if receiptRequested: self.call("message_ack", (jid, messageId))
|
if receiptRequested: self.call("message_ack", (jid, messageId))
|
||||||
|
|
||||||
def onVcardReceived(self, messageId, jid, name, data, receiptRequested, isBroadcast): # TODO
|
|
||||||
buddy = jid.split("@")[0]
|
|
||||||
self.logger.info("VCard received from %s", buddy)
|
|
||||||
self.sendMessageToXMPP(buddy, "Received VCard (not implemented yet)")
|
|
||||||
if receiptRequested: self.call("message_ack", (jid, messageId))
|
|
||||||
|
|
||||||
def onGroupGotInfo(self, gjid, owner, subject, subjectOwner, subjectTimestamp, creationTimestamp):
|
def onGroupGotInfo(self, gjid, owner, subject, subjectOwner, subjectTimestamp, creationTimestamp):
|
||||||
room = gjid.split("@")[0]
|
room = gjid.split("@")[0]
|
||||||
|
@ -471,7 +509,7 @@ class Session(YowsupApp):
|
||||||
room = gjid.split("@")[0]
|
room = gjid.split("@")[0]
|
||||||
buddy = jid.split("@")[0]
|
buddy = jid.split("@")[0]
|
||||||
|
|
||||||
logger.info("Added % to room %s", buddy, room)
|
self.logger.info("Added %s to room %s", buddy, room)
|
||||||
|
|
||||||
self.backend.handleParticipantChanged(self.user, buddy, room, protocol_pb2.PARTICIPANT_FLAG_NONE, protocol_pb2.STATUS_ONLINE)
|
self.backend.handleParticipantChanged(self.user, buddy, room, protocol_pb2.PARTICIPANT_FLAG_NONE, protocol_pb2.STATUS_ONLINE)
|
||||||
if receiptRequested: self.call("notification_ack", (gjid, messageId))
|
if receiptRequested: self.call("notification_ack", (gjid, messageId))
|
||||||
|
|
|
@ -64,6 +64,9 @@ class WhatsAppBackend(SpectrumBackend):
|
||||||
# a buddy, one to the bare jid and one to /bot. This causes duplicate
|
# a buddy, one to the bare jid and one to /bot. This causes duplicate
|
||||||
# messages. Since it is unlikely a user wants to send the same message
|
# messages. Since it is unlikely a user wants to send the same message
|
||||||
# twice, we should just ignore the second message
|
# twice, we should just ignore the second message
|
||||||
|
#
|
||||||
|
# TODO Proper fix, this work around drops all duplicate messages even
|
||||||
|
# intentional ones.
|
||||||
usersMessage = self.lastMessage[user]
|
usersMessage = self.lastMessage[user]
|
||||||
if buddy not in usersMessage or usersMessage[buddy] != message:
|
if buddy not in usersMessage or usersMessage[buddy] != message:
|
||||||
self.sessions[user].sendMessageToWA(buddy, message)
|
self.sessions[user].sendMessageToWA(buddy, message)
|
||||||
|
@ -115,7 +118,8 @@ class WhatsAppBackend(SpectrumBackend):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def handleFTStartRequest(self, user, buddy, fileName, size, ftID):
|
def handleFTStartRequest(self, user, buddy, fileName, size, ftID):
|
||||||
pass
|
self.logger.debug('File send request %s, for user %s, from %s, size: %s',
|
||||||
|
fileName, user, buddy, size)
|
||||||
|
|
||||||
def handleFTFinishRequest(self, user, buddy, fileName, size, ftID):
|
def handleFTFinishRequest(self, user, buddy, fileName, size, ftID):
|
||||||
pass
|
pass
|
||||||
|
|
101
yowsupwrapper.py
101
yowsupwrapper.py
|
@ -30,7 +30,8 @@ from yowsup.layers.protocol_calls import YowCallsProtocolLayer
|
||||||
# ProtocolEntities
|
# ProtocolEntities
|
||||||
|
|
||||||
from yowsup.layers.protocol_presence.protocolentities import *
|
from yowsup.layers.protocol_presence.protocolentities import *
|
||||||
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity
|
from yowsup.layers.protocol_messages.protocolentities import *
|
||||||
|
from yowsup.layers.protocol_media.protocolentities import *
|
||||||
from yowsup.layers.protocol_chatstate.protocolentities import *
|
from yowsup.layers.protocol_chatstate.protocolentities import *
|
||||||
from yowsup.layers.protocol_acks.protocolentities import *
|
from yowsup.layers.protocol_acks.protocolentities import *
|
||||||
from yowsup.layers.protocol_receipts.protocolentities import *
|
from yowsup.layers.protocol_receipts.protocolentities import *
|
||||||
|
@ -110,8 +111,8 @@ class YowsupApp(object):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
- _id: id of message received
|
- _id: id of message received
|
||||||
- _from
|
- _from: jid of person who sent the message
|
||||||
- read: ('read' or something else)
|
- read: ('read' or None) None is just delivered, 'read' is read
|
||||||
- participant
|
- participant
|
||||||
"""
|
"""
|
||||||
receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant)
|
receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant)
|
||||||
|
@ -304,6 +305,67 @@ class YowsupApp(object):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def onTextMessage(self, _id, _from, to, notify, timestamp, participant, offline, retry, body):
|
||||||
|
"""
|
||||||
|
Called when text message is received
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- _id:
|
||||||
|
- _from: (str) jid of of sender
|
||||||
|
- to:
|
||||||
|
- notify: (str) human readable name of _from (e.g. John Smith)
|
||||||
|
- timestamp:
|
||||||
|
- participant:
|
||||||
|
- offline:
|
||||||
|
- retry:
|
||||||
|
- body: The content of the message
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onImage(self, entity):
|
||||||
|
"""
|
||||||
|
Called when image message is received
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- entity: ImageDownloadableMediaMessageProtocolEntity
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onAudio(self, entity):
|
||||||
|
"""
|
||||||
|
Called when audio message is received
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- entity: AudioDownloadableMediaMessageProtocolEntity
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def onVideo(self, entity):
|
||||||
|
"""
|
||||||
|
Called when video message is received
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- entity: VideoDownloadableMediaMessageProtocolEntity
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onVCard(self, _id, _from, name, card_data, to, notify, timestamp, participant):
|
||||||
|
"""
|
||||||
|
Called when VCard message is received
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- _id: (str) id of entity
|
||||||
|
- _from:
|
||||||
|
- name:
|
||||||
|
- card_data:
|
||||||
|
- to:
|
||||||
|
- notify:
|
||||||
|
- timestamp:
|
||||||
|
- participant:
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def sendEntity(self, entity):
|
def sendEntity(self, entity):
|
||||||
"""Sends an entity down the stack (as if YowsupAppLayer called toLower)"""
|
"""Sends an entity down the stack (as if YowsupAppLayer called toLower)"""
|
||||||
self.stack.broadcastEvent(YowLayerEvent(YowsupAppLayer.TO_LOWER_EVENT,
|
self.stack.broadcastEvent(YowLayerEvent(YowsupAppLayer.TO_LOWER_EVENT,
|
||||||
|
@ -392,7 +454,38 @@ class YowsupAppLayer(YowInterfaceLayer):
|
||||||
|
|
||||||
@ProtocolEntityCallback('message')
|
@ProtocolEntityCallback('message')
|
||||||
def onMessageReceived(self, entity):
|
def onMessageReceived(self, entity):
|
||||||
self.caller.onMessage(entity)
|
if entity.getType() == MessageProtocolEntity.MESSAGE_TYPE_TEXT:
|
||||||
|
self.caller.onTextMessage(
|
||||||
|
entity._id,
|
||||||
|
entity._from,
|
||||||
|
entity.to,
|
||||||
|
entity.notify,
|
||||||
|
entity.timestamp,
|
||||||
|
entity.participant,
|
||||||
|
entity.offline,
|
||||||
|
entity.retry,
|
||||||
|
entity.body
|
||||||
|
)
|
||||||
|
elif entity.getType() == MessageProtocolEntity.MESSAGE_TYPE_MEDIA:
|
||||||
|
if isinstance(entity, ImageDownloadableMediaMessageProtocolEntity):
|
||||||
|
# There is just way too many fields to pass them into the
|
||||||
|
# function
|
||||||
|
self.caller.onImage(entity)
|
||||||
|
elif isinstance(entity, AudioDownloadableMediaMessageProtocolEntity):
|
||||||
|
self.caller.onAudio(entity)
|
||||||
|
elif isinstance(entity, VideoDownloadableMediaMessageProtocolEntity):
|
||||||
|
self.caller.onVideo(entity)
|
||||||
|
elif isinstance(entity, VCardMediaMessageProtocolEntity):
|
||||||
|
self.caller.onVCard(
|
||||||
|
entity._id,
|
||||||
|
entity._from,
|
||||||
|
entity.name,
|
||||||
|
entity.card_data,
|
||||||
|
entity.to,
|
||||||
|
entity.notify,
|
||||||
|
entity.timestamp,
|
||||||
|
entity.participant
|
||||||
|
)
|
||||||
|
|
||||||
@ProtocolEntityCallback('presence')
|
@ProtocolEntityCallback('presence')
|
||||||
def onPresenceReceived(self, presence):
|
def onPresenceReceived(self, presence):
|
||||||
|
|
Loading…
Reference in a new issue