Repository navigation
Expand file tree
/
Copy pathadd_subscribers.py
More file actions
executable file
·45 lines (34 loc) · 1.63 KB
/
Copy pathadd_subscribers.py
File metadata and controls
executable file
·45 lines (34 loc) · 1.63 KB
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
#!/usr/bin/env python3
"""Add emails from a file to your list as free subscribers, one call per email.
python add_subscribers.py emails.txt
python add_subscribers.py contacts.csv --column email --yes
Each address gets Substack's welcome email. Add only people who asked to subscribe.
"""
import argparse
import csv
import sys
from pathlib import Path
from substack_api_mcp.core.errors import ToolError
from substack_api_mcp.scripting import call, run
def read_emails(path: Path, column: str | None) -> list[str]:
if column:
with path.open(newline="", encoding="utf-8") as fh:
return [row[column].strip() for row in csv.DictReader(fh) if row.get(column, "").strip()]
return [line.strip() for line in path.read_text(encoding="utf-8").splitlines() if "@" in line]
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("file", help="Text file with one email per line, or a CSV with --column")
parser.add_argument("--column", help="CSV column that holds the email")
parser.add_argument("--yes", action="store_true", help="Do not ask before adding")
args = parser.parse_args()
emails = list(dict.fromkeys(read_emails(Path(args.file), args.column)))
if not args.yes and input(f"Add {len(emails)} emails as free subscribers? [y/N] ").lower() != "y":
sys.exit("Nothing added.")
for email in emails:
try:
call("add_subscriber", {"email": email})
print(f"added {email}")
except ToolError as err:
print(f"skipped {email}: {err}", file=sys.stderr)
if __name__ == "__main__":
run(main)