Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
38f66147cb | ||
|
ffa26c20b5 | ||
|
430ada7f84 | ||
|
988e37eb42 | ||
|
1938b90bce | ||
|
f61d1403f3 | ||
|
d228f34f64 | ||
|
97049556ed | ||
|
b64c6a94cc | ||
|
edc655bae7 | ||
|
884af48270 | ||
|
95f018fad3 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -29,3 +29,6 @@ my_tests.py
|
|||||||
my_test_data.json
|
my_test_data.json
|
||||||
my_data.json
|
my_data.json
|
||||||
tests.data
|
tests.data
|
||||||
|
|
||||||
|
# Virtual environment
|
||||||
|
venv/
|
||||||
|
@@ -5,8 +5,8 @@ from fbchat import log, Client
|
|||||||
# Subclass fbchat.Client and override required methods
|
# Subclass fbchat.Client and override required methods
|
||||||
class EchoBot(Client):
|
class EchoBot(Client):
|
||||||
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
|
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
|
||||||
self.markAsDelivered(author_id, thread_id)
|
self.markAsDelivered(thread_id, message_object.uid)
|
||||||
self.markAsRead(author_id)
|
self.markAsRead(thread_id)
|
||||||
|
|
||||||
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
|
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@ from .client import *
|
|||||||
|
|
||||||
|
|
||||||
__copyright__ = 'Copyright 2015 - {} by Taehoon Kim'.format(datetime.now().year)
|
__copyright__ = 'Copyright 2015 - {} by Taehoon Kim'.format(datetime.now().year)
|
||||||
__version__ = '1.3.5'
|
__version__ = '1.3.7'
|
||||||
__license__ = 'BSD'
|
__license__ = 'BSD'
|
||||||
__author__ = 'Taehoon Kim; Moreels Pieter-Jan; Mads Marquart'
|
__author__ = 'Taehoon Kim; Moreels Pieter-Jan; Mads Marquart'
|
||||||
__email__ = 'carpedm20@gmail.com'
|
__email__ = 'carpedm20@gmail.com'
|
||||||
|
@@ -138,8 +138,9 @@ class Client(object):
|
|||||||
return self._graphql(payload, error_retries=error_retries-1)
|
return self._graphql(payload, error_retries=error_retries-1)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def _cleanGet(self, url, query=None, timeout=30):
|
def _cleanGet(self, url, query=None, timeout=30, allow_redirects=True):
|
||||||
return self._session.get(url, headers=self._header, params=query, timeout=timeout, verify=self.ssl_verify)
|
return self._session.get(url, headers=self._header, params=query, timeout=timeout, verify=self.ssl_verify,
|
||||||
|
allow_redirects=allow_redirects)
|
||||||
|
|
||||||
def _cleanPost(self, url, query=None, timeout=30):
|
def _cleanPost(self, url, query=None, timeout=30):
|
||||||
self.req_counter += 1
|
self.req_counter += 1
|
||||||
@@ -209,8 +210,18 @@ class Client(object):
|
|||||||
|
|
||||||
r = self._get(self.req_url.BASE)
|
r = self._get(self.req_url.BASE)
|
||||||
soup = bs(r.text, "lxml")
|
soup = bs(r.text, "lxml")
|
||||||
self.fb_dtsg = soup.find("input", {'name':'fb_dtsg'})['value']
|
|
||||||
self.fb_h = soup.find("input", {'name':'h'})['value']
|
fb_dtsg_element = soup.find("input", {'name': 'fb_dtsg'})
|
||||||
|
if fb_dtsg_element:
|
||||||
|
self.fb_dtsg = fb_dtsg_element['value']
|
||||||
|
else:
|
||||||
|
self.fb_dtsg = re.search(r'name="fb_dtsg" value="(.*?)"', r.text).group(1)
|
||||||
|
|
||||||
|
|
||||||
|
fb_h_element = soup.find("input", {'name':'h'})
|
||||||
|
if fb_h_element:
|
||||||
|
self.fb_h = fb_h_element['value']
|
||||||
|
|
||||||
for i in self.fb_dtsg:
|
for i in self.fb_dtsg:
|
||||||
self.ttstamp += str(ord(i))
|
self.ttstamp += str(ord(i))
|
||||||
self.ttstamp += '2'
|
self.ttstamp += '2'
|
||||||
@@ -325,8 +336,8 @@ class Client(object):
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
# Send a request to the login url, to see if we're directed to the home page
|
# Send a request to the login url, to see if we're directed to the home page
|
||||||
r = self._cleanGet(self.req_url.LOGIN)
|
r = self._cleanGet(self.req_url.LOGIN, allow_redirects=False)
|
||||||
return 'home' in r.url
|
return 'Location' in r.headers and 'home' in r.headers['Location']
|
||||||
|
|
||||||
def getSession(self):
|
def getSession(self):
|
||||||
"""Retrieves session cookies
|
"""Retrieves session cookies
|
||||||
@@ -400,6 +411,11 @@ class Client(object):
|
|||||||
:return: True if the action was successful
|
:return: True if the action was successful
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not hasattr(self, 'fb_h'):
|
||||||
|
h_r = self._post(self.req_url.MODERN_SETTINGS_MENU, {'pmid': '4'})
|
||||||
|
self.fb_h = re.search(r'name=\\"h\\" value=\\"(.*?)\\"', h_r.text).group(1)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'ref': "mb",
|
'ref': "mb",
|
||||||
'h': self.fb_h
|
'h': self.fb_h
|
||||||
@@ -1269,9 +1285,9 @@ class Client(object):
|
|||||||
:raises: FBchatException if request failed
|
:raises: FBchatException if request failed
|
||||||
"""
|
"""
|
||||||
data = {
|
data = {
|
||||||
"ids[%s]" % thread_id: True,
|
"ids[%s]" % thread_id: 'true',
|
||||||
"watermarkTimestamp": now(),
|
"watermarkTimestamp": now(),
|
||||||
"shouldSendReadReceipt": True,
|
"shouldSendReadReceipt": 'true',
|
||||||
}
|
}
|
||||||
|
|
||||||
r = self._post(self.req_url.READ_STATUS, data)
|
r = self._post(self.req_url.READ_STATUS, data)
|
||||||
|
@@ -190,7 +190,7 @@ def graphql_to_thread(thread):
|
|||||||
url=user.get('url'),
|
url=user.get('url'),
|
||||||
name=user.get('name'),
|
name=user.get('name'),
|
||||||
first_name=user.get('short_name'),
|
first_name=user.get('short_name'),
|
||||||
last_name=user.get('name').split(user.get('short_name'),1)[1].strip(),
|
last_name=user.get('name').split(user.get('short_name'),1).pop().strip(),
|
||||||
is_friend=user.get('is_viewer_friend'),
|
is_friend=user.get('is_viewer_friend'),
|
||||||
gender=GENDERS.get(user.get('gender')),
|
gender=GENDERS.get(user.get('gender')),
|
||||||
affinity=user.get('affinity'),
|
affinity=user.get('affinity'),
|
||||||
|
@@ -469,7 +469,7 @@ class EmojiSize(Enum):
|
|||||||
|
|
||||||
class ThreadColor(Enum):
|
class ThreadColor(Enum):
|
||||||
"""Used to specify a thread colors"""
|
"""Used to specify a thread colors"""
|
||||||
MESSENGER_BLUE = ''
|
MESSENGER_BLUE = '#0084ff'
|
||||||
VIKING = '#44bec7'
|
VIKING = '#44bec7'
|
||||||
GOLDEN_POPPY = '#ffc300'
|
GOLDEN_POPPY = '#ffc300'
|
||||||
RADICAL_RED = '#fa3c4c'
|
RADICAL_RED = '#fa3c4c'
|
||||||
|
@@ -121,6 +121,7 @@ class ReqUrl(object):
|
|||||||
GRAPHQL = "https://www.facebook.com/api/graphqlbatch/"
|
GRAPHQL = "https://www.facebook.com/api/graphqlbatch/"
|
||||||
ATTACHMENT_PHOTO = "https://www.facebook.com/mercury/attachments/photo/"
|
ATTACHMENT_PHOTO = "https://www.facebook.com/mercury/attachments/photo/"
|
||||||
EVENT_REMINDER = "https://www.facebook.com/ajax/eventreminder/create"
|
EVENT_REMINDER = "https://www.facebook.com/ajax/eventreminder/create"
|
||||||
|
MODERN_SETTINGS_MENU = "https://www.facebook.com/bluebar/modern_settings_menu/"
|
||||||
|
|
||||||
pull_channel = 0
|
pull_channel = 0
|
||||||
|
|
||||||
|
2
tests.py
2
tests.py
@@ -114,7 +114,7 @@ class TestFbchat(unittest.TestCase):
|
|||||||
self.assertIsNotNone(client.send(Message(sticker=Sticker(test_sticker_id))))
|
self.assertIsNotNone(client.send(Message(sticker=Sticker(test_sticker_id))))
|
||||||
|
|
||||||
def test_sendImages(self):
|
def test_sendImages(self):
|
||||||
image_url = 'https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-image-128.png'
|
image_url = 'https://github.com/carpedm20/fbchat/raw/master/tests/image.png'
|
||||||
image_local_url = path.join(path.dirname(__file__), 'tests/image.png')
|
image_local_url = path.join(path.dirname(__file__), 'tests/image.png')
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
client.setDefaultThread(thread_id=thread['id'], thread_type=thread['type'])
|
client.setDefaultThread(thread_id=thread['id'], thread_type=thread['type'])
|
||||||
|
Reference in New Issue
Block a user