parent
995507c27f
commit
c716e94c70
|
@ -3,7 +3,7 @@ import socket
|
|||
import struct
|
||||
import sys
|
||||
import os
|
||||
|
||||
import logging
|
||||
import google.protobuf
|
||||
|
||||
def WRAP(MESSAGE, TYPE):
|
||||
|
@ -19,11 +19,12 @@ class SpectrumBackend:
|
|||
@param host: Host where Spectrum2 NetworkPluginServer runs.
|
||||
@param port: Port.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.m_pingReceived = False
|
||||
self.m_data = ""
|
||||
self.m_init_res = 0
|
||||
self.logger = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
|
||||
def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = ""):
|
||||
m = protocol_pb2.ConversationMessage()
|
||||
|
@ -251,6 +252,7 @@ class SpectrumBackend:
|
|||
|
||||
def handleConvMessagePayload(self, data):
|
||||
payload = protocol_pb2.ConversationMessage()
|
||||
self.logger.error("handleConvMessagePayload")
|
||||
if (payload.ParseFromString(data) == False):
|
||||
#TODO: ERROR
|
||||
return
|
||||
|
@ -363,8 +365,10 @@ class SpectrumBackend:
|
|||
if (len(self.m_data) >= 4):
|
||||
expected_size = struct.unpack('!I', self.m_data[0:4])[0]
|
||||
if (len(self.m_data) - 4 < expected_size):
|
||||
self.logger.error("Expected Data Size Error")
|
||||
return
|
||||
else:
|
||||
self.logger.error("Data too small")
|
||||
return
|
||||
|
||||
|
||||
|
@ -378,9 +382,13 @@ class SpectrumBackend:
|
|||
|
||||
if (parseFromString == False):
|
||||
self.m_data = self.m_data[expected_size+4:]
|
||||
self.logger.error("Parse from String error")
|
||||
return
|
||||
|
||||
|
||||
self.m_data = self.m_data[4+expected_size:]
|
||||
#self.logger.error("Data Type: %s",wrapper.type)
|
||||
|
||||
|
||||
if wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGIN:
|
||||
self.handleLoginPayload(wrapper.payload)
|
||||
|
|
18
bot.py
18
bot.py
|
@ -48,7 +48,9 @@ class Bot():
|
|||
"prune": self._prune,
|
||||
"welcome": self._welcome,
|
||||
"fortune": self._fortune,
|
||||
"sync": self._sync
|
||||
"sync": self._sync,
|
||||
"groups": self._groups,
|
||||
"getgroups": self._getgroups
|
||||
}
|
||||
|
||||
def parse(self, message):
|
||||
|
@ -173,6 +175,8 @@ class Bot():
|
|||
\\import [token] import buddies from Google
|
||||
\\sync sync your imported contacts with WhatsApp
|
||||
\\fortune [database] give me a quote
|
||||
\\groups print all attended groups
|
||||
\\getgroups get current groups from WA
|
||||
|
||||
following user commands are available:
|
||||
\\lastseen request last online timestamp from buddy""")
|
||||
|
@ -193,3 +197,15 @@ following user commands are available:
|
|||
self.session.buddies.prune()
|
||||
self.session.updateRoster()
|
||||
self.send("buddy list cleared")
|
||||
def _groups(self):
|
||||
for group in self.session.groups:
|
||||
buddy = self.session.groups[group].owner
|
||||
try:
|
||||
nick = self.session.buddies[buddy].nick
|
||||
except KeyError:
|
||||
nick = buddy
|
||||
|
||||
self.send(self.session.groups[group].id + " " + self.session.groups[group].subject + " Owner: " + nick )
|
||||
def _getgroups(self):
|
||||
self.session.call("group_getGroups", ("participating",))
|
||||
|
||||
|
|
74
session.py
74
session.py
|
@ -67,6 +67,8 @@ class Session:
|
|||
self.timer = None
|
||||
self.password = None
|
||||
self.initialized = False
|
||||
self.lastMsgId = None
|
||||
self.synced = False
|
||||
|
||||
self.buddies = BuddyList(legacyName, db)
|
||||
self.frontend = YowsupConnectionManager()
|
||||
|
@ -154,13 +156,21 @@ class Session:
|
|||
def sendMessageToWA(self, sender, message, ID):
|
||||
self.logger.info("Message (ID: %s) send from %s to %s: %s", ID, self.legacyName, sender, message)
|
||||
message = message.encode("utf-8")
|
||||
if ID == self.lastMsgId:
|
||||
return
|
||||
self.lastMsgId = ID
|
||||
|
||||
if sender == "bot":
|
||||
self.bot.parse(message)
|
||||
elif "-" in sender: # group msg
|
||||
if "/" in sender:
|
||||
room, buddy = sender.split("/")
|
||||
self.call("message_send", (buddy + "@s.whatsapp.net", message))
|
||||
room, nick2 = sender.split("/")
|
||||
buddy2 = nick2
|
||||
for buddy, buddy3 in self.buddies.iteritems():
|
||||
self.logger.info("Group buddy=%s nick=%s", buddy, buddy3.nick)
|
||||
if buddy3.nick == nick2:
|
||||
buddy2 = buddy
|
||||
self.call("message_send", (buddy2 + "@s.whatsapp.net", message))
|
||||
else:
|
||||
room = sender
|
||||
group = self.groups[room]
|
||||
|
@ -177,7 +187,11 @@ class Session:
|
|||
self.sendMessageToXMPP(buddy, "Fetching Profile Picture")
|
||||
self.call("contact_getProfilePicture", (buddy + "@s.whatsapp.net",))
|
||||
else:
|
||||
waId = self.call("message_send", (buddy + "@s.whatsapp.net", message))
|
||||
if ("jpg" in message) or ("webp" in message):
|
||||
#waId = self.call("message_imageSend", (buddy + "@s.whatsapp.net", message, None, 0, None))
|
||||
waId = self.call("message_send", (buddy + "@s.whatsapp.net", message))
|
||||
else:
|
||||
waId = self.call("message_send", (buddy + "@s.whatsapp.net", message))
|
||||
self.msgIDs[waId] = MsgIDs( ID, waId)
|
||||
self.logger.info("WA Message send to %s with ID %s", buddy, waId)
|
||||
|
||||
|
@ -196,8 +210,9 @@ class Session:
|
|||
try:
|
||||
nick = self.buddies[buddy].nick
|
||||
except KeyError:
|
||||
nick = "unknown"
|
||||
|
||||
nick = buddy
|
||||
|
||||
buddyFull = buddy
|
||||
if timestamp:
|
||||
timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp))
|
||||
|
||||
|
@ -207,10 +222,10 @@ class Session:
|
|||
if room not in self.groupOfflineQueue:
|
||||
self.groupOfflineQueue[room] = [ ]
|
||||
|
||||
self.groupOfflineQueue[room].append((buddy, messageContent + ": " + nick, timestamp))
|
||||
self.groupOfflineQueue[room].append((nick, messageContent, timestamp))
|
||||
else:
|
||||
self.logger.debug("Group message sent from %s to %s: %s", buddy, room, messageContent)
|
||||
self.backend.handleMessage(self.user, room, messageContent + ": " + nick, buddy, "", timestamp)
|
||||
self.backend.handleMessage(self.user, room, messageContent, nick , "", timestamp)
|
||||
|
||||
def changeStatus(self, status):
|
||||
if status != self.status:
|
||||
|
@ -258,10 +273,16 @@ class Session:
|
|||
self.logger.info("Joining room: %s room=%s, nick=%s", self.legacyName, room, nick)
|
||||
|
||||
group.nick = nick
|
||||
try:
|
||||
ownerNick = self.buddies[group.subjectOwner].nick
|
||||
except KeyError:
|
||||
ownerNick = group.subjectOwner
|
||||
|
||||
#time.sleep(2)
|
||||
if init == False:
|
||||
self.call("group_getParticipants", (room + "@g.us",)) #FIXME
|
||||
self.backend.handleSubject(self.user, room, group.subject, group.subjectOwner)
|
||||
self.backend.handleSubject(self.user, room, group.subject, ownerNick)
|
||||
#self.backend.handleSubject(self.user, room, group.subject, self.user)
|
||||
self.backend.handleRoomNicknameChanged(self.user,room,group.subject)
|
||||
else:
|
||||
self.logger.warn("Room doesn't exist: %s", room)
|
||||
|
@ -272,7 +293,13 @@ class Session:
|
|||
old = self.buddies.keys()
|
||||
self.buddies.load()
|
||||
new = self.buddies.keys()
|
||||
contacts = new
|
||||
#self.logger.info("Roster: %s", str(list(new)))
|
||||
|
||||
if self.synced == False:
|
||||
self.call("sync_sendSync", (contacts,))
|
||||
self.synced = True
|
||||
#self.call("sync_sendContacts", (contacts,))
|
||||
add = set(new) - set(old)
|
||||
remove = set(old) - set(new)
|
||||
|
||||
|
@ -340,7 +367,7 @@ class Session:
|
|||
#if receiptRequested:
|
||||
self.call("message_ack", (jid, messageId))
|
||||
|
||||
def onMediaReceived(self, messageId, jid, preview, url, size, receiptRequested, isBroadcast):
|
||||
def onMediaReceived(self, messageId, jid, preview, url, size, caption, timestamp, receiptRequested, pushName, isBroadcast):
|
||||
buddy = jid.split("@")[0]
|
||||
|
||||
self.logger.info("Media received from %s: %s", buddy, url)
|
||||
|
@ -349,7 +376,7 @@ class Session:
|
|||
#if receiptRequested:
|
||||
self.call("message_ack", (jid, messageId))
|
||||
|
||||
def onGroupMediaReceived(self, messageId, gjid, jid, preview, url, size, receiptRequested):
|
||||
def onGroupMediaReceived(self, messageId, gjid, jid, preview, url, size, caption, timestamp, receiptRequested, pushName):
|
||||
buddy = jid.split("@")[0]
|
||||
room = gjid.split("@")[0]
|
||||
|
||||
|
@ -362,31 +389,35 @@ class Session:
|
|||
|
||||
|
||||
|
||||
def onLocationReceived(self, messageId, jid, name, preview, latitude, longitude, receiptRequested, isBroadcast):
|
||||
def onLocationReceived(self, messageId, jid, name, preview, latitude, longitude, timestamp, receiptRequested, pushName, isBroadcast):
|
||||
buddy = jid.split("@")[0]
|
||||
self.logger.info("Location received from %s: %s, %s", buddy, latitude, longitude)
|
||||
|
||||
url = "http://maps.google.de?%s" % urllib.urlencode({ "q": "%s %s" % (latitude, longitude) })
|
||||
geo = "geo:"+latitude+","+longitude
|
||||
# self.sendMessageToXMPP(buddy, utils.shorten(url))
|
||||
self.sendMessageToXMPP(buddy, url)
|
||||
self.sendMessageToXMPP(buddy, geo)
|
||||
#if receiptRequested:
|
||||
self.call("message_ack", (jid, messageId))
|
||||
|
||||
|
||||
def onGroupLocationReceived(self, messageId, gjid, jid, name, preview, latitude, longitude, receiptRequested):
|
||||
def onGroupLocationReceived(self, messageId, gjid, jid, name, preview, latitude, longitude, timestamp, receiptRequested, pushName):
|
||||
buddy = jid.split("@")[0]
|
||||
room = gjid.split("@")[0]
|
||||
|
||||
url = "http://maps.google.de?%s" % urllib.urlencode({ "q": "%s %s" % (latitude, longitude) })
|
||||
geo = "geo:"+latitude+","+longitude
|
||||
# self.sendMessageToXMPP(buddy, utils.shorten(url))
|
||||
self.sendGroupMessageToXMPP(room, buddy, url)
|
||||
self.sendGroupMessageToXMPP(room, buddy, geo)
|
||||
#if receiptRequested:
|
||||
self.call("message_ack", (gjid, messageId))
|
||||
|
||||
|
||||
|
||||
|
||||
def onVcardReceived(self, messageId, jid, name, data, receiptRequested, isBroadcast): # TODO
|
||||
def onVcardReceived(self, messageId, jid, name, data, timestamp, receiptRequested, pushName, isBroadcast): # TODO
|
||||
buddy = jid.split("@")[0]
|
||||
self.logger.info("VCard received from %s", buddy)
|
||||
self.sendMessageToXMPP(buddy, "Received VCard (not implemented yet)")
|
||||
|
@ -469,14 +500,25 @@ class Session:
|
|||
for jid in jids:
|
||||
buddy = jid.split("@")[0]
|
||||
self.logger.info("Added %s to room %s", buddy, room)
|
||||
|
||||
try:
|
||||
nick = self.buddies[buddy].nick
|
||||
except KeyError:
|
||||
nick = buddy
|
||||
#nick = ""
|
||||
#nick = ""
|
||||
buddyFull = buddy
|
||||
if buddy == group.owner:
|
||||
flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR
|
||||
else:
|
||||
flags = protocol_pb2.PARTICIPANT_FLAG_NONE
|
||||
if buddy == self.legacyName:
|
||||
nick = group.nick
|
||||
flags = protocol_pb2.PARTICIPANT_FLAG_ME
|
||||
buddyFull = self.user
|
||||
|
||||
self.backend.handleParticipantChanged(self.user, buddy, room, flags, protocol_pb2.STATUS_ONLINE,"Nici","") # TODO check status
|
||||
|
||||
self.backend.handleParticipantChanged(self.user, buddyFull, room, flags, protocol_pb2.STATUS_ONLINE, buddy, nick) # TODO check status
|
||||
#self.backend.handleParticipantChanged(self.user, buddy , room, flags, protocol_pb2.STATUS_ONLINE, buddy, nick) # TODO check sta
|
||||
if room in self.groupOfflineQueue:
|
||||
while self.groupOfflineQueue[room]:
|
||||
msg = self.groupOfflineQueue[room].pop(0)
|
||||
|
@ -552,7 +594,7 @@ class Session:
|
|||
self.db.commit()
|
||||
|
||||
|
||||
# if receiptRequested: self.call("notification_ack", (jid, messageId))
|
||||
#if receiptRequested: self.call("notification_ack", (jid, messageId))
|
||||
|
||||
def onReceiptMessageDeliverd(self, jid, msgId):
|
||||
buddy = jid.split("@")[0]
|
||||
|
|
|
@ -63,7 +63,7 @@ class WhatsAppBackend(SpectrumBackend):
|
|||
del self.sessions[user]
|
||||
|
||||
def handleMessageSendRequest(self, user, buddy, message, xhtml = "", ID = 0):
|
||||
self.logger.debug("handleMessageSendRequest(user=%s, buddy=%s, message=%s, id=%d)", user, buddy, message, ID)
|
||||
self.logger.info("handleMessageSendRequest(user=%s, buddy=%s, message=%s, id=%s)", user, buddy, message, ID)
|
||||
if user not in self.sessions:
|
||||
return;
|
||||
self.sessions[user].sendMessageToWA(buddy, message, ID)
|
||||
|
|
Loading…
Reference in New Issue