Skip to content

Gmail Integration API

The Gmail integration enables organizations to send invoices directly via Gmail using OAuth2. The flow uses Google OAuth2 for authorization, Puppeteer for server-side PDF generation from invoice data, and the Gmail API to send the email with the PDF attachment.

Prerequisites

  • A Google Cloud project with the Gmail API enabled
  • OAuth2 credentials (Client ID & Client Secret) configured on the backend
  • The organization must complete the OAuth2 consent flow before sending invoices

Architecture Overview

┌─────────┐    ┌──────────┐    ┌────────────┐    ┌───────────┐
│ Frontend │───▶│ Backend  │───▶│ Puppeteer  │───▶│ Gmail API │
│          │    │          │    │ (PDF Gen)  │    │ (Send)    │
└─────────┘    └──────────┘    └────────────┘    └───────────┘
                    │                                   ▲
                    │         ┌──────────────┐          │
                    └────────▶│ Google OAuth2 │─────────┘
                              └──────────────┘

Endpoints

GET /api/gmail/:orgId/auth-url

Generate the Google OAuth2 authorization URL. Redirect the user to this URL to begin the consent flow.

Path Parameters

ParamTypeDescription
orgIdstringOrganization ID

Response 200 OK

json
{
  "success": true,
  "authUrl": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...&scope=https://www.googleapis.com/auth/gmail.send&response_type=code&access_type=offline&prompt=consent"
}

Scopes Requested

ScopePurpose
https://www.googleapis.com/auth/gmail.sendSend emails on behalf of the user

POST /api/gmail/:orgId/callback

Handle the OAuth2 callback after the user grants consent. Exchanges the authorization code for access & refresh tokens, which are securely stored for the organization.

Path Parameters

ParamTypeDescription
orgIdstringOrganization ID

Request Body

FieldTypeRequiredDescription
codestringYesAuthorization code from Google
statestringNoState parameter for CSRF validation
json
{
  "code": "4/0AX4XfWh...",
  "state": "random-state-string"
}

Response 200 OK

json
{
  "success": true,
  "message": "Gmail connected successfully",
  "email": "hotel@gmail.com"
}

Token Storage

Refresh tokens are encrypted at rest and stored in the organization document. Access tokens are refreshed automatically when expired.


GET /api/gmail/:orgId/status

Check whether the organization has a valid Gmail connection.

Path Parameters

ParamTypeDescription
orgIdstringOrganization ID

Response 200 OK

json
{
  "success": true,
  "connected": true,
  "email": "hotel@gmail.com",
  "connectedAt": "2026-01-15T10:30:00.000Z"
}

Disconnected State

json
{
  "success": true,
  "connected": false,
  "email": null,
  "connectedAt": null
}

POST /api/gmail/:orgId/disconnect

Revoke the Gmail OAuth2 tokens and disconnect the integration for the organization.

Path Parameters

ParamTypeDescription
orgIdstringOrganization ID

Response 200 OK

json
{
  "success": true,
  "message": "Gmail disconnected successfully"
}

POST /api/gmail/:orgId/:invoiceId/send-invoice

Generate a PDF for the given invoice using Puppeteer and send it as a Gmail attachment to the guest's email address.

Path Parameters

ParamTypeDescription
orgIdstringOrganization ID
invoiceIdstringInvoice ID

Flow

  1. Fetch invoice data (line items, guest info, org details)
  2. Render invoice HTML template server-side
  3. Generate PDF via Puppeteer (page.pdf())
  4. Upload PDF to Azure Blob Storage (temporary)
  5. Compose email with PDF attachment via Gmail API
  6. Send email to the guest's registered email address
  7. Clean up temporary PDF

Response 200 OK

json
{
  "success": true,
  "message": "Invoice sent successfully",
  "sentTo": "guest@example.com",
  "invoiceNumber": "INV-2026-0042"
}

Error Scenarios

StatusCondition
400Invoice not found or missing guest email
401Gmail not connected for this org
502Gmail API or Puppeteer failure
json
{
  "success": false,
  "message": "Gmail is not connected. Please authorize first."
}

Integration Lifecycle

StepActionEndpoint
1Get authorization URLGET /api/gmail/:orgId/auth-url
2User grants consent(Google OAuth2 consent screen)
3Exchange code for tokensPOST /api/gmail/:orgId/callback
4Verify connectionGET /api/gmail/:orgId/status
5Send invoicesPOST /api/gmail/:orgId/:invoiceId/send-invoice
6Disconnect (if needed)POST /api/gmail/:orgId/disconnect

Error Responses

All endpoints follow the standard error format:

json
{
  "success": false,
  "message": "Descriptive error message"
}

Released under the MIT License.