Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support for direct messages #17

Merged
merged 3 commits into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.2.3'
__version__ = '0.3.0'