Merge pull request #22 from PidgeyL/master

New features
This commit is contained in:
Taehoon Kim
2016-01-05 22:32:19 +09:00
3 changed files with 120 additions and 3 deletions

View File

@@ -15,9 +15,9 @@ from .client import *
__copyright__ = 'Copyright 2015 by Taehoon Kim'
__version__ = '0.2.3'
__version__ = '0.3.0'
__license__ = 'BSD'
__author__ = 'Taehoon Kim'
__author__ = 'Taehoon Kim; Moreels Pieter-Jan'
__email__ = 'carpedm20@gmail.com'
__source__ = 'https://github.com/carpedm20/fbchat/'

View File

@@ -32,6 +32,8 @@ DeliveredURL ="https://www.facebook.com/ajax/mercury/delivery_receipts.php"
MarkSeenURL ="https://www.facebook.com/ajax/mercury/mark_seen.php"
BaseURL ="https://www.facebook.com"
MobileURL ="https://m.facebook.com/"
StickyURL ="https://0-edge-chat.facebook.com/pull"
PingURL ="https://0-channel-proxy-06-ash2.facebook.com/active_ping"
class Client(object):
"""A client for the Facebook Chat (Messenger).
@@ -199,6 +201,7 @@ class Client(object):
:param message: a text that you want to send
:param like: size of the like sticker you want to send
"""
timestamp = now()
date = datetime.now()
data = {
@@ -346,3 +349,117 @@ class Client(object):
r = self._post(MarkSeenURL, {"seen_timestamp": 0})
return r.ok
def ping(self, sticky):
data={
'channel': self.user_channel,
'clientid': self.client_id,
'partition': -2,
'cap': 0,
'uid': self.uid,
'sticky': sticky,
'viewer_uid': self.uid
}
r = self._get(PingURL, data)
return r.ok
def _getSticky(self):
'''
Call pull api to get sticky and pool parameter,
newer api needs these parameter to work.
'''
data={ "msgs_recv": 0 }
r = self._get(StickyURL, data)
j = get_json(r.text)
if 'lb_info' not in j:
raise Exception('Get sticky pool error')
sticky = j['lb_info']['sticky']
pool = j['lb_info']['pool']
return sticky, pool
def _pullMessage(self, sticky, pool):
'''
Call pull api with seq value to get message data.
'''
data={
"msgs_recv": 0,
"sticky_token":sticky,
"sticky_pool":pool
}
r = self._get(StickyURL, data)
j = get_json(r.text)
self.seq = j.get('seq', '0')
return j
def _parseMessage(self, content):
'''
Get message and author name from content.
May contains multiple messages in the content.
'''
if 'ms' not in content:
return
for m in content['ms']:
if m['type'] in ['m_messaging', 'messaging']:
try:
mid = m['message']['mid']
message=m['message']['body']
fbid = m['message']['sender_fbid']
name = m['message']['sender_name']
self.on_message(mid, fbid, name, message, m)
except:
pass
elif m['type'] in ['typ']:
try:
fbid = m["from"]
self.on_typing(fbid)
except:
pass
elif m['type'] in ['m_read_receipt']:
try:
author = m['author']
reader = m['reader']
time = m['time']
self.on_read(author, reader, time)
except:
pass
else:
print(m)
def listen(self, markAlive=True):
self.listening = True
sticky, pool = self._getSticky()
if self.debug:
print("Listening...")
while self.listening:
try:
if markAlive: self.ping(sticky)
try:
content = self._pullMessage(sticky, pool)
self._parseMessage(content)
except requests.exceptions.RequestException as e:
continue
except KeyboardInterrupt:
break
except requests.exceptions.Timeout:
pass
def on_message(self, mid, author_id, author_name, message, metadata):
self.markAsDelivered(author_id, mid)
self.markAsRead(author_id)
print("%s said: %s"%(author_name, message))
def on_typing(self, author_id):
pass
def on_read(self, author, reader, time):
pass