113 lines
3.0 KiB
Markdown
113 lines
3.0 KiB
Markdown
# Gmail IMAP/SMTP Full Code Templates
|
|
|
|
## IMAP — Full Fetch + Parse
|
|
|
|
```python
|
|
import imaplib, email
|
|
from email.header import decode_header
|
|
from email.utils import parsedate_to_datetime
|
|
|
|
def fetch_emails(user, app_pass, folder='INBOX', limit=10, search_criteria='ALL'):
|
|
"""Fetch last N emails from Gmail IMAP."""
|
|
m = imaplib.IMAP4_SSL('imap.gmail.com', 993)
|
|
m.login(user, app_pass)
|
|
m.select(folder)
|
|
_, data = m.search(None, search_criteria)
|
|
ids = data[0].split()[-limit:]
|
|
|
|
results = []
|
|
for mid in reversed(ids):
|
|
_, msg_data = m.fetch(mid, '(RFC822)')
|
|
raw = email.message_from_bytes(msg_data[0][1])
|
|
|
|
# Subject decode
|
|
subj_parts = decode_header(raw['Subject'])
|
|
subject = ''
|
|
for part, charset in subj_parts:
|
|
if isinstance(part, bytes):
|
|
subject += part.decode(charset or 'utf-8', errors='replace')
|
|
else:
|
|
subject += str(part)
|
|
|
|
# Body (text/plain first, fallback text/html)
|
|
body = ''
|
|
if raw.is_multipart():
|
|
for part in raw.walk():
|
|
ct = part.get_content_type()
|
|
if ct == 'text/plain':
|
|
body = part.get_payload(decode=True).decode('utf-8', errors='replace')
|
|
break
|
|
else:
|
|
body = raw.get_payload(decode=True).decode('utf-8', errors='replace')
|
|
|
|
results.append({
|
|
'id': int(mid),
|
|
'from': raw['From'],
|
|
'to': raw['To'],
|
|
'subject': subject,
|
|
'date': raw['Date'],
|
|
'body': body[:500],
|
|
})
|
|
|
|
m.logout()
|
|
return results
|
|
```
|
|
|
|
## SMTP — Full Send
|
|
|
|
```python
|
|
import smtplib
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
|
|
def send_email(user, app_pass, to, subject, body, html=False):
|
|
"""Send email via Gmail SMTP."""
|
|
msg = MIMEMultipart() if html else MIMEText(body)
|
|
if html:
|
|
msg.attach(MIMEText(body, 'html'))
|
|
else:
|
|
msg = MIMEText(body)
|
|
|
|
msg['Subject'] = subject
|
|
msg['From'] = user
|
|
msg['To'] = to
|
|
|
|
with smtplib.SMTP_SSL('smtp.gmail.com', 465, timeout=10) as s:
|
|
s.login(user, app_pass)
|
|
s.send_message(msg)
|
|
```
|
|
|
|
## Sub-address filter pattern
|
|
|
|
```python
|
|
# Fetch only emails sent to specific sub-address
|
|
m.search(None, 'TO', '[REDACTED-NAME]+bot@gmail.com')
|
|
```
|
|
|
|
## Gmail IMAP folder list
|
|
|
|
```python
|
|
m = imaplib.IMAP4_SSL('imap.gmail.com')
|
|
m.login(user, app_pass)
|
|
_, folders = m.list()
|
|
for f in folders:
|
|
print(f.decode())
|
|
# Common: INBOX, [Gmail]/Sent Mail, [Gmail]/Drafts, [Gmail]/Spam, [Gmail]/Trash
|
|
```
|
|
|
|
## Connection test (quick)
|
|
|
|
```python
|
|
import socket
|
|
|
|
def test_gmail_imap():
|
|
"""Quick connectivity test — no login."""
|
|
try:
|
|
ip = socket.getaddrinfo('imap.gmail.com', 993, socket.AF_INET, socket.SOCK_STREAM)
|
|
print(f"DNS OK: {ip[0][4]}")
|
|
return True
|
|
except Exception as e:
|
|
print(f"DNS FAIL: {e}")
|
|
return False
|
|
```
|