Skip to content

Commit

Permalink
Merge pull request #17 from bstoilov/messages
Browse files Browse the repository at this point in the history
adding support for direct messages
  • Loading branch information
bstoilov committed Oct 10, 2019
2 parents 8abbf90 + 98e044f commit dc61603
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 12 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -128,6 +128,9 @@ Current pinterest scopes are: pins, buyable_pins, my_pins, videos, users, boards

```pinterest.load_pin(pin_id='pin_id')```

### Send perosnal message
```pinterest.send_message(conversation_id=conversation_id, pin_id="(pin_id)", message="hey")```




14 changes: 6 additions & 8 deletions examples.py
Expand Up @@ -37,7 +37,8 @@ def get_board_pins():
feed_batch = pinterest.board_feed(board_id=board_id, board_url=board_url)
while len(feed_batch) > 0:
board_feed += feed_batch
feed_batch = pinterest.board_feed(board_id=board_id, board_url=board_url)
feed_batch = pinterest.board_feed(
board_id=board_id, board_url=board_url)

return board_feed

Expand Down Expand Up @@ -113,7 +114,8 @@ def get_board_pin_recommendations():
board_id = 'board_id'
max_len = 100
rec_pins = []
rec_batch = pinterest.board_recommendations(board_url=board_url, board_id=board_id)
rec_batch = pinterest.board_recommendations(
board_url=board_url, board_id=board_id)
while len(rec_batch) > 0:
rec_pins += rec_batch
if len(rec_pins) > max_len:
Expand All @@ -131,11 +133,6 @@ def pin():
return pinterest.pin(board_id=board_id, image_url=image_url, description=description, title=title, link=link)


def delete_pin():
pin_id = 'some pin id'
return pinterest.delete_pin(pin_id=pin_id)


def search():
# After change in pinterest API, you can no longer search for users
# Instead you need to search for something else and extract the user data from there.
Expand Down Expand Up @@ -182,7 +179,8 @@ def get_board_invites():
board_url = 'board_url'
board_id = 'board_id'
invites = []
invites_batch = pinterest.get_board_invites(board_url=board_url, board_id=board_id)
invites_batch = pinterest.get_board_invites(
board_url=board_url, board_id=board_id)
while len(invites_batch) > 0:
invites += invites_batch
return invites
Expand Down
86 changes: 86 additions & 0 deletions messages_example.py
@@ -0,0 +1,86 @@
from py3pin.Pinterest import Pinterest

username = 'username'
password = 'password!'
email = 'email'
# cred_root is the place the user sessions and cookies will be stored you should specify this to avoid permission issues
cred_root = 'cred_root'

pinterest = Pinterest(email=email,
password=password,
username=username,
cred_root=cred_root)


# get the user id by username
def get_user_id(username):
return pinterest.get_user_overview(username=username)['id']


# Pinterest conversations are stored in a list of conversation object on their side.
# Each converastion has id and last message they use to display on the initial drop down once you click the message button
def get_all_conversations():
return pinterest.get_conversations()


# Once you obtain a conversation id, only then you can see all the messages and participants in it.
def load_conversation(conversation_id):
return pinterest.load_conversation(conversation_id=conversation_id)


# in order to have conversation with some one, it needs to be initialized once with some initial message
# this is called once per user (or group of users)
# the method receives array of users, this way grop conversations are started
# calling this method multiple times for the same user does nothing
def initiate_conversation(username, message):
usernames = [username]

# get the user id by username
user_ids = []
for u in usernames:
user_ids.append(get_user_id(u))

pinterest.initiate_conversation(user_ids=user_ids, message=message)


# search for conversation with specific user
# NOTE: he might be part of multiple conversations (group conversations)
def find_conversation_by_username(username):
conversations = pinterest.get_conversations()
conversation_ids = []

# get all conversations in which username is found
for c in conversations:
conv_usernames = []
for usr in c['users']:
conv_usernames.append(usr['username'])
if username in conv_usernames:
conversation_ids.append(c['id'])

return conversation_ids


# send message to user
# if this is the first time new conversation will be created
def send_message(username, message):
conversations_ids = find_conversation_by_username(username)

if len(conversations_ids) == 0:
initiate_conversation(username=username, message=message)
else:
# add logic to chose conversation if needed
conversation_id = conversations_ids[0]

# you can send 3 types of messages

# Only text message
pinterest.send_message(conversation_id=conversation_id, pin_id=None, message=message)

# Send pin by id
# pinterest.send_message(conversation_id=conversation_id, pin_id="(pin_id)")

# Message followed by pin
# pinterest.send_message(conversation_id=conversation_id, pin_id="(pin_id)", message="hey")


send_message(username='hknives', message='hi2')
124 changes: 123 additions & 1 deletion py3pin/Pinterest.py
Expand Up @@ -45,6 +45,10 @@
GET_PIN_COMMENTS_RESOURCE = 'https://www.pinterest.com/_ngjs/resource/AggregatedCommentFeedResource/get'
LOAD_PIN_URL_FORMAT = 'https://www.pinterest.com/pin/{}/'
DELETE_COMMENT = 'https://www.pinterest.com/_ngjs/resource/AggregatedCommentResource/delete/'
CONVERSATION_RESOURCE = 'https://www.pinterest.com/resource/ConversationsResource/get/'
CONVERSATION_RESOURCE_CREATE = 'https://www.pinterest.com/resource/ConversationsResource/create/'
LOAD_CONVERSATION = 'https://www.pinterest.com/resource/ConversationMessagesResource/get/'
SEND_MESSAGE = 'https://www.pinterest.com/resource/ConversationMessagesResource/create/'


class Pinterest:
Expand All @@ -59,7 +63,7 @@ def __init__(self, password='', proxies=None, username='', email='', cred_root='

self.http = requests.session()
self.proxies = proxies
self.data_path = os.path.join(cred_root,self.email) + os.sep
self.data_path = os.path.join(cred_root, self.email) + os.sep
if not os.path.isdir(self.data_path):
os.makedirs(self.data_path)
self.registry = Registry('%sregistry.dat' % self.data_path)
Expand Down Expand Up @@ -608,6 +612,124 @@ def board_feed(self, board_url='', board_id='', page_size=250):
pins.append(pin_data)
return pins

def initiate_conversation(self, user_ids=None, message='hi'):
headers = self._load_headers()
options = {
"user_ids": user_ids,
"text": message
}

data_obj = {
'options': options,
'context': {}
}

data = {
'source_url': '/',
'data': json.dumps(data_obj)
}

return requests.post(CONVERSATION_RESOURCE_CREATE, headers=headers, data=data)

def send_message(self, message='', conversation_id='', pin_id=''):
options = {
"conversation_id": conversation_id,
"text": message,
"pin": pin_id
}

data_obj = {
'options': options,
'context': {}
}


data = {
'source_url': '/',
'data': json.dumps(data_obj)
}

headers = self._load_headers()
return requests.post(url=SEND_MESSAGE, headers=headers, data=data)

def _load_headers(self):
cookies = self.registry.get(Registry.Key.COOKIES)
csrftoken = ''
cookie_str = ''
for c in cookies:
if c.name == 'csrftoken':
csrftoken = c.value
cookie_str += c.name + '=' + c.value + '; '
cookie_str = cookie_str.strip()

headers = {
'cookie': cookie_str,
'x-csrftoken': csrftoken,
'user-agent': AGENT_STRING
}

return headers

def load_conversation(self, conversation_id=''):
messages = []

message_batch = self._load_conversation_batch(conversation_id=conversation_id)
while len(message_batch) > 0:
messages += message_batch
message_batch = self._load_conversation_batch(conversation_id=conversation_id)

return messages

def _load_conversation_batch(self, conversation_id='', page_size=25):
next_bookmark = self.bookmark_manager.get_bookmark(primary='conversations', secondary=conversation_id)

if next_bookmark == '-end-':
return []

options = {
"isPrefetch": False,
"page_size": page_size,
"conversation_id": conversation_id,
"bookmarks": [next_bookmark]
}

url = self.req_builder.buildGet(url=LOAD_CONVERSATION, options=options)
response = self.get(url=url).json()

bookmark = response['resource']['options']['bookmarks'][0]
self.bookmark_manager.add_bookmark(primary='conversations', secondary=conversation_id, bookmark=bookmark)

return response['resource_response']['data']

def get_conversations(self):
conversations = []
conv_batch = self._get_conversation_batch()
while len(conv_batch) > 0:
conversations += conv_batch
conv_batch = self._get_conversation_batch()

return conversations

def _get_conversation_batch(self):
next_bookmark = self.bookmark_manager.get_bookmark(primary='conversations')

if next_bookmark == '-end-':
return []

options = {
"isPrefetch": False,
"field_set_key": "default",
"bookmarks": [next_bookmark]
}

url = self.req_builder.buildGet(url=CONVERSATION_RESOURCE, options=options)
response = self.get(url=url).json()

next_bookmark = response['resource']['options']['bookmarks'][0]
self.bookmark_manager.add_bookmark(primary='conversations', bookmark=next_bookmark)

return response['resource_response']['data']


def extract_pins(results):
pins = []
Expand Down
4 changes: 2 additions & 2 deletions py3pin/RequestBuilder.py
Expand Up @@ -7,7 +7,7 @@ class RequestBuilder:
def __init__(self):
pass

def buildPost(self, options, source_url, context={}):
def buildPost(self, options, source_url="/", context={}):
return self.url_encode({
'source_url': source_url,
'data': json.dumps({
Expand All @@ -17,7 +17,7 @@ def buildPost(self, options, source_url, context={}):
'_': '%s' % int(time.time() * 1000)
})

def buildGet(self, url, options, source_url, context={}):
def buildGet(self, url, options, source_url="/", context={}):
data = self.url_encode({
'source_url': source_url,
'data': json.dumps({
Expand Down
2 changes: 1 addition & 1 deletion py3pin/__version__.py
@@ -1 +1 @@
__version__ = '0.2.3'
__version__ = '0.3.0'

0 comments on commit dc61603

Please sign in to comment.