@accounter/gmail-listener
Version:
A Gmail listener that listens for new emails, extracts financial documents, and sends them to the server
129 lines (87 loc) • 4.06 kB
Markdown
## Setup Instructions
These instructions are specific to this repository package: `packages/gmail-listener`.
### 1. Google Cloud Project Setup
1. Create or select a Google Cloud project in <https://console.cloud.google.com/>.
2. Enable these APIs in that project:
- Gmail API
- Cloud Pub/Sub API
3. Create a service account for Pub/Sub access:
- IAM & Admin -> Service Accounts -> Create Service Account
- Grant least-privilege Pub/Sub permissions required by your org policy (Editor is not required)
- Create and download a JSON key
4. Save the downloaded JSON key in this package directory as:
- `packages/gmail-listener/accounter-gmail-service-key.json`
5. Ensure Gmail can publish to Pub/Sub topic:
- In Pub/Sub topic permissions, add principal `gmail-api-push@system.gserviceaccount.com`
- Grant role `Pub/Sub Publisher`
Note: this repository already ignores `**/accounter-gmail-service-key.json` in root `.gitignore`.
### 2. Pub/Sub Resources
Create:
- Topic: `gmail-notifications` (or your custom name)
- Subscription: `gmail-notifications-sub` (or your custom name)
You can use custom names, but they must match `PUBSUB_TOPIC` and `PUBSUB_SUBSCRIPTION` in `.env`.
### 3. Gmail OAuth App Setup
1. In Google Cloud Console, go to APIs & Services -> Credentials.
2. Create OAuth 2.0 Client ID credentials.
3. Configure the consent screen according to your organization policy.
4. Keep client ID and client secret for `.env`.
### 4. Generate Refresh Token
Use OAuth Playground:
1. Open <https://developers.google.com/oauthplayground>
2. Click the settings gear and enable "Use your own OAuth credentials"
3. Paste your OAuth client ID and client secret and close the settings dialog
4. Select scope `https://mail.google.com/` (under Gmail API v1)
5. Authorize with the mailbox you want the listener to monitor
6. Exchange authorization code for tokens and copy the refresh token
### 5. Environment Configuration
Create `.env` in `packages/gmail-listener` (or copy from `.env.template`):
```env
# Accounter server GraphQL endpoint
SERVER_URL=https://your-accounter-server/graphql
# API key for X-API-Key header when calling Accounter server
GMAIL_LISTENER_API_KEY=your_api_key
# Gmail OAuth2
GMAIL_CLIENT_ID=your_client_id
GMAIL_CLIENT_SECRET=your_client_secret
GMAIL_REFRESH_TOKEN=your_refresh_token
GMAIL_LABEL_PATH=accounter/documents
# Google Cloud / PubSub
GOOGLE_CLOUD_PROJECT_ID=your_project_id
PUBSUB_TOPIC=gmail-notifications
PUBSUB_SUBSCRIPTION=gmail-notifications-sub
# Absolute or package-relative path to the service account key JSON
GOOGLE_APPLICATION_CREDENTIALS=./accounter-gmail-service-key.json
```
Important:
- `GMAIL_CLIENT_ID`, `GMAIL_CLIENT_SECRET`, `GMAIL_REFRESH_TOKEN`, `GOOGLE_CLOUD_PROJECT_ID`, and
`GOOGLE_APPLICATION_CREDENTIALS` are validated together. Set all of them or none.
- If the process is not started from `packages/gmail-listener`, prefer an absolute path for
`GOOGLE_APPLICATION_CREDENTIALS`.
### 6. Run the Service
From `packages/gmail-listener`:
```bash
yarn
yarn dev
```
On startup, the listener:
1. validates env
2. validates OAuth access
3. ensures labels exist
4. processes pending labeled messages
5. starts Pub/Sub listening and Gmail watch renewal
### 7. Validate End-to-End
1. Send a test invoice email to the monitored mailbox.
2. Apply/confirm the target label (default `accounter/documents`).
3. Verify logs show processing.
4. Check resulting labels:
- success -> `.../processed`
- failure -> `.../errors`
- no relevant docs -> `.../debug`
## Troubleshooting Notes
- `invalid_grant`: refresh token is invalid/expired or consent screen configuration is incomplete.
- Gmail watch setup errors: verify topic exists and Gmail publisher principal is granted.
- No documents extracted: inspect email attachments/type filters and business email config on server
side.
## About Polling
This package is implemented with Gmail push notifications + Pub/Sub, not polling. Keep polling as a
fallback design only if infrastructure constraints prevent Pub/Sub usage.