Compare commits

..

11 Commits

Author SHA1 Message Date
Mads Marquart
884af48270 Version up, thanks to @gave92
Properly fixed `markAsRead`, @gave92  reminded me that I forgot to change the `True` to `'true'` when removing `encode_params`
2018-03-21 10:05:07 +01:00
Mads Marquart
95f018fad3 Fixed example Echobot 2018-03-19 21:40:51 +01:00
Mads Marquart
b44758a195 Version up, thanks to @gave92
Fix `markAsRead` and `fetchUnread`; fixes #261
Added the `ssl_verify` instance variable, which allows disabling SSL varification for proxies
2018-03-19 21:28:48 +01:00
Mads Marquart
f1c20d490e Removed encode_params from PR, as discussed in #269 2018-03-19 21:15:23 +01:00
Mads Marquart
04372d498e Merge pull request #269 from gave92/FetchUnread
Fix `markAsRead` and `fetchUnread`; fixes #261
Added the `ssl_verify` instance variable, which allows disabling SSL varification for proxies
2018-03-19 21:08:45 +01:00
Marco Gavelli
63ea899605 fix for python3 2018-03-19 20:47:41 +01:00
Marco Gavelli
4fdd145d1e verify in _postFile 2018-03-19 16:52:22 +01:00
Marco Gavelli
57ee68b0e0 added documentation to markAsRead 2018-03-19 16:38:19 +01:00
Marco Gavelli
99c6884681 added documentation to fetchUnread 2018-03-19 16:29:26 +01:00
Marco Gavelli
1c1438e9bc fix for markAsRead, fetchUnread 2018-03-18 11:18:46 +01:00
Marco Gavelli
22f1b3e489 fix FetchUnread 2018-03-17 19:32:45 +01:00
5 changed files with 58 additions and 29 deletions

5
.gitignore vendored
View File

@@ -24,7 +24,8 @@ develop-eggs
# Sphinx documentation
docs/_build/
# Data for tests
# Scripts and data for tests
my_tests.py
my_test_data.json
my_data.json
tests.data
tests.data

View File

@@ -5,8 +5,8 @@ from fbchat import log, Client
# Subclass fbchat.Client and override required methods
class EchoBot(Client):
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
self.markAsDelivered(author_id, thread_id)
self.markAsRead(author_id)
self.markAsDelivered(thread_id, message_object.uid)
self.markAsRead(thread_id)
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))

View File

@@ -17,7 +17,7 @@ from .client import *
__copyright__ = 'Copyright 2015 - {} by Taehoon Kim'.format(datetime.now().year)
__version__ = '1.3.4'
__version__ = '1.3.6'
__license__ = 'BSD'
__author__ = 'Taehoon Kim; Moreels Pieter-Jan; Mads Marquart'
__email__ = 'carpedm20@gmail.com'

View File

@@ -20,6 +20,8 @@ class Client(object):
See https://fbchat.readthedocs.io for complete documentation of the API.
"""
ssl_verify = True
"""Verify ssl certificate, set to False to allow debugging with a proxy"""
listening = False
"""Whether the client is listening. Used when creating an external event loop to determine when to stop listening"""
uid = None
@@ -105,7 +107,7 @@ class Client(object):
def _get(self, url, query=None, timeout=30, fix_request=False, as_json=False, error_retries=3):
payload = self._generatePayload(query)
r = self._session.get(url, headers=self._header, params=payload, timeout=timeout)
r = self._session.get(url, headers=self._header, params=payload, timeout=timeout, verify=self.ssl_verify)
if not fix_request:
return r
try:
@@ -117,7 +119,7 @@ class Client(object):
def _post(self, url, query=None, timeout=30, fix_request=False, as_json=False, error_retries=3):
payload = self._generatePayload(query)
r = self._session.post(url, headers=self._header, data=payload, timeout=timeout)
r = self._session.post(url, headers=self._header, data=payload, timeout=timeout, verify=self.ssl_verify)
if not fix_request:
return r
try:
@@ -137,17 +139,17 @@ class Client(object):
raise e
def _cleanGet(self, url, query=None, timeout=30):
return self._session.get(url, headers=self._header, params=query, timeout=timeout)
return self._session.get(url, headers=self._header, params=query, timeout=timeout, verify=self.ssl_verify)
def _cleanPost(self, url, query=None, timeout=30):
self.req_counter += 1
return self._session.post(url, headers=self._header, data=query, timeout=timeout)
return self._session.post(url, headers=self._header, data=query, timeout=timeout, verify=self.ssl_verify)
def _postFile(self, url, files=None, query=None, timeout=30, fix_request=False, as_json=False, error_retries=3):
payload=self._generatePayload(query)
# Removes 'Content-Type' from the header
headers = dict((i, self._header[i]) for i in self._header if i != 'Content-Type')
r = self._session.post(url, headers=headers, data=payload, timeout=timeout, files=files)
r = self._session.post(url, headers=headers, data=payload, timeout=timeout, files=files, verify=self.ssl_verify)
if not fix_request:
return r
try:
@@ -791,24 +793,34 @@ class Client(object):
def fetchUnread(self):
"""
.. todo::
Documenting this
Get the unread thread list
:return: List of unread thread ids
:rtype: list
:raises: FBchatException if request failed
"""
form = {
'client': 'mercury_sync',
'folders[0]': 'inbox',
'client': 'mercury',
'last_action_timestamp': now() - 60*1000
# 'last_action_timestamp': 0
}
j = self._post(self.req_url.THREAD_SYNC, form, fix_request=True, as_json=True)
j = self._post(self.req_url.UNREAD_THREADS, form, fix_request=True, as_json=True)
return {
"message_counts": j['payload']['message_counts'],
"unseen_threads": j['payload']['unseen_thread_ids']
}
return j['payload']['unread_thread_fbids'][0]['other_user_fbids']
def fetchUnseen(self):
"""
Get the unseen (new) thread list
:return: List of unseen thread ids
:rtype: list
:raises: FBchatException if request failed
"""
j = self._post(self.req_url.UNSEEN_THREADS, None, fix_request=True, as_json=True)
return j['payload']['unseen_thread_fbids'][0]['other_user_fbids']
def fetchImageUrl(self, image_id):
"""Fetches the url to the original image from an image attachment ID
@@ -1230,28 +1242,36 @@ class Client(object):
END SEND METHODS
"""
def markAsDelivered(self, userID, threadID):
def markAsDelivered(self, thread_id, message_id):
"""
.. todo::
Documenting this
Mark a message as delivered
:param thread_id: User/Group ID to which the message belongs. See :ref:`intro_threads`
:param message_id: Message ID to set as delivered. See :ref:`intro_threads`
:return: Whether the request was successful
:raises: FBchatException if request failed
"""
data = {
"message_ids[0]": threadID,
"thread_ids[%s][0]" % userID: threadID
"message_ids[0]": message_id,
"thread_ids[%s][0]" % thread_id: message_id
}
r = self._post(self.req_url.DELIVERED, data)
return r.ok
def markAsRead(self, userID):
def markAsRead(self, thread_id):
"""
.. todo::
Documenting this
Mark a thread as read
All messages inside the thread will be marked as read
:param thread_id: User/Group ID to set as read. See :ref:`intro_threads`
:return: Whether the request was successful
:raises: FBchatException if request failed
"""
data = {
"ids[%s]" % thread_id: 'true',
"watermarkTimestamp": now(),
"shouldSendReadReceipt": True,
"ids[%s]" % userID: True
"shouldSendReadReceipt": 'true',
}
r = self._post(self.req_url.READ_STATUS, data)

View File

@@ -9,6 +9,13 @@ import warnings
import logging
from .models import *
try:
from urllib.parse import urlencode
basestring = (str, bytes)
except ImportError:
from urllib import urlencode
basestring = basestring
# Python 2's `input` executes the input, whereas `raw_input` just returns the input
try:
input = raw_input
@@ -87,7 +94,8 @@ class ReqUrl(object):
SEARCH = "https://www.facebook.com/ajax/typeahead/search.php"
LOGIN = "https://m.facebook.com/login.php?login_attempt=1"
SEND = "https://www.facebook.com/messaging/send/"
THREAD_SYNC = "https://www.facebook.com/ajax/mercury/thread_sync.php"
UNREAD_THREADS = "https://www.facebook.com/ajax/mercury/unread_threads.php"
UNSEEN_THREADS = "https://www.facebook.com/mercury/unseen_thread_ids/"
THREADS = "https://www.facebook.com/ajax/mercury/threadlist_info.php"
MESSAGES = "https://www.facebook.com/ajax/mercury/thread_info.php"
READ_STATUS = "https://www.facebook.com/ajax/mercury/change_read_status.php"