Skip to content

Commit 4c70dd8

Browse files
authored
Create SG.py
0 parents  commit 4c70dd8

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

SG.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import json
4+
import sys
5+
import urllib.request
6+
7+
API_URL = "https://api.sendgrid.com/v3/mail/send"
8+
9+
def main():
10+
p = argparse.ArgumentParser(description="Send a plain-text email via SendGrid")
11+
p.add_argument("--api-key", required=True, help="SendGrid API key (SG.xxxxx)")
12+
p.add_argument("--from", dest="from_email", required=True, help="From email")
13+
p.add_argument("--to", required=True, nargs="+", help="To email(s), space-separated")
14+
p.add_argument("--subject", required=True, help="Email subject")
15+
p.add_argument("--text", required=True, help="Plain text body")
16+
p.add_argument("--cc", nargs="*", default=[], help="CC email(s)")
17+
p.add_argument("--bcc", nargs="*", default=[], help="BCC email(s)")
18+
args = p.parse_args()
19+
20+
def add_personalizations(emails, field):
21+
return [{ "email": e } for e in emails] if emails else None
22+
23+
payload = {
24+
"personalizations": [{
25+
"to": add_personalizations(args.to, "to"),
26+
**({"cc": add_personalizations(args.cc, "cc")} if args.cc else {}),
27+
**({"bcc": add_personalizations(args.bcc, "bcc")} if args.bcc else {}),
28+
"subject": args.subject
29+
}],
30+
"from": { "email": args.from_email },
31+
"content": [{
32+
"type": "text/plain",
33+
"value": args.text
34+
}]
35+
}
36+
37+
data = json.dumps(payload).encode("utf-8")
38+
req = urllib.request.Request(API_URL, data=data, method="POST", headers={
39+
"Authorization": f"Bearer {args.api_key}",
40+
"Content-Type": "application/json"
41+
})
42+
43+
try:
44+
with urllib.request.urlopen(req) as resp:
45+
# SendGrid returns 202 Accepted on success with an empty body
46+
if resp.status == 202:
47+
print("Email accepted by SendGrid (202).")
48+
else:
49+
print(f"Unexpected status: {resp.status}")
50+
except urllib.error.HTTPError as e:
51+
body = e.read().decode("utf-8", errors="replace")
52+
print(f"SendGrid error {e.code}:\n{body}", file=sys.stderr)
53+
sys.exit(1)
54+
except Exception as e:
55+
print(f"Error: {e}", file=sys.stderr)
56+
sys.exit(1)
57+
58+
if __name__ == "__main__":
59+
main()

0 commit comments

Comments
 (0)