Skip to content

Commit

Permalink
Label update
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyephron committed Aug 14, 2020
1 parent 6a41bdf commit ff6fc33
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 38 deletions.
65 changes: 57 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,32 @@

A simple Gmail API client in Python for applications.

Current Supported Behavior:
* Sending html messages
* Sending messages with attachments
* Sending messages with your Gmail account signature
* Retrieving messages with the full suite of Gmail's search capabilities
* Retrieving messages with attachments, and downloading attachments
* Modifying message labels (includes marking as read/unread, important/not
Currently Supported Behavior:
- Sending html messages
- Sending messages with attachments
- Sending messages with your Gmail account signature
- Retrieving messages with the full suite of Gmail's search capabilities
- Retrieving messages with attachments, and downloading attachments
- Modifying message labels (includes marking as read/unread, important/not
important, starred/unstarred, trash/untrash, inbox/archive)

## Table of Contents

- [Getting Started](#getting-started)
- [Installation](#installation)
- [Usage](#usage)
- [Send a simple message](#send-a-simple-message)
- [Send a message with attachments, cc, bcc fields](#send-a-message-with-attachments-cc-bcc-fields)
- [Retrieving messages](#retrieving-messages)
- [Marking messages](#marking-messages)
- [Changing message labels](#changing-message-labels)
- [Downloading attachments](#downloading-attachments)
- [Retrieving messages with queries](#retrieving-messages-advanced-with-queries)
- [Retrieving messages with more advanced queries](#retrieving-messages-more-advanced-with-more-queries)
- [Feedback](#feedback)

## Getting Started

The only setup required is to download an OAuth 2.0 Client ID file from Google
that will authorize your application.

Expand Down Expand Up @@ -57,7 +73,9 @@ pip3 install simplegmail
```

## Usage

### Send a simple message:

```python
from simplegmail import Gmail

Expand All @@ -75,6 +93,7 @@ message = gmail.send_message(**params) # equivalent to send_message(to="you@you
```

### Send a message with attachments, cc, bcc fields:

```python
from simplegmail import Gmail

Expand All @@ -97,6 +116,7 @@ message = gmail.send_message(**params) # equivalent to send_message(to="you@you
It couldn't be easier!

### Retrieving messages:

```python
from simplegmail import Gmail

Expand All @@ -122,6 +142,7 @@ for message in messages:
```

### Marking messages:

```python
from simplegmail import Gmail

Expand All @@ -144,7 +165,31 @@ message_to_trash.trash()
# ...and many more functions can be found in message.py!
```

### Changing message labels:

```python
from simplegmail import Gmail

gmail = Gmail()

# Get the label objects for your account. Each label has a specific ID that
# you need, not just the name!
labels = gmail.list_labels()

messages = gmail.get_unread_inbox()

# We can add/remove a label
message = messages[0]
message.add_label(label[5])

# We can "move" a message from one label to another
message.modify_labels(to_add=labels[10], to_remove=message.label_ids[-1])

# ...check out the code in message.py for more!
```

### Downloading attachments:

```python
from simplegmail import Gmail

Expand All @@ -162,6 +207,7 @@ if message.attachments:
```

### Retrieving messages (advanced, with queries!):

```python
from simplegmail import Gmail
from simplegmail.query import construct_query
Expand All @@ -187,6 +233,7 @@ messages = gmail.get_messages(query=construct_query(query_params))
```

### Retrieving messages (more advanced, with more queries!):

```python
from simplegmail import Gmail
from simplegmail.query import construct_query
Expand Down Expand Up @@ -221,4 +268,6 @@ messages = gmail.get_messages(query=construct_query(query_params_1, query_params
For more on what you can do with queries, read the docstring for `construct_query()` in `query.py`.

## Feedback
If there is functionality you'd like to see added, or any bugs in this project, please let me know by posting an issue or submitting a pull request!

If there is functionality you'd like to see added, or any bugs in this project,
please let me know by posting an issue or submitting a pull request!
79 changes: 69 additions & 10 deletions simplegmail/gmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from oauth2client.clientsecrets import InvalidClientSecretsError

from simplegmail import labels
from simplegmail.labels import Label
from simplegmail.message import Message
from simplegmail.attachment import Attachment

Expand Down Expand Up @@ -125,7 +126,7 @@ def send_message(self, sender, to, subject='', msg_html=None,
print(f"An error has occurred: {error}")
return "Error"

def get_unread_inbox(self, user_id='me', label_ids=[], query='',
def get_unread_inbox(self, user_id='me', label_ids=None, query='',
attachments='reference'):
"""
Gets unread messages from your inbox.
Expand All @@ -146,10 +147,13 @@ def get_unread_inbox(self, user_id='me', label_ids=[], query='',
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.INBOX)
return self.get_unread_messages(user_id, label_ids, query)

def get_starred_messages(self, user_id='me', label_ids=[], query='',
def get_starred_messages(self, user_id='me', label_ids=None, query='',
attachments='reference', include_spam_trash=False):
"""
Gets starred messages from your account.
Expand All @@ -172,11 +176,14 @@ def get_starred_messages(self, user_id='me', label_ids=[], query='',
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.STARRED)
return self.get_messages(user_id, label_ids, query, attachments,
include_spam_trash)

def get_important_messages(self, user_id='me', label_ids=[], query='',
def get_important_messages(self, user_id='me', label_ids=None, query='',
attachments='reference',
include_spam_trash=False):
"""
Expand All @@ -199,12 +206,15 @@ def get_important_messages(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.IMPORTANT)
return self.get_messages(user_id, label_ids, query, attachments,
include_spam_trash)

def get_unread_messages(self, user_id='me', label_ids=[], query='',
def get_unread_messages(self, user_id='me', label_ids=None, query='',
attachments='reference', include_spam_trash=False):
"""
Gets unread messages from your account.
Expand All @@ -226,12 +236,15 @@ def get_unread_messages(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.UNREAD)
return self.get_messages(user_id, label_ids, query, attachments,
include_spam_trash)

def get_drafts(self, user_id='me', label_ids=[], query='',
def get_drafts(self, user_id='me', label_ids=None, query='',
attachments='reference', include_spam_trash=False):
"""
Gets drafts saved in your account.
Expand All @@ -253,12 +266,15 @@ def get_drafts(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.DRAFTS)
return self.get_messages(user_id, label_ids, query, attachments,
include_spam_trash)

def get_sent_messages(self, user_id='me', label_ids=[], query='',
def get_sent_messages(self, user_id='me', label_ids=None, query='',
attachments='reference', include_spam_trash=False):
"""
Gets sent messages from your account.
Expand All @@ -280,12 +296,15 @@ def get_sent_messages(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.SENT)
return self.get_messages(user_id, label_ids, query, attachments,
include_spam_trash)

def get_trash_messages(self, user_id='me', label_ids=[], query='',
def get_trash_messages(self, user_id='me', label_ids=None, query='',
attachments='reference'):

"""
Expand All @@ -306,11 +325,14 @@ def get_trash_messages(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.TRASH)
return self.get_messages(user_id, label_ids, query, attachments, True)

def get_spam_messages(self, user_id='me', label_ids=[], query='',
def get_spam_messages(self, user_id='me', label_ids=None, query='',
attachments='reference'):
"""
Gets messages marked as spam from your account.
Expand All @@ -330,11 +352,14 @@ def get_spam_messages(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids.append(labels.SPAM)
return self.get_messages(user_id, label_ids, query, attachments, True)

def get_messages(self, user_id='me', label_ids=[], query='',
def get_messages(self, user_id='me', label_ids=None, query='',
attachments='reference', include_spam_trash=False):
"""
Gets messages from your account.
Expand All @@ -356,6 +381,11 @@ def get_messages(self, user_id='me', label_ids=[], query='',
List[Message]: a list of message objects.
"""

if label_ids is None:
label_ids = []

label_ids = [lbl.id for lbl in label_ids]

try:
response = self.service.users().messages().list(
Expand Down Expand Up @@ -384,6 +414,34 @@ def get_messages(self, user_id='me', label_ids=[], query='',

except HttpError as error:
print(f"An error occurred: {error}")

def list_labels(self, user_id='me'):
"""
Retrieves all labels for the specified user.
These Label objects are to be used with other functions like
modify_labels().
Args:
user_id (str): the account the messages belong to. Default 'me'
refers to the main account.
Returns:
List[Label]: the list of Label objects.
"""

try:
res = self.service.users().labels().list(
userId=user_id
).execute()

except HttpError as error:
print(f'An error occurred: {error}')

else:
labels = [Label(name=x['name'], id=x['id']) for x in res['labels']]
return labels

def _get_messages_from_refs(self, user_id, message_refs,
attachments='reference'):
Expand Down Expand Up @@ -439,7 +497,8 @@ def _build_message_from_ref(self, user_id, message_ref,
else:
msg_id = message['id']
thread_id = message['threadId']
label_ids = message['labelIds']
user_labels = {x.id: x for x in self.list_labels(user_id=user_id)}
label_ids = [user_labels[x] for x in message['labelIds']]
snippet = html.unescape(message['snippet'])

payload = message['payload']
Expand Down
36 changes: 23 additions & 13 deletions simplegmail/labels.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
"""Gmail reserved system labels."""

INBOX = 'INBOX'
SPAM = 'SPAM'
TRASH = 'TRASH'
UNREAD = 'UNREAD'
STARRED = 'STARRED'
SENT = 'SENT'
IMPORTANT = 'IMPORTANT'
DRAFT = 'DRAFT'
PERSONAL = 'CATEGORY_PERSONAL'
SOCIAL = 'CATEGORY_SOCIAL'
PROMOTIONS = 'CATEGORY_PROMOTIONS'
UPDATES = 'CATEGORY_UPDATES'
FORUMS = 'CATEGORY_FORUMS'
from dataclasses import dataclass


@dataclass
class Label:
name: str
id: str


INBOX = Label('INBOX', 'INBOX')
SPAM = Label('SPAM', 'SPAM')
TRASH = Label('TRASH', 'TRASH')
UNREAD = Label('UNREAD', 'UNREAD')
STARRED = Label('STARRED', 'STARRED')
SENT = Label('SENT', 'SENT')
IMPORTANT = Label('IMPORTANT', 'IMPORTANT')
DRAFT = Label('DRAFT', 'DRAFT')
PERSONAL = Label('CATEGORY_PERSONAL', 'CATEGORY_PERSONAL')
SOCIAL = Label('CATEGORY_SOCIAL', 'CATEGORY_SOCIAL')
PROMOTIONS = Label('CATEGORY_PROMOTIONS', 'CATEGORY_PROMOTIONS')
UPDATES = Label('CATEGORY_UPDATES', 'CATEGORY_UPDATES')
FORUMS = Label('CATEGORY_FORUMS', 'CATEGORY_FORUMS')

Loading

0 comments on commit ff6fc33

Please sign in to comment.