-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_tricks.py
102 lines (80 loc) · 3.35 KB
/
get_tricks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import base64
import email
import pickle
from datetime import timedelta
from os import getenv
from typing import Dict, List, Tuple
import googleapiclient.discovery
import requests
from dotenv import load_dotenv
from structlog import get_logger
from timeloop import Timeloop
load_dotenv()
webhook = getenv('DISCORD_WEBHOOK')
tl = Timeloop()
log = get_logger()
def get_new_pytricks(service: googleapiclient.discovery.Resource) -> List[Dict]:
results = service.users().messages().list(userId='me', labelIds=['INBOX', 'UNREAD'],
q='from:[email protected] subject:[🐍pytricks]').execute()
messages = results.get('messages', [])
return [service.users().messages().get(userId='me', id=msg['id'], format='raw').execute() for msg in messages]
def extract_message_content(mime_msg: email.message.Message) -> str:
for part in mime_msg.get_payload():
if part.get_content_maintype() == 'text':
return part.get_payload(decode=True).decode()
return ''
def get_content(message: Dict) -> Tuple[str, str]:
msg = base64.urlsafe_b64decode(message['raw'].encode('ASCII'))
mime_msg = email.message_from_bytes(msg)
messageMainType = mime_msg.get_content_maintype()
messageSubject = email.header.decode_header(mime_msg['subject'])[0][0].decode()
if messageMainType == 'multipart':
messageContent = extract_message_content(mime_msg)
elif messageMainType == 'text':
messageContent = mime_msg.get_payload(decode=True).decode()
return messageSubject, messageContent
def mark_as_read(service: googleapiclient.discovery.Resource, message: Dict) -> None:
msgId = message['id']
body = {"removeLabelIds": ["UNREAD"]}
response = service.users().messages().modify(userId='me', id=msgId, body=body).execute()
log.info('Marked as read', response=response)
def send_to_webhook(subject: str, content: str) -> requests.models.Response:
subject = subject.replace('_', '\_').replace('*', '\*')
data = {'content': f'**{subject}**\n```python\n{content.split("------")[0]}```\n'}
if len(data) < 2000:
response = requests.post(webhook, json=data)
else:
parts = split_message(data)
response = requests.post(webhook, json=parts[0])
for part in parts[1:]:
requests.post(webhook, json=part)
return response
def split_message(message: str) -> List[str]:
parts = []
lines = message.split('\n')
part = ''
for line in lines:
if len(part + line) < 2000:
part += line
else:
parts.append(part)
part = line
parts.append(part)
return parts
@tl.job(interval=timedelta(seconds=1800))
def main() -> None:
with open('token.pickle', 'rb') as token:
credentials = pickle.load(token)
service = googleapiclient.discovery.build('gmail', 'v1', credentials=credentials)
messages = get_new_pytricks(service)
for message in messages:
subject, content = get_content(message)
log.info('Found new message', subject=subject)
response = send_to_webhook(subject, content)
if response.status_code == 204:
log.info('Sent to discord', subject=subject)
mark_as_read(service, message)
else:
log.error(f'Error while sending to Discord: {response.status_code} {response.content}')
if __name__ == '__main__':
tl.start(block=True)