How to Detect and Unsubscribe from Newsletters with OpenClaw in Paradime

Feb 26, 2026

Table of Contents

How to Auto-Unsubscribe From Newsletters Using Paradime, OpenClaw, and the Gmail API

Stop drowning in newsletter noise. If you're an analytics engineer — or really, anyone with a Gmail inbox — you know the drill: hundreds of marketing emails pile up, you never read them, and the "unsubscribe" links hide behind three clicks and a CAPTCHA. What if you could identify every newsletter you haven't opened in months, extract the unsubscribe links, and review them in one place — automatically, every Sunday?

That's exactly what we're building in this guide. We'll wire up Paradime's Bolt scheduler with OpenClaw's agent capabilities and the Gmail API to create a hands-off newsletter cleanup pipeline. No local config headaches, no cron jobs running on your laptop at 3 AM. Just a secure, UI-driven setup that runs in production.

Let's get into it.

What Is Paradime?

Paradime is an all-in-one AI platform that replaces dbt Cloud™. It gives analytics teams a single workspace to code, ship, fix, and scale data pipelines — whether for analytics or AI workloads. Think of it as the operating system for your entire dbt™ workflow.

The features that matter for this project:

  • Code IDE — An AI-native IDE that cuts dbt™ and Python development time by 83%+. Full context awareness across data, docs, and lineage.

  • Bolt — Paradime's scheduler and orchestration engine. It runs dbt™ commands and Python scripts on a cron schedule, with a configure-and-forget UI. Deploy jobs 50% faster than legacy tools.

  • Environment Variables — Managed through a secure UI. Admin-controlled, with per-schedule overrides. No .env files floating around in Slack DMs.

Bolt is the star here. It supports cron-based triggers, on-merge triggers, API triggers, and even chained schedule triggers. And critically for us, it can run Python scripts alongside dbt™ commands — meaning our unsubscribe logic lives right next to our data pipeline.

Why not just use dbt Cloud™? Paradime's Bolt supports Python script execution natively as a first-class command type, alongside dbt™ commands, Elementary, Lightdash, Tableau refreshes, and more. That's not something you get out of the box elsewhere.

What Is OpenClaw?

OpenClaw is an open-source, local-first personal AI agent that runs on your own hardware. It connects to messaging platforms you already use (WhatsApp, Telegram, Slack, Discord, etc.) and executes real-world tasks: reading email, browsing the web, running shell commands, and managing files — all with persistent memory across sessions.

Here's what makes OpenClaw relevant to our newsletter problem:

  • Email management — Categorize messages, unsubscribe from spam, draft replies, summarize urgent items.

  • Skills system — Modular plugins (100+) that extend what the agent can do. You can download skills from ClawHub or let the agent write its own.

  • Model-agnostic — Works with Anthropic, OpenAI, Gemini, DeepSeek, or local models via Ollama.

  • Gateway architecture — An always-on control plane on your machine that routes requests, manages sessions, and handles authentication.

Install is straightforward:

The onboarding wizard walks you through model selection, channel pairing, and permissions. Configuration lives at ~/.openclaw/openclaw.json, and your workspace (skills, prompts, memories) lives at ~/.openclaw/workspace.

Setup: OpenClaw + Gmail API

Before we write the unsubscribe script, we need OpenClaw connected to Gmail with proper OAuth credentials. No app passwords. No hacks. OAuth 2.0 with scoped permissions.

Figure 1: OAuth flow connecting OpenClaw to the Gmail API.

Step-by-Step

1. Create a Google Cloud Project

Head to Google Cloud Console. Create a new project — name it something like Openclaw Gmail Integration.

2. Enable the Gmail API

Navigate to APIs & Services → Library, search for "Gmail API", and click Enable.

3. Configure the OAuth Consent Screen

Go to APIs & Services → OAuth consent screen. Select External user type. Fill in your app name (Openclaw Agent), support email, and developer contact. Save and continue.

4. Add OAuth Scopes

Add these scopes — and nothing more:

Scope

Purpose

https://www.googleapis.com/auth/gmail.modify

Read, label, and delete emails

https://www.googleapis.com/auth/gmail.send

Send emails (optional)

Principle of least privilege. Don't grant full account access when you only need to read and label messages.

5. Create OAuth Credentials

Go to APIs & Services → Credentials → Create Credentials → OAuth client ID. Select Desktop app, name it Openclaw Desktop Client, and download the credentials file.

6. Save Credentials for OpenClaw

7. Configure the OpenClaw Google Adapter

Create ~/.openclaw/adapters/google/config.json:

8. Authorize OpenClaw

Then, from your messaging surface, send:

This opens a browser, prompts Google sign-in, and stores OAuth tokens securely.

9. Verify the Connection

You should see:

The Script: Identify, Extract, and Log Newsletter Unsubscribe Candidates

Now for the core logic. We'll write a Python script that:

  1. Identifies newsletter and marketing emails you haven't engaged with

  2. Extracts unsubscribe links from List-Unsubscribe headers and email bodies

  3. Logs candidates to a review file — it does not auto-click unsubscribe links (that's your call)

This is the safe, opinionated approach. Automated unsubscribing without human review is how you accidentally lose access to a service you actually care about.

Figure 2: Newsletter cleanup pipeline — from Gmail fetch to human review.

The Python Script

Create a file called unsubscribe_scanner.py in your dbt™ project root:

How It Works

Step

What happens

Authenticate

Reads GOOGLE_CREDENTIALS_JSON from the environment (set in Paradime Bolt), exchanges for OAuth tokens

Query Gmail

Searches category:promotions and category:updates for unread emails older than 90 days

Parse headers

Checks List-Unsubscribe header first (RFC 2369 compliant), falls back to body link scanning

Deduplicate

One entry per sender — you don't need 47 rows for the same SaaS company

Output

Writes unsubscribe_candidates.csv with sender, subject, link, source, and category

The script does not click any unsubscribe links. It logs them for your review. This is deliberate. Automated unsubscribing without oversight is how you lose access to things like password reset emails from services that share a domain with their marketing arm.

Environment Variables: GOOGLE_CREDENTIALS_JSON and OPENCLAW_API_KEY

Both secrets need to be configured securely — and neither belongs in your codebase.

In Paradime (for Bolt Schedules)

  1. Navigate to Settings → Workspaces → Environment Variables

  2. In the Bolt Schedules section, click Add New

  3. Add the following:

Key

Value

Purpose

GOOGLE_CREDENTIALS_JSON

Your OAuth credentials JSON (the full contents of google-credentials.json)

Gmail API authentication

OPENCLAW_API_KEY

Your OpenClaw API key or model provider key

OpenClaw agent authentication

  1. Click the Save icon

Admin access required. Only admins can add, edit, or remove Bolt environment variables. This is a feature, not a limitation — it prevents credential sprawl.

You can also bulk upload variables via CSV if you're setting up multiple schedules:

Per-schedule overrides are supported too — if you want one schedule to use a different Google account, override GOOGLE_CREDENTIALS_JSON at the schedule level without touching the global default.

In OpenClaw (for Local Development)

OpenClaw reads environment variables from multiple sources with a never-override rule:

Figure 3: OpenClaw environment variable precedence — process env always wins.

For local development, add your keys to ~/.openclaw/.env:

Or inline in ~/.openclaw/openclaw.json:

The ${VAR} syntax resolves from the process environment at activation time — useful when you want config to reference secrets without hardcoding them.

Bolt Schedule: Cron Weekly Sunday

Here's where the setup becomes truly hands-off. We configure a Bolt schedule to run our unsubscribe scanner every Sunday morning.

Option 1: Schedules as Code (YAML)

Add this to your paradime_schedules.yml file in your dbt™ project root:

The cron expression 0 8 * * 0 means: every Sunday at 8:00 AM. The 0 at the end is Sunday in standard cron syntax (0 = Sunday, 6 = Saturday). Validate at crontab.guru.

Option 2: UI-Based Setup

If you prefer clicks over YAML:

  1. Go to Bolt in Paradime

  2. Click Create Schedule

  3. Set Trigger Type to Scheduled Run

  4. Enter cron expression: 0 8 * * 0

  5. Select timezone (e.g., America/New_York)

  6. Add commands:

  7. Configure notifications for failed events

  8. Click Deploy

Figure 4: Weekly Bolt schedule execution flow — Python scan then optional dbt™ run.

Tip: Bolt auto-refreshes schedules from paradime_schedules.yml every 10 minutes, or you can manually trigger a parse via Bolt → Parse Schedules.

Monitoring and Debugging

Once your schedule is running, you need visibility into what's happening — and what's failing. Paradime's Bolt gives you three levels of logs:

Log Level

Use Case

Detail Level

Summary Logs

Quick health check — DinoAI-generated overview with warnings and suggested fixes

Low

Console Logs

Detailed chronological record of all operations

Medium

Debug Logs

System-level operations, dbt™ internals, performance tuning

High

Accessing Logs

  1. Navigate to Bolt in Paradime

  2. Click on your weekly_newsletter_cleanup schedule

  3. Open the Run History section

  4. Click on a specific run

  5. Scroll to Logs and Artifacts

The DinoAI-powered Summary Logs are genuinely useful here — if the Gmail API throws a token refresh error at 3 AM on Sunday, the summary will tell you what went wrong and suggest a fix before you've had your coffee.

Artifacts

Each run produces artifacts you can download:

  • Run SQL files — if your schedule includes dbt™ commands

  • Compiled SQL — useful for debugging model logic

  • Manifest files — for lineage and dependency tracking

  • CSV output — your unsubscribe_candidates.csv file

OpenClaw Monitoring

On the OpenClaw side, monitor your agent's Gmail operations with:

This checks Gateway status, channel connections, and active sessions. For deeper debugging:

The --verbose flag outputs detailed request/response logs, including Gmail API calls and token refresh events.

Troubleshooting Common Issues

1. GOOGLE_CREDENTIALS_JSON Not Found

Symptom: EnvironmentError: GOOGLE_CREDENTIALS_JSON environment variable is not set

Fix: Verify the variable is set in Paradime Settings → Workspaces → Environment Variables → Bolt Schedules. Only Admin roles can manage these. Also check: did you set it in the Code IDE section instead of Bolt Schedules? They're separate.

2. Gmail OAuth Token Expired

Symptom: google.auth.exceptions.RefreshError: Token has been revoked

Fix: OAuth refresh tokens can expire if:

  • You revoked access in Google Account Security

  • The Google Cloud project is in "Testing" mode (tokens expire after 7 days)

  • The app hasn't been used in 6 months

Solution: Move your OAuth consent screen to "Production" status (even for internal use) or re-authorize with /connect google in OpenClaw.

3. Missing Production Warehouse Connection (PARA-1000)

Symptom: PARA-1000: Missing production warehouse connection

Fix: Your Bolt schedule needs a production warehouse connection, even for Python-only jobs. Add one in Account Settings → Connections. See the Paradime Error List for details.

4. OpenClaw Gateway Not Running

Symptom: OpenClaw commands hang or return connection errors.

Fix: Verify the gateway is running:

If it's down, restart:

On macOS, ensure the daemon is installed:

5. Rate Limiting from Gmail API

Symptom: HttpError 429: Rate Limit Exceeded

Fix: The Gmail API has a quota of 250 quota units per user per second. Our script fetches up to 200 messages per category — if you have a massive inbox, add a sleep between API calls:

6. Schedule Not Triggering

Symptom: Your cron job never runs.

Fix: Check these in order:

  1. Is the schedule suspended: true in your YAML? Set it to false.

  2. Is the cron expression valid? Test at crontab.guru.

  3. Is the YAML file on your default branch (main/master)? Bolt reads from the default branch only.

  4. Try Bolt → Parse Schedules to force a refresh.

Figure 5: Troubleshooting decision tree for non-triggering Bolt schedules.

Wrapping Up

Here's what we built:

Component

Role

Paradime Bolt

Schedules the Python script on a weekly Sunday cron. Manages environment variables securely. Provides monitoring, logs, and notifications.

OpenClaw

Connects to Gmail via OAuth. Provides agent capabilities for email management. Handles credential storage and token refresh.

Gmail API

Reads promotional/marketing emails. Exposes List-Unsubscribe headers. Returns message metadata for filtering.

Python Script

Identifies newsletter candidates (unread, 90+ days, promotional category). Extracts unsubscribe links. Logs to CSV for human review.

The beauty of this approach is that nothing runs on your laptop. The credentials live in Paradime's secure environment variable store. The schedule runs in Bolt's managed infrastructure. The Gmail API tokens refresh automatically. And you get a CSV every Sunday morning with a clean list of newsletters you can unsubscribe from — or not.

No local config pain. No cron jobs dying silently on a MacBook that went to sleep. Just a production-grade pipeline that keeps your inbox clean.

Next Steps

  • Add OpenClaw auto-review — Have the agent scan the CSV and flag high-confidence unsubscribe candidates (e.g., senders you haven't opened in 6+ months)

  • Load to your warehouse — Use a dbt™ model to track unsubscribe trends over time

  • Add a Slack notification — Post the candidate count to your team channel every Sunday

  • Extend to other categories — Add category:social or category:forums to cast a wider net

The whole setup takes about 30 minutes. Most of that is the Google Cloud OAuth dance. Once it's running, you'll wonder why you ever manually clicked "unsubscribe" on 200 emails on a Saturday afternoon.

Your inbox deserves better. So does your time.

Further reading:

Interested to Learn More?
Try Out the Free 14-Days Trial

Stop Managing Pipelines. Start Shipping Them.

Join the teams that replaced manual dbt™ workflows with agentic AI. Free to start, no credit card required.

Stop Managing Pipelines. Start Shipping Them.

Join the teams that replaced manual dbt™ workflows with agentic AI. Free to start, no credit card required.

Stop Managing Pipelines. Start Shipping Them.

Join the teams that replaced manual dbt™ workflows with agentic AI. Free to start, no credit card required.

Copyright © 2026 Paradime Labs, Inc. Made with ❤️ in San Francisco ・ London

*dbt® and dbt Core® are federally registered trademarks of dbt Labs, Inc. in the United States and various jurisdictions around the world. Paradime is not a partner of dbt Labs. All rights therein are reserved to dbt Labs. Paradime is not a product or service of or endorsed by dbt Labs, Inc.

Copyright © 2026 Paradime Labs, Inc. Made with ❤️ in San Francisco ・ London

*dbt® and dbt Core® are federally registered trademarks of dbt Labs, Inc. in the United States and various jurisdictions around the world. Paradime is not a partner of dbt Labs. All rights therein are reserved to dbt Labs. Paradime is not a product or service of or endorsed by dbt Labs, Inc.

Copyright © 2026 Paradime Labs, Inc. Made with ❤️ in San Francisco ・ London

*dbt® and dbt Core® are federally registered trademarks of dbt Labs, Inc. in the United States and various jurisdictions around the world. Paradime is not a partner of dbt Labs. All rights therein are reserved to dbt Labs. Paradime is not a product or service of or endorsed by dbt Labs, Inc.