Use when a Google integration (Gmail, Docs, Sheets, Drive, Calendar) needs its OAuth client set up, its refresh token obtained again after expiry, or an access token minted at runtime.
Install
npx skillscat add chnlich/charlie-bot/google-oauth Install via the SkillsCat registry.
Google OAuth
All Google integrations share a single OAuth client and refresh token.
Configuration
Single home of the shared credential setup; integration skills point here instead of restating it.
- Credentials location:
~/.charliebot/credentials.yaml - Keys (section
google):client_id,client_secret,refresh_token - Auth model: OAuth2 user token flow using a long-lived refresh token
- Store only the
refresh_tokenkey in thegooglesection. Access tokens are minted at runtime and discarded after use.
Runtime Token Mint
Every integration mints its access token at call time from the stored refresh
token; access tokens are never persisted. Run this before the integration's own
API calls:
# Read credentials (uses python3+pyyaml)
read GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET GOOGLE_REFRESH_TOKEN < <(python3 -c "
import yaml
c = yaml.safe_load(open('$HOME/.charliebot/credentials.yaml'))
print(c['google']['client_id'], c['google']['client_secret'], c['google']['refresh_token'])
")
ACCESS_TOKEN=$(curl -s -X POST https://oauth2.googleapis.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=$GOOGLE_CLIENT_ID" \
--data-urlencode "client_secret=$GOOGLE_CLIENT_SECRET" \
--data-urlencode "refresh_token=$GOOGLE_REFRESH_TOKEN" \
--data-urlencode "grant_type=refresh_token" | jq -r '.access_token')Bootstrap / Re-Authorization
One-time setup to obtain a refresh token for the desktop-app OAuth flow:
- In Google Cloud Console, enable the APIs you need (Gmail, Docs, Sheets, Drive, Calendar).
- Create an OAuth client of type Desktop app.
- Open the consent URL with all scopes and offline access. Use
redirect_uri=http://localhost(nothttp://127.0.0.1:PORT):
response_type=code
client_id=CLIENT_ID
redirect_uri=http://localhost
scope=https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/calendar
access_type=offline
prompt=consent- Authorize once, capture the
codefrom the redirect, and exchange it for tokens:
curl -s -X POST https://oauth2.googleapis.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=CLIENT_ID" \
--data-urlencode "client_secret=CLIENT_SECRET" \
--data-urlencode "code=AUTH_CODE" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "redirect_uri=http://localhost"- Save the returned
refresh_tokento therefresh_tokenkey of thegooglesection in~/.charliebot/credentials.yaml.
Note: If the GCP project is in Testing mode, the refresh token expires in ~7 days. Publish the OAuth consent screen to Production for non-expiring tokens.