From 72eca6b032a382fc864d543d1c39132f283eb8f7 Mon Sep 17 00:00:00 2001 From: Michael Chesterton Date: Wed, 1 May 2019 16:12:52 +1000 Subject: [PATCH 1/2] add support for getting sms messages from pushbullet import Pushbullet api_key = 'replace with your api key' encryption_key = 'replace with your encryption key' pb = Pushbullet(api_key, encryption_key) device = pb.get_device('replace with your device nickname') threads = pb.get_permanents(device) for thread in threads: messages = pb.get_permanent(device, thread['id']) print(messages) I guess it's using an undocumented api feature and i haven't done extensive testing, for example I don't know if a cursor is ever sent. I've tested url parameters like limit= and modified_after= and they didn't appear to work. --- pushbullet/pushbullet.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pushbullet/pushbullet.py b/pushbullet/pushbullet.py index 2723202..0e2f940 100644 --- a/pushbullet/pushbullet.py +++ b/pushbullet/pushbullet.py @@ -26,6 +26,7 @@ class Pushbullet(object): PUSH_URL = "https://api.pushbullet.com/v2/pushes" UPLOAD_REQUEST_URL = "https://api.pushbullet.com/v2/upload-request" EPHEMERALS_URL = "https://api.pushbullet.com/v2/ephemerals" + PERMANENTS_URL = "https://api.pushbullet.com/v2/permanents" def __init__(self, api_key, encryption_password=None, proxy=None): self.api_key = api_key @@ -353,3 +354,42 @@ def refresh(self): self._load_chats() self._load_user_info() self._load_channels() + + def _get_json(self, r): + if hasattr(r, 'json'): + if r.json().get('encrypted'): + return json.loads(self._decrypt_data(r.json().get('ciphertext'))) + else: + return r.json() + return {} + + def get_permanents(self, device, modified_after=None, limit=None, filter_inactive=True): + thread_url = '_threads' + thread_element = 'threads' + return self._get_permanents(device, thread_url, thread_element, modified_after=modified_after, limit=limit, + filter_inactive=filter_inactive) + + def get_permanent(self, device, thread, modified_after=None, limit=None, filter_inactive=True): + thread_url = '_thread_' + str(thread) + thread_element = 'thread' + return self._get_permanents(device, thread_url, thread_element, modified_after=modified_after, limit=limit, + filter_inactive=filter_inactive) + + def _get_permanents(self, device, thread_url, thread_element, modified_after=None, limit=None, + filter_inactive=True): + data = {"modified_after": modified_after, "limit": limit} + if filter_inactive: + data['active'] = "true" + permanents_list = [] + get_more_permanents = True + while get_more_permanents: + r = self._session.get(self.PERMANENTS_URL + '/' + device.device_iden + thread_url, params=data) + if r.status_code != requests.codes.ok: + raise PushbulletError(r.text) + json_data = self._get_json(r) + permanents_list += json_data.get(thread_element) + if 'cursor' in json_data and (not limit or len(permanents_list) < limit): + data['cursor'] = json_data['cursor'] + else: + get_more_permanents = False + return permanents_list From ffee782043e977f267b5f1da7a491893b0c8a7c2 Mon Sep 17 00:00:00 2001 From: Michael Chesterton Date: Fri, 7 Jun 2019 15:12:36 +1000 Subject: [PATCH 2/2] Clean up add support for getting sms messages import json from pushbullet import Pushbullet api_key = 'your api key' encryption_key = 'your encryption key' pb = Pushbullet(api_key, encryption_key) device = pb.get_device('your device nickname') threads = pb.get_threads(device) for thread in json.loads(pb._decrypt_data(threads.get('ciphertext'))).get('threads'): messages = pb.get_thread(device, int(thread['id'])) print(json.loads(pb._decrypt_data(messages.get('ciphertext')))) --- pushbullet/pushbullet.py | 51 ++++++++++------------------------------ 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/pushbullet/pushbullet.py b/pushbullet/pushbullet.py index 0e2f940..994c91f 100644 --- a/pushbullet/pushbullet.py +++ b/pushbullet/pushbullet.py @@ -355,41 +355,16 @@ def refresh(self): self._load_user_info() self._load_channels() - def _get_json(self, r): - if hasattr(r, 'json'): - if r.json().get('encrypted'): - return json.loads(self._decrypt_data(r.json().get('ciphertext'))) - else: - return r.json() - return {} - - def get_permanents(self, device, modified_after=None, limit=None, filter_inactive=True): - thread_url = '_threads' - thread_element = 'threads' - return self._get_permanents(device, thread_url, thread_element, modified_after=modified_after, limit=limit, - filter_inactive=filter_inactive) - - def get_permanent(self, device, thread, modified_after=None, limit=None, filter_inactive=True): - thread_url = '_thread_' + str(thread) - thread_element = 'thread' - return self._get_permanents(device, thread_url, thread_element, modified_after=modified_after, limit=limit, - filter_inactive=filter_inactive) - - def _get_permanents(self, device, thread_url, thread_element, modified_after=None, limit=None, - filter_inactive=True): - data = {"modified_after": modified_after, "limit": limit} - if filter_inactive: - data['active'] = "true" - permanents_list = [] - get_more_permanents = True - while get_more_permanents: - r = self._session.get(self.PERMANENTS_URL + '/' + device.device_iden + thread_url, params=data) - if r.status_code != requests.codes.ok: - raise PushbulletError(r.text) - json_data = self._get_json(r) - permanents_list += json_data.get(thread_element) - if 'cursor' in json_data and (not limit or len(permanents_list) < limit): - data['cursor'] = json_data['cursor'] - else: - get_more_permanents = False - return permanents_list + def get_threads(self, device): + permanents_url = '_threads' + return self._get_permanents(device, permanents_url) + + def get_thread(self, device, thread): + permanents_url = '_thread_' + str(thread) + return self._get_permanents(device, permanents_url) + + def _get_permanents(self, device, permanents_url): + r = self._session.get(self.PERMANENTS_URL + '/' + device.device_iden + permanents_url) + if r.status_code != requests.codes.ok: + raise PushbulletError(r.text) + return r.json()