Gmail
Gmail API access
Create a demo Gmail account, a Google Cloud project with the Gmail API, an OAuth consent screen in production, a desktop client, and a refresh token.
By the end of this page your .env holds a client ID, a client secret, and a refresh token for the demo Gmail account. With those three values the backend can read, send, and label mail without a browser.
Gmail is the inbox here because everyone can create one for free. A real company would usually use a ticketing system such as Help Scout, Gorgias, or Zendesk, and the pipeline stays the same.
Why OAuth and not an API key
API keys only work for public data. Mail is private, so the account owner has to approve access once. You do that in the browser, and Google gives you a refresh token that the backend uses from then on. A service account does not work for a personal gmail.com address. That needs Google Workspace.
Create the demo Gmail account
Create a new Gmail account for this project, for example harborandpine.support@gmail.com (pick any free name). Stay logged in with it in your browser for the next steps.
Create a Google Cloud project
- Open the Google Cloud console with the demo account.
- Click the project picker at the top, then New project.
- Name it
ai-customer-supportand click Create. Select it when it is ready.
Enable the Gmail API
- Open APIs & Services, then Library.
- Search for Gmail API, open it, and click Enable.
Set up the consent screen
- Open Google Auth platform, then Branding, and click Get started.
- App name:
AI customer support. User support email: the demo address. - Audience: External. A personal Gmail account cannot pick Internal.
- Contact email: the demo address. Accept the policy and click Create.
Publish the app
Open Audience and click Publish app, then confirm. The publishing status changes to In production.
Do not skip this
In Testing, refresh tokens expire after 7 days, and the server stops reading mail a week after you deploy it. For an app only you use, production needs no Google verification. You click through an "unverified app" warning once.
Add the Gmail scope
- Open Data access and click Add or remove scopes.
- Filter for
gmail.modify, tickhttps://www.googleapis.com/auth/gmail.modify, and click Update, then Save.
gmail.modify covers reading, sending, and labels. It is the only scope this project needs.
Create a desktop client
- Open Clients and click Create client.
- Application type: Desktop app. Name:
ai-customer-support. - Click Create, then download the JSON file.
- Rename it to
credentials.jsonand move it into the root ofai-customer-support.
credentials.json is already in .gitignore. Never commit it.
Get the refresh token
This script runs once on your laptop. It opens the browser, you log in with the demo account, and it prints the three values for .env.
from google_auth_oauthlib.flow import InstalledAppFlow
SCOPES = ["https://www.googleapis.com/auth/gmail.modify"]
flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
# prompt="consent" makes Google return a refresh token every time.
creds = flow.run_local_server(port=0, access_type="offline", prompt="consent")
print(f"GOOGLE_CLIENT_ID={creds.client_id}")
print(f"GOOGLE_CLIENT_SECRET={creds.client_secret}")
print(f"GOOGLE_REFRESH_TOKEN={creds.refresh_token}")uv run python scripts/get_refresh_token.pyIn the browser:
- Pick the demo account.
- Google shows Google hasn't verified this app. Click Advanced, then Go to AI customer support (unsafe). It is your own app.
- Allow access to Gmail.
Back in the terminal, copy the three printed lines into .env.
The terminal now shows secrets. Clear it afterwards, and never share a screenshot of it.
Check
.env holds a value for GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and GOOGLE_REFRESH_TOKEN. In the Google Cloud console, Audience shows In production.
The google-auth library turns the refresh token into short-lived access tokens by itself. The same three values go to the server later.