[object Object]

← back to Dw Vendor Mailer

Keep cc_finish.py (code-exchange+draft); CC API app rejects valid tokens (CC-side entitlement) — deliver via manual paste

e9cab7702ab2acf47e4a60b7d9d2085f48f9c3fb · 2026-09-09 11:56:38 -0700 · Steve Abrams

Files touched

Diff

commit e9cab7702ab2acf47e4a60b7d9d2085f48f9c3fb
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 9 11:56:38 2026 -0700

    Keep cc_finish.py (code-exchange+draft); CC API app rejects valid tokens (CC-side entitlement) — deliver via manual paste
---
 cc_finish.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/cc_finish.py b/cc_finish.py
new file mode 100644
index 0000000..ac858b1
--- /dev/null
+++ b/cc_finish.py
@@ -0,0 +1,55 @@
+import sys, re, json, base64, time, pathlib, urllib.parse, urllib.request, urllib.error
+
+arg = sys.argv[1] if len(sys.argv) > 1 else ""
+# accept a full redirected URL or a bare code
+m = re.search(r'[?&]code=([^&\s]+)', arg)
+code = urllib.parse.unquote(m.group(1)) if m else arg.strip()
+if not code:
+    print("NO CODE provided"); sys.exit(1)
+
+ENVP = pathlib.Path.home()/"Projects/secrets-manager/.env"
+env = ENVP.read_text()
+g = lambda k: (re.search(rf'^{k}=(.*)$', env, re.M).group(1).strip().strip('"').strip("'"))
+CID, CSEC = g('CC_CLIENT_ID'), g('CC_CLIENT_SECRET')
+REDIR = "https://localhost"
+UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36"
+
+def post(url, data, headers, form=False):
+    body = urllib.parse.urlencode(data).encode() if form else json.dumps(data).encode()
+    req = urllib.request.Request(url, data=body, headers=headers, method="POST")
+    try:
+        r = urllib.request.urlopen(req, timeout=45); return r.status, r.read().decode()
+    except urllib.error.HTTPError as e: return e.code, e.read().decode()
+
+basic = base64.b64encode(f"{CID}:{CSEC}".encode()).decode()
+st, body = post("https://authz.constantcontact.com/oauth2/default/v1/token",
+    {"grant_type":"authorization_code","code":code,"redirect_uri":REDIR},
+    {"Authorization":"Basic "+basic,"Content-Type":"application/x-www-form-urlencoded","User-Agent":UA,"Accept":"application/json"}, form=True)
+if st != 200:
+    print("CODE EXCHANGE FAILED", st, body[:400]); sys.exit(2)
+tok = json.loads(body); AT = tok["access_token"]; NRT = tok.get("refresh_token")
+if NRT:
+    ENVP.write_text(re.sub(r'^CC_REFRESH_TOKEN=.*$', f'CC_REFRESH_TOKEN={NRT}', env, flags=re.M))
+    print("new refresh token persisted (…%s)" % NRT[-6:])
+print("access token acquired ✓")
+
+html = pathlib.Path("mailer.html").read_text(encoding="utf-8")
+payload = {"name":"New — The Houses We Represent "+time.strftime("%Y-%m-%d %H:%M"),
+  "email_campaign_activities":[{"format_type":5,"from_name":"Designer Wallcoverings",
+    "from_email":"steve@designerwallcoverings.com","reply_to_email":"info@designerwallcoverings.com",
+    "subject":"New: The Houses We Represent — order any as a $4.25 sample","html_content":html,
+    "physical_address_in_footer":{"address_line1":"15442 Ventura Blvd","city":"Sherman Oaks",
+      "state_code":"CA","postal_code":"91403","country_code":"US","organization_name":"Designer Wallcoverings"}}]}
+st, body = post("https://api.cc.email/v3/emails", payload,
+    {"Authorization":"Bearer "+AT,"Content-Type":"application/json","Accept":"application/json","User-Agent":UA})
+print("CREATE DRAFT status:", st)
+try:
+    j = json.loads(body)
+    if st in (200,201):
+        print("✓ DRAFT CREATED  campaign_id:", j.get("campaign_id"))
+        for a in j.get("campaign_activities", []):
+            print("   activity:", a.get("campaign_activity_id"), a.get("role"))
+    else:
+        print(body[:900])
+except Exception:
+    print(body[:900])

← bbe2946 Outlook-safe swap: DG->3 JPG patterns, O&L Papilio->Quartz J  ·  back to Dw Vendor Mailer  ·  Real hosted logos (re-uploaded to Shopify Files), remove $4. 6387511 →