> ## Documentation Index
> Fetch the complete documentation index at: https://labs.prompthon.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Gmail OAuth Setup

> Create Google Cloud OAuth credentials for local Gmail-backed agent starters.

<div className="not-prose my-4 rounded-md border border-gray-200 bg-gray-50 p-2 text-sm dark:border-gray-800 dark:bg-gray-900/40">
  <div className="mb-2 px-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Need help?</div>

  <div className="flex flex-wrap gap-2">
    <a className="inline-flex items-center gap-2 rounded-md border border-gray-200 bg-white px-3 py-1.5 font-medium text-gray-700 no-underline shadow-sm hover:border-gray-300 hover:bg-gray-50 dark:border-gray-800 dark:bg-gray-950/60 dark:text-gray-200 dark:hover:bg-gray-900" href="https://discord.gg/sDE2HhGTg4" target="_blank" rel="noreferrer">
      <Icon icon="discord" iconType="brands" size={14} />

      <span>Ask in Discord</span>
    </a>

    <a className="inline-flex items-center gap-2 rounded-md border border-gray-200 bg-white px-3 py-1.5 font-medium text-gray-700 no-underline shadow-sm hover:border-gray-300 hover:bg-gray-50 dark:border-gray-800 dark:bg-gray-950/60 dark:text-gray-200 dark:hover:bg-gray-900" href="https://github.com/Prompthon-IO/agent-systems-handbook/issues/new/choose" target="_blank" rel="noreferrer">
      <Icon icon="github" iconType="brands" size={14} />

      <span>Open a GitHub issue</span>
    </a>

    <a className="inline-flex items-center gap-2 rounded-md border border-gray-200 bg-white px-3 py-1.5 font-medium text-gray-700 no-underline shadow-sm hover:border-gray-300 hover:bg-gray-50 dark:border-gray-800 dark:bg-gray-950/60 dark:text-gray-200 dark:hover:bg-gray-900" href="https://github.com/Prompthon-IO/agent-systems-handbook/blob/main/SUPPORT.md" target="_blank" rel="noreferrer">
      <Icon icon="life-ring" size={14} />

      <span>Support guide</span>
    </a>
  </div>
</div>

Use this setup when a local agent starter needs to call the Gmail API directly
from your machine. For the Customer Email Assist starter, this is the path that
lets the dashboard send an approved reply automatically after the undo
countdown. If you only use the Codex Gmail connector, you can skip this setup.

<Warning>
  Do not publish client secrets, refresh tokens, `.env.local` files, or
  screenshots that expose OAuth credentials.
</Warning>

## What You Will Create

| Value                                  | Where it comes from               | Used for                                                            |
| -------------------------------------- | --------------------------------- | ------------------------------------------------------------------- |
| `GOOGLE_CLIENT_ID`                     | Google Cloud OAuth client         | Identifies your local app to Google.                                |
| `GOOGLE_CLIENT_SECRET`                 | Google Cloud OAuth client         | Authenticates the OAuth client.                                     |
| Gmail refresh token                    | Dashboard `Connect Gmail` flow    | Stored locally by the app after Google redirects back to localhost. |
| `CUSTOMER_EMAIL_ASSIST_OPERATOR_EMAIL` | Gmail profile or optional env var | Helps detect human outbound replies and avoid duplicate sends.      |
| `CUSTOMER_EMAIL_ASSIST_GMAIL_LABEL`    | Gmail label ID such as `INBOX`    | Controls which mailbox label the local sync reads.                  |

`GOOGLE_REFRESH_TOKEN`, `CUSTOMER_EMAIL_ASSIST_DB_PATH`, and
`CUSTOMER_EMAIL_ASSIST_POLICY_PATH` are optional. The dashboard stores the
refresh token locally, and the starter has defaults for the DB and policy paths.

## Step 1: Open Or Create A Google Cloud Project

1. Open [Google Cloud Console](https://console.cloud.google.com/).
2. Sign in with the Google account that owns the Gmail mailbox.
3. In the top bar, click the project selector.
4. Click **New Project**.
5. Name it something explicit, such as `Customer Email Assist Local`.
6. Click **Create**.
7. Use the project selector again and select the new project.

Using a dedicated project keeps testing credentials separate from production
Google projects.

## Step 2: Enable Gmail API

1. In the left navigation, open **APIs & Services**.
2. Click **Library**.
3. Search for `Gmail API`.
4. Open **Gmail API**.
5. Click **Enable**.

If the button says **Manage**, the API is already enabled for this project.

## Step 3: Configure The OAuth Consent Screen

Google has been moving this UI into **Google Auth Platform**. Older projects may
still show **APIs & Services > OAuth consent screen**. The same settings exist
in both layouts.

1. In the left navigation, open **Google Auth Platform**. If your Console still
   uses the older layout, open **APIs & Services > OAuth consent screen**.
2. If this is a new project, click **Get started**.
3. Set the app name to something local and clear, such as
   `Customer Email Assist Local`.
4. Set **User support email** to your Gmail address.
5. Set **Audience**:
   * Choose **External** for a personal Gmail account.
   * Choose **Internal** only for a Google Workspace app used inside that
     organization.
6. Add your email under **Contact information** or
   **Developer contact information**.
7. Keep publishing status as **Testing** while developing.
8. Save the app information.

Testing mode is enough for a local workshop or single-operator starter. For a
public multi-user app, expect Google OAuth verification requirements.

## Step 4: Add Yourself As A Test User

1. Open **Google Auth Platform > Audience**. In the older layout, open
   **APIs & Services > OAuth consent screen**.
2. Find **Test users**.
3. Click **Add users**.
4. Enter the Gmail address that will authorize mailbox access.
5. Click **Save**.

If the app remains in Testing mode, only listed test users can authorize it.

## Step 5: Add Gmail Scopes

1. Open **Google Auth Platform > Data Access**. In the older layout, open the
   consent screen's **Scopes** step.
2. Click **Add or remove scopes**.
3. Search for Gmail.
4. Select or manually add:

```text theme={null}
https://www.googleapis.com/auth/gmail.send
https://www.googleapis.com/auth/gmail.readonly
```

Use `gmail.send` when the local dashboard needs to send approved replies.
Use `gmail.readonly` when local scripts need to import Gmail threads. If your
flow only sends and never imports through local OAuth, `gmail.send` is the
minimum scope.

## Step 6: Create The OAuth Client

1. Open **APIs & Services > Credentials**.
2. Click **Create Credentials**.
3. Select **OAuth client ID**.
4. For **Application type**, choose **Web application**.
5. Name it `Customer Email Assist Local Web`.
6. Under **Authorized redirect URIs**, click **Add URI**.
7. Enter the callback URI for the port where your dashboard runs:

```text theme={null}
http://localhost:3002/api/gmail/oauth/callback
```

If you use the default Next.js port, add this instead:

```text theme={null}
http://localhost:3000/api/gmail/oauth/callback
```

If you use both ports during testing, add both URIs.

8. Click **Create**.
9. Copy the client ID and client secret into `.env.local`.

Google may only show or download the client secret at creation time. Store it
in your local `.env.local`, not in the repository.

## Step 7: Create `.env.local`

In the starter directory, create:

```text theme={null}
case-studies/examples/customer-email-assist-starter/.env.local
```

Use this shape:

```bash theme={null}
GOOGLE_CLIENT_ID="paste-client-id"
GOOGLE_CLIENT_SECRET="paste-client-secret"

CUSTOMER_EMAIL_ASSIST_GMAIL_LABEL="INBOX"

# Optional
GOOGLE_REDIRECT_URI="http://localhost:3002/api/gmail/oauth/callback"
CUSTOMER_EMAIL_ASSIST_OPERATOR_EMAIL="you@example.com"
GOOGLE_REFRESH_TOKEN="manual-fallback-refresh-token"
CUSTOMER_EMAIL_ASSIST_DB_PATH="/tmp/customer-email-assist.sqlite3"
CUSTOMER_EMAIL_ASSIST_POLICY_PATH="./support-policy.md"
```

Restart the dashboard after editing `.env.local`.

## Step 8: Connect Gmail From The Dashboard

1. Start the dashboard.
2. Leave **Gmail mode** set to **OAuth**.
3. Click **Connect Gmail**.
4. Sign in as the same test user you configured in Google Cloud.
5. Approve the Gmail scopes.
6. Google redirects back to `/api/gmail/oauth/callback`.
7. The app stores the refresh token locally under:

```text theme={null}
~/.codex/state/customer-email-assist/gmail-oauth.json
```

This is the normal web-app flow. OAuth Playground is only a manual debugging
fallback now; users should not need it for the starter.

## Step 9: Use The Dashboard Mode Switch

In the Customer Email Assist dashboard:

* Select **OAuth** to use local OAuth. This attempts the direct Gmail API send
  path after the undo countdown.
* Select **Gmail connector** to queue approved replies for connector-backed
  processing instead.

## Quick Verification

From the starter folder:

```bash theme={null}
npm install
npm run setup-local
npm run dev
```

For a local OAuth sync pass:

```bash theme={null}
npm run sync:oauth
```

For queued approved replies:

```bash theme={null}
tsx scripts/customer-email-assist.ts apply-send-queue
```

## Official References

* [Gmail API scopes](https://developers.google.com/workspace/gmail/api/auth/scopes)
* [Gmail send API](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/send)
* [Google web server OAuth flow](https://developers.google.com/identity/protocols/oauth2/web-server)
* [Google OAuth app verification](https://support.google.com/cloud/answer/13463073)
* [Google Auth Platform audience and test users](https://support.google.com/cloud/answer/15549945)
