# Connecting Notion — no keys, ever 🔌

You should **never** edit `.env` or paste API keys to send leads to Notion. This
is how the connect flow works and how to make it fully one-click for everyone.

## What you (and your buyers) actually do

```bash
leadgen connect notion
```

Your browser opens. You authorize once. The token is saved **only on your
computer** at `~/.leadgen/credentials.json` (owner-only `0600` permissions), and
a **Leads** database is created for you automatically. Every later run is silent:

```bash
leadgen run --niche "cafe" --location "Kolkata" --limit 30 --to notion
```

If you forget to connect first, `leadgen run --to notion` **auto-launches the
connect step** for you, then continues the run. Same for the Go and Python
editions — identical behaviour, identical local store.

> Nothing is ever written to `.env`, committed, or sent to any server we run.
> The token lives on your machine and only your machine.

---

## Two modes (picked automatically)

### 1. Paste-once fallback — works immediately, zero setup
If no OAuth app is configured, `leadgen connect notion` opens a small **local**
page (served on `127.0.0.1`) where you paste a Notion **integration token** a
single time. We then auto-create the database and remember it forever — you
never do it again, and you never touch `.env`.

One-time, in Notion: open any page → `•••` → **Connections** → add your
integration so it can see a page to create the database under. Get a token at
[notion.so/my-integrations](https://www.notion.so/my-integrations) → **New
integration** → *Internal* → copy the secret.

### 2. "Sign in with Notion" — true OAuth, fully click-only
For a product you hand to non-technical buyers, set up a Notion **public OAuth
app once** (≈5 minutes, by you, the owner — never by your buyers). After that,
`leadgen connect notion` shows a real **Sign in with Notion** button: buyers
click *Allow* and they're done. No token, no integration, nothing pasted.

#### One-time owner setup
1. Go to [notion.so/my-integrations](https://www.notion.so/my-integrations) →
   **New integration** → set type to **Public**.
2. Add these **Redirect URIs** (both):
   - `http://localhost:53682/callback`  ← the desktop CLI loopback
   - `https://YOUR-MCP-DOMAIN/oauth/notion/callback`  ← only if you also run the
     hosted MCP server (use your tunnel/VPS URL)
3. Copy the **OAuth client ID** and **client secret**.
4. **Bake them in** (this is the key step — credentials live in the binary, like
   Anthropic baked Claude Code's GitHub app id, so end users never set env vars).
   Paste them into BOTH:
   - Go: [`go/internal/oauthapp/oauthapp.go`](go/internal/oauthapp/oauthapp.go) →
     `bakedNotionClientID` / `bakedNotionClientSecret`, then rebuild.
   - Python: [`src/leadgen_maps/oauthapp.py`](src/leadgen_maps/oauthapp.py) →
     `_BAKED_NOTION_CLIENT_ID` / `_BAKED_NOTION_CLIENT_SECRET`.

   (Env vars `LEADGEN_NOTION_OAUTH_CLIENT_ID/SECRET` still work as an override for
   CI. The **MCP server** uses the same values; its redirect is
   `https://YOUR-MCP-DOMAIN/oauth/notion/callback`, derived from
   `LEADGEN_PUBLIC_URL`, so register that URI too.)

That's it. Once baked, both editions and the MCP server are pure one-click OAuth.

---

# Connecting Google Sheets — no keys either 📊

```bash
leadgen connect google
```

Your browser opens, you click **Allow**, and we **auto-create a Google Sheet** in
your Drive and cache the tokens locally (`~/.leadgen/credentials.json`). Then:

```bash
leadgen run --niche "cafe" --location "Kolkata" --limit 30 --to gsheets
```

As with Notion, `leadgen run --to gsheets` auto-launches the connect step the
first time. Works in both the Go and Python editions.

### One-time owner setup (Google OAuth)
Google has no "paste a token" fallback, so the one-time OAuth app is required to
use the keyless flow:

1. In [Google Cloud Console](https://console.cloud.google.com/) → **APIs &
   Services**: enable the **Google Sheets API** and **Google Drive API**.
2. **Credentials** → **Create credentials** → **OAuth client ID** → application
   type **Desktop app**. Copy the **client ID** and **client secret**.
3. On the **OAuth consent screen**, add yourself (and any buyers) as **Test
   users** — or publish the app once you're ready.
4. **Bake them in** (same as Notion — into the binary, not env vars):
   - Go: [`go/internal/oauthapp/oauthapp.go`](go/internal/oauthapp/oauthapp.go) →
     `bakedGoogleClientID` / `bakedGoogleClientSecret`, then rebuild.
   - Python: [`src/leadgen_maps/oauthapp.py`](src/leadgen_maps/oauthapp.py) →
     `_BAKED_GOOGLE_CLIENT_ID` / `_BAKED_GOOGLE_CLIENT_SECRET`.
   (Env vars `LEADGEN_GOOGLE_OAUTH_CLIENT_ID/SECRET` still work as a CI override.)

The loopback redirect (`http://localhost:53682/callback`) needs no registration
for Desktop-app clients — Google allows any loopback port automatically. Scopes
requested are the narrowest that work: `spreadsheets` + `drive.file` (only the
sheets this app creates).

> Legacy path still supported: a service account
> (`GOOGLE_SERVICE_ACCOUNT_JSON` + `GSHEET_ID` in `.env`, Python edition) is used
> automatically if you haven't run `leadgen connect google`.

---

## Disconnect & uninstall

```bash
leadgen disconnect notion     # remove just Notion
leadgen disconnect google     # remove just Google Sheets
leadgen disconnect all        # clear ~/.leadgen/credentials.json entirely
```

Uninstall the tool itself:

```bash
# Python edition
pipx uninstall leadgen-maps          # or: pip uninstall leadgen-maps

# Go edition (one-liners)
curl -fsSL https://raw.githubusercontent.com/subhadeeproy3902/lead-gen/master/go/uninstall.sh | sh      # macOS/Linux
irm  https://raw.githubusercontent.com/subhadeeproy3902/lead-gen/master/go/uninstall.ps1 | iex          # Windows
```

The uninstallers also remove `~/.leadgen` (your saved connections) unless you set
`LEADGEN_KEEP_CREDS=1`.

---

## Where credentials live (security)

| Surface | Where the token is stored | Lifetime |
|---|---|---|
| CLI (Go + Python) | `~/.leadgen/credentials.json`, `0600`, local only | until you re-connect |
| MCP server | in-memory, scoped to your `connect_token` session | until the server restarts |

- The token **never** appears in chat, logs, or the repo.
- The OAuth `client_secret` is the only shared value; in the "embed in app"
  model you chose, it ships with the app and is used only to exchange the
  authorization code for a token. Keep your private repo private.
- To disconnect: delete `~/.leadgen/credentials.json` (or re-run
  `leadgen connect notion` to relink a different workspace).

---

## Still want to use a raw token / .env? (advanced)

`NOTION_TOKEN` and `NOTION_DATABASE_ID` in `.env` are still honoured as a
fallback, so existing setups keep working. The local connect store takes
priority when present.
