Merge pull request #53 from JohnathonNow/master

Added support for sending images
This commit is contained in:
Taehoon Kim
2016-08-21 22:35:22 +09:00
committed by GitHub

View File

@@ -12,10 +12,12 @@
""" """
import requests import requests
import json
from uuid import uuid1 from uuid import uuid1
from random import random, choice from random import random, choice
from datetime import datetime from datetime import datetime
from bs4 import BeautifulSoup as bs from bs4 import BeautifulSoup as bs
from mimetypes import guess_type
from .utils import * from .utils import *
from .models import * from .models import *
@@ -35,6 +37,8 @@ BaseURL ="https://www.facebook.com"
MobileURL ="https://m.facebook.com/" MobileURL ="https://m.facebook.com/"
StickyURL ="https://0-edge-chat.facebook.com/pull" StickyURL ="https://0-edge-chat.facebook.com/pull"
PingURL ="https://0-channel-proxy-06-ash2.facebook.com/active_ping" PingURL ="https://0-channel-proxy-06-ash2.facebook.com/active_ping"
UploadURL ="https://upload.facebook.com/ajax/mercury/upload.php"
class Client(object): class Client(object):
"""A client for the Facebook Chat (Messenger). """A client for the Facebook Chat (Messenger).
@@ -118,7 +122,12 @@ class Client(object):
def _cleanPost(self, url, query=None, timeout=30): def _cleanPost(self, url, query=None, timeout=30):
self.req_counter += 1 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)
def _postFile(self, url, files=None, timeout=30):
payload=self._generatePayload(None)
return self._session.post(url, data=payload, timeout=timeout, files=files)
def login(self): def login(self):
if not (self.email and self.password): if not (self.email and self.password):
raise Exception("id and password or config is needed") raise Exception("id and password or config is needed")
@@ -196,13 +205,14 @@ class Client(object):
users.append(User(entry)) users.append(User(entry))
return users # have bug TypeError: __repr__ returned non-string (type bytes) return users # have bug TypeError: __repr__ returned non-string (type bytes)
def send(self, recipient_id, message=None, message_type='user', like=None): def send(self, recipient_id, message=None, message_type='user', like=None, image_id=None):
"""Send a message with given thread id """Send a message with given thread id
:param recipient_id: the user id or thread id that you want to send a message to :param recipient_id: the user id or thread id that you want to send a message to
:param message: a text that you want to send :param message: a text that you want to send
:param message_type: determines if the recipient_id is for user or thread :param message_type: determines if the recipient_id is for user or thread
:param like: size of the like sticker you want to send :param like: size of the like sticker you want to send
:param image_id: id for the image to send, gotten from the UploadURL
""" """
if message_type.lower() == 'group': if message_type.lower() == 'group':
@@ -238,9 +248,12 @@ class Client(object):
'message_batch[0][message_id]' : generateMessageID(self.client_id), 'message_batch[0][message_id]' : generateMessageID(self.client_id),
'message_batch[0][manual_retry_cnt]' : '0', 'message_batch[0][manual_retry_cnt]' : '0',
'message_batch[0][thread_fbid]' : thread_id, 'message_batch[0][thread_fbid]' : thread_id,
'message_batch[0][has_attachment]' : False, 'message_batch[0][has_attachment]' : image_id != None,
'message_batch[0][other_user_fbid]' : user_id 'message_batch[0][other_user_fbid]' : user_id
} }
if image_id:
data['message_batch[0][image_ids][0]'] = image_id
if like: if like:
try: try:
@@ -253,7 +266,40 @@ class Client(object):
r = self._post(SendURL, data) r = self._post(SendURL, data)
return r.ok return r.ok
def sendRemoteImage(self, recipient_id, message=None, message_type='user', image=''):
"""Send an image from a URL
:param recipient_id: the user id or thread id that you want to send a message to
:param message: a text that you want to send
:param message_type: determines if the recipient_id is for user or thread
:param image: URL for an image to download and send
"""
mimetype = guess_type(image)[0]
remote_image = requests.get(image).content
image_id = self.uploadImage({'file': (image, remote_image, mimetype)})
return self.send(recipient_id, message, message_type, None, image_id)
def sendLocalImage(self, recipient_id, message=None, message_type='user', image=''):
"""Send an image from a file path
:param recipient_id: the user id or thread id that you want to send a message to
:param message: a text that you want to send
:param message_type: determines if the recipient_id is for user or thread
:param image: path to a local image to send
"""
mimetype = guess_type(image)[0]
image_id = self.uploadImage({'file': (image, open(image), mimetype)})
return self.send(recipient_id, message, message_type, None, image_id)
def uploadImage(self, image):
"""Upload an image and get the image_id for sending in a message
:param image: a tuple of (file name, data, mime type) to upload to facebook
"""
r = self._postFile(UploadURL, image)
# Strip the start and parse out the returned image_id
return json.loads(r._content[9:])['payload']['metadata'][0]['image_id']
def getThreadInfo(self, userID, start, end=None): def getThreadInfo(self, userID, start, end=None):
"""Get the info of one Thread """Get the info of one Thread