Skip to content

Developer-MultiGroup/dmg-mailer

Repository files navigation

Environment Variables Guide

This document explains all environment variables needed for the bulk email sender application and exactly where to obtain them.

Quick Setup

# Copy the example file
cp .env.example .env.local

# Fill in all variables (see below for instructions)

Environment Variables Overview

# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=

# Gmail API Configuration
GMAIL_CLIENT_ID=
GMAIL_CLIENT_SECRET=
GMAIL_REDIRECT_URI=
GMAIL_REFRESH_TOKEN=
GMAIL_USER=

# PostHog Analytics
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=

# Optional: Database (if using)
DATABASE_URL=

# Optional: App Configuration
NEXT_PUBLIC_APP_URL=

1. Supabase Configuration

NEXT_PUBLIC_SUPABASE_URL

What it is: Your Supabase project URL
Required: βœ… Yes
Example: https://abcdefghijklmnop.supabase.co

How to Get It:

  1. Go to https://supabase.com/dashboard
  2. Click on your project (or create a new one)
  3. Click "Settings" in the left sidebar
  4. Click "API" under Settings
  5. Find "Project URL" at the top
  6. Copy the URL

Screenshot Location:

Dashboard β†’ Your Project β†’ Settings β†’ API β†’ Project URL

NEXT_PUBLIC_SUPABASE_ANON_KEY

What it is: Your Supabase anonymous/public API key
Required: βœ… Yes
Example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

How to Get It:

  1. In the same "Settings β†’ API" page (from above)
  2. Scroll down to "Project API keys"
  3. Find "anon public" key
  4. Click the copy icon
  5. Paste in your .env.local

Screenshot Location:

Dashboard β†’ Your Project β†’ Settings β†’ API β†’ Project API keys β†’ anon public

⚠️ Note: This key is safe to expose on the client-side. It's meant to be public.


2. Gmail API Configuration

Step 1: Create Google Cloud Project

  1. Go to https://console.cloud.google.com
  2. Click "Select a project" dropdown at the top
  3. Click "New Project"
  4. Enter project name (e.g., "Bulk Email Sender")
  5. Click "Create"
  6. Wait for project creation (~30 seconds)
  7. Select your new project from the dropdown

Step 2: Enable Gmail API

  1. In Google Cloud Console, go to "APIs & Services" β†’ "Library"
  2. Search for "Gmail API"
  3. Click on "Gmail API" in results
  4. Click "Enable" button
  5. Wait for API to be enabled (~10 seconds)

Direct Link: https://console.cloud.google.com/apis/library/gmail.googleapis.com


Step 3: Configure OAuth Consent Screen

  1. Go to "APIs & Services" β†’ "OAuth consent screen"
  2. Select "Internal" (if you have Google Workspace) or "External"
  3. Click "Create"

Fill in required fields:

  • App name: Bulk Email Sender (or your app name)
  • User support email: Your email
  • Developer contact email: Your email
  • Click "Save and Continue"

Scopes (Step 2):

  • Click "Add or Remove Scopes"
  • Search for: https://www.googleapis.com/auth/gmail.send
  • Check the box next to "Gmail API .../auth/gmail.send"
  • Click "Update"
  • Click "Save and Continue"

Test Users (if External):

  • Click "Add Users"
  • Add your Gmail address
  • Click "Save and Continue"

Summary:

  • Review and click "Back to Dashboard"

Step 4: Create OAuth2 Credentials

  1. Go to "APIs & Services" β†’ "Credentials"
  2. Click "Create Credentials" β†’ "OAuth 2.0 Client ID"
  3. Application type: "Web application"
  4. Name: Bulk Email Sender (or your choice)

Authorized redirect URIs:

  • Click "Add URI"
  • Enter: http://localhost:3000/api/auth/callback
  • (For production, add: https://yourdomain.com/api/auth/callback)
  1. Click "Create"
  2. A popup will show your credentials

GMAIL_CLIENT_ID

What it is: OAuth 2.0 Client ID
Required: βœ… Yes
Example: 123456789-abc123def456.apps.googleusercontent.com

How to Get It:

From the credentials creation popup (Step 4):

  • Copy "Your Client ID"
  • Or go to "APIs & Services" β†’ "Credentials"
  • Click on your OAuth 2.0 Client
  • Copy "Client ID"

GMAIL_CLIENT_SECRET

What it is: OAuth 2.0 Client Secret
Required: βœ… Yes
Example: GOCSPX-abc123def456ghi789jkl

How to Get It:

From the same location as Client ID:

  • Copy "Your Client Secret"
  • Or from the credentials page, copy "Client secret"

⚠️ Security Warning:

  • Never commit this to Git
  • Store securely in .env.local
  • Rotate periodically for security

GMAIL_REDIRECT_URI

What it is: The OAuth callback URL
Required: βšͺ Optional (auto-detected if not set)
Auto-detection:

  • If NEXT_PUBLIC_APP_URL is set: ${NEXT_PUBLIC_APP_URL}/api/auth/callback
  • Development (NODE_ENV !== 'production'): http://localhost:3000/api/auth/callback
  • Production (NODE_ENV === 'production'): https://mail.devmultigroup.com/api/auth/callback

How to Set It:

Option 1: Use NEXT_PUBLIC_APP_URL (Recommended)

# Development
NEXT_PUBLIC_APP_URL=http://localhost:3000

# Production
NEXT_PUBLIC_APP_URL=https://mail.devmultigroup.com

The redirect URI will be automatically constructed as ${NEXT_PUBLIC_APP_URL}/api/auth/callback

Option 2: Set GMAIL_REDIRECT_URI manually

# Development
GMAIL_REDIRECT_URI=http://localhost:3000/api/auth/callback

# Production
GMAIL_REDIRECT_URI=https://mail.devmultigroup.com/api/auth/callback

Note: This must match exactly what you added in "Authorized redirect URIs" in Google Cloud Console.


GMAIL_REFRESH_TOKEN

What it is: OAuth refresh token for Gmail API
Required: βœ… Yes
Example: 1//0abc123def456ghi789jkl...

How to Get It:

This requires a special authentication flow. Follow these steps:

Option A: Using Our Helper Script

  1. Create a file scripts/get-refresh-token.js:
const { google } = require('googleapis');
const readline = require('readline');

const oauth2Client = new google.auth.OAuth2(
  process.env.GMAIL_CLIENT_ID,
  process.env.GMAIL_CLIENT_SECRET,
  process.env.GMAIL_REDIRECT_URI
);

const scopes = ['https://www.googleapis.com/auth/gmail.send'];

const authUrl = oauth2Client.generateAuthUrl({
  access_type: 'offline',
  scope: scopes,
  prompt: 'consent',
});

console.log('Authorize this app by visiting this url:', authUrl);

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.question('Enter the code from that page here: ', async (code) => {
  rl.close();
  try {
    const { tokens } = await oauth2Client.getToken(code);
    console.log('\nβœ… Success! Add this to your .env.local:\n');
    console.log(`GMAIL_REFRESH_TOKEN=${tokens.refresh_token}`);
  } catch (error) {
    console.error('Error retrieving access token', error);
  }
});
  1. Run the script:
node scripts/get-refresh-token.js
  1. Open the URL shown in your browser
  2. Sign in with your Gmail account
  3. Grant permissions
  4. Copy the authorization code from the URL
  5. Paste it into the terminal
  6. Copy the refresh token to your .env.local

Option B: Using OAuth2 Playground

  1. Go to https://developers.google.com/oauthplayground
  2. Click the gear icon (βš™οΈ) in top right
  3. Check "Use your own OAuth credentials"
  4. Enter your Client ID and Client Secret
  5. Close settings

In the left panel:

Exchange authorization code:

  • Click "Exchange authorization code for tokens"
  • Copy the "Refresh token"
  • Paste in your .env.local

⚠️ Important:

  • Refresh token is generated only once
  • If you lose it, you need to revoke access and generate a new one
  • Store it securely

GMAIL_USER

What it is: Your Gmail/Google Workspace email address
Required: βœ… Yes
Example: your.email@gmail.com or you@yourcompany.com

How to Set It:

Simply use the Gmail address you want to send emails from:

GMAIL_USER=your.email@gmail.com

Requirements:

  • Must be a Google Workspace account for 2000 recipient limit
  • Must be the same account used for OAuth
  • Must have permission to send emails

3. PostHog Analytics Configuration

What is PostHog?

PostHog is an open-source product analytics platform that will help you track:

  • User behavior and events
  • Email sending metrics
  • Feature usage
  • Error tracking
  • User journeys
  • Performance monitoring

NEXT_PUBLIC_POSTHOG_KEY

What it is: Your PostHog project API key
Required: βœ… Yes (for analytics)
Example: phc_abc123def456ghi789jklmnopqrstuvwxyz

How to Get It:

Step 1: Create PostHog Account

  1. Go to https://app.posthog.com/signup
  2. Sign up for a free account (no credit card required)
  3. Choose "PostHog Cloud" (recommended) or self-hosted
  4. Complete the onboarding

Step 2: Create Project

  1. After signup, you'll be in your first project
  2. Or click "Project" in top left β†’ "Create project"
  3. Enter project name: "Bulk Email Sender"
  4. Click "Create project"

Step 3: Get Project API Key

  1. Click "Project settings" (gear icon) in left sidebar
  2. Or go to: Settings β†’ Project
  3. Find "Project API Key" section
  4. Copy the key (starts with phc_)
  5. Paste in your .env.local

Screenshot Location:

Dashboard β†’ Settings β†’ Project β†’ Project API Key

Direct Link: https://app.posthog.com/settings/project


NEXT_PUBLIC_POSTHOG_HOST

What it is: PostHog API endpoint URL
Required: βœ… Yes
Default for PostHog Cloud: https://app.posthog.com or https://us.posthog.com

How to Set It:

For PostHog Cloud (US):

NEXT_PUBLIC_POSTHOG_HOST=https://us.posthog.com

For PostHog Cloud (EU):

NEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.com

For Self-Hosted:

NEXT_PUBLIC_POSTHOG_HOST=https://your-posthog-instance.com

How to find your host:

  1. Go to PostHog Settings β†’ Project
  2. Find "Host" in the snippet code
  3. Copy the URL

Default: Use https://us.posthog.com if you signed up for PostHog Cloud US


4. Optional Configuration

DATABASE_URL

What it is: PostgreSQL connection string (if using Supabase database features)
Required: βšͺ Optional
Example: postgresql://postgres:password@db.project.supabase.co:5432/postgres

How to Get It:

  1. Go to Supabase Dashboard
  2. Click "Settings" β†’ "Database"
  3. Scroll to "Connection string"
  4. Select "URI" tab
  5. Copy the connection string
  6. Replace [YOUR-PASSWORD] with your database password

When you need this:

  • If storing campaign history in database
  • If using Row Level Security features
  • If building analytics dashboard

NEXT_PUBLIC_APP_URL

What it is: Your application's URL
Required: βšͺ Optional (but recommended)
Example:

  • Development: http://localhost:3000
  • Production: https://mail.devmultigroup.com

How to Set It:

# Development
NEXT_PUBLIC_APP_URL=http://localhost:3000

# Production
NEXT_PUBLIC_APP_URL=https://mail.devmultigroup.com

Used for:

  • Generating absolute URLs
  • Auto-constructing GMAIL_REDIRECT_URI: ${NEXT_PUBLIC_APP_URL}/api/auth/callback
  • Email links
  • Other absolute URL needs

Note: If set, GMAIL_REDIRECT_URI will be automatically constructed from this value.


Complete .env.local Example

# ======================
# Supabase Configuration
# ======================
NEXT_PUBLIC_SUPABASE_URL=https://abcdefghijklmnop.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiY2RlZmdoaWprbG1ub3AiLCJyb2xlIjoiYW5vbiIsImlhdCI6MTYyMzA4NTQ4NCwiZXhwIjoxOTM4NjYxNDg0fQ.abc123def456

# ============================
# Gmail API Configuration
# ============================
GMAIL_CLIENT_ID=123456789012-abc123def456ghi789jkl.apps.googleusercontent.com
GMAIL_CLIENT_SECRET=GOCSPX-abc123def456ghi789
GMAIL_REDIRECT_URI=http://localhost:3000/api/auth/callback
GMAIL_REFRESH_TOKEN=1//0abc123def456ghi789jkl_mnopqrs-tuv-wxyzABCDEF
GMAIL_USER=your.email@gmail.com

# ============================
# PostHog Analytics
# ============================
NEXT_PUBLIC_POSTHOG_KEY=phc_abc123def456ghi789jklmnopqrstuvwxyz
NEXT_PUBLIC_POSTHOG_HOST=https://us.posthog.com

# ============================
# Optional Configuration
# ============================
DATABASE_URL=postgresql://postgres:your-password@db.abcdefghijklmnop.supabase.co:5432/postgres
NEXT_PUBLIC_APP_URL=http://localhost:3000

Verification Checklist

Before running your application, verify:

Supabase

  • Project created and active
  • URL copied correctly
  • Anon key copied correctly
  • Email authentication enabled

Google Cloud

  • Project created
  • Gmail API enabled
  • OAuth consent screen configured
  • OAuth credentials created
  • Redirect URI matches exactly

PostHog

  • Account created
  • Project created
  • API key copied correctly
  • Host URL set correctly

Environment Variables

  • All required variables set
  • No extra spaces in values
  • Quotes removed from values
  • File saved as .env.local (not .env.local.txt)
  • File in project root directory

Gmail Account

  • Using Google Workspace account (for 2K limit)
  • Account has sending permissions
  • Refresh token generated successfully
  • Test email sent successfully

Testing Your Configuration

1. Test Supabase Connection

Create a test file scripts/test-supabase.js:

const { createClient } = require('@supabase/supabase-js');
require('dotenv').config({ path: '.env.local' });

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);

async function test() {
  const { data, error } = await supabase.auth.getSession();
  if (error) {
    console.error('❌ Supabase connection failed:', error.message);
  } else {
    console.log('βœ… Supabase connection successful!');
  }
}

test();

Run: node scripts/test-supabase.js


2. Test Gmail API Connection

Create a test file scripts/test-gmail.js:

const { google } = require('googleapis');
require('dotenv').config({ path: '.env.local' });

async function test() {
  try {
    const oauth2Client = new google.auth.OAuth2(
      process.env.GMAIL_CLIENT_ID,
      process.env.GMAIL_CLIENT_SECRET,
      process.env.GMAIL_REDIRECT_URI
    );

    oauth2Client.setCredentials({
      refresh_token: process.env.GMAIL_REFRESH_TOKEN,
    });

    const gmail = google.gmail({ version: 'v1', auth: oauth2Client });
    
    // Test: Get user profile
    const profile = await gmail.users.getProfile({ userId: 'me' });
    
    console.log('βœ… Gmail API connection successful!');
    console.log(`πŸ“§ Connected as: ${profile.data.emailAddress}`);
    console.log(`πŸ“Š Total messages: ${profile.data.messagesTotal}`);
  } catch (error) {
    console.error('❌ Gmail API connection failed:', error.message);
  }
}

test();

Run: node scripts/test-gmail.js


3. Send Test Email

Create scripts/send-test-email.js:

const { google } = require('googleapis');
require('dotenv').config({ path: '.env.local' });

async function sendTestEmail() {
  const oauth2Client = new google.auth.OAuth2(
    process.env.GMAIL_CLIENT_ID,
    process.env.GMAIL_CLIENT_SECRET,
    process.env.GMAIL_REDIRECT_URI
  );

  oauth2Client.setCredentials({
    refresh_token: process.env.GMAIL_REFRESH_TOKEN,
  });

  const gmail = google.gmail({ version: 'v1', auth: oauth2Client });

  const message = [
    `From: ${process.env.GMAIL_USER}`,
    `To: ${process.env.GMAIL_USER}`,
    'Subject: Test Email from Bulk Sender',
    '',
    'This is a test email. If you receive this, your setup is working!',
  ].join('\n');

  const encodedMessage = Buffer.from(message)
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');

  try {
    await gmail.users.messages.send({
      userId: 'me',
      requestBody: {
        raw: encodedMessage,
      },
    });
    console.log('βœ… Test email sent successfully!');
    console.log(`πŸ“§ Check your inbox: ${process.env.GMAIL_USER}`);
  } catch (error) {
    console.error('❌ Failed to send test email:', error.message);
  }
}

sendTestEmail();

Run: node scripts/send-test-email.js


4. Test PostHog Connection

Create scripts/test-posthog.js:

const { PostHog } = require('posthog-node');
require('dotenv').config({ path: '.env.local' });

async function test() {
  try {
    const client = new PostHog(
      process.env.NEXT_PUBLIC_POSTHOG_KEY,
      { host: process.env.NEXT_PUBLIC_POSTHOG_HOST }
    );

    // Send a test event
    client.capture({
      distinctId: 'test-user',
      event: 'test_event',
      properties: {
        test: true,
        timestamp: new Date().toISOString(),
      },
    });

    await client.shutdown();
    
    console.log('βœ… PostHog connection successful!');
    console.log('πŸ“Š Check your PostHog dashboard for the "test_event"');
    console.log(`πŸ”— Dashboard: ${process.env.NEXT_PUBLIC_POSTHOG_HOST}/project/events`);
  } catch (error) {
    console.error('❌ PostHog connection failed:', error.message);
  }
}

test();

Run: node scripts/test-posthog.js

Then check your PostHog dashboard to see if the test event appears.


Troubleshooting

"Invalid client" error

Problem: Client ID or Client Secret is wrong
Solution:

  1. Go back to Google Cloud Console
  2. Verify credentials in "APIs & Services" β†’ "Credentials"
  3. Copy them again carefully
  4. Remove any extra spaces

"Redirect URI mismatch" error

Problem: GMAIL_REDIRECT_URI doesn't match Google Cloud settings
Solution:

  1. Check Google Cloud Console β†’ Credentials β†’ Your OAuth Client
  2. Ensure redirect URI is exactly: http://localhost:3000/api/auth/callback
  3. No trailing slash
  4. Correct protocol (http vs https)

"Invalid refresh token" error

Problem: Refresh token is incorrect or expired
Solution:

  1. Revoke access in Google Account settings
  2. Generate a new refresh token
  3. Use the helper script or OAuth Playground again

Supabase connection fails

Problem: Incorrect URL or anon key
Solution:

  1. Double-check values in Supabase Dashboard
  2. Ensure no extra characters or spaces
  3. Try recreating the Supabase client

"Gmail API not enabled"

Problem: API not enabled in Google Cloud
Solution:

  1. Go to Google Cloud Console
  2. "APIs & Services" β†’ "Library"
  3. Search "Gmail API"
  4. Click "Enable"
  5. Wait a few minutes for propagation

"PostHog events not appearing"

Problem: Events not showing in PostHog dashboard
Solution:

  1. Verify NEXT_PUBLIC_POSTHOG_KEY is correct
  2. Check NEXT_PUBLIC_POSTHOG_HOST matches your region
  3. Wait 1-2 minutes for events to process
  4. Check PostHog project is active
  5. Verify no ad blockers are blocking PostHog

"Invalid PostHog API key"

Problem: PostHog key is incorrect
Solution:

  1. Go to PostHog Dashboard β†’ Settings β†’ Project
  2. Copy the Project API Key (starts with phc_)
  3. Ensure no extra spaces or characters
  4. Restart your development server

Security Best Practices

βœ… DO:

  • Store .env.local file locally only
  • Add .env.local to .gitignore
  • Rotate credentials every 6 months
  • Use environment variables in Vercel for production
  • Enable 2FA on Google and Supabase accounts
  • Limit OAuth scopes to minimum needed

❌ DON'T:

  • Commit .env.local to Git
  • Share credentials in Slack/email
  • Use the same credentials for multiple apps
  • Hardcode credentials in source code
  • Leave test credentials in production
  • Share your refresh token

Setting Up in Vercel (Production)

When deploying to Vercel:

  1. Go to your Vercel project dashboard
  2. Click "Settings" β†’ "Environment Variables"
  3. Add each variable:
    • Name: NEXT_PUBLIC_SUPABASE_URL
    • Value: Your value
    • Environment: Production (and Preview if needed)
  4. Click "Save"
  5. Repeat for all variables
  6. Redeploy your application

Production-specific notes:

  • Update GMAIL_REDIRECT_URI to production URL
  • Add production redirect URI to Google Cloud Console
  • Use secure, rotated credentials
  • Never use development credentials in production

Quick Reference

Variable Where to Get It Required
NEXT_PUBLIC_SUPABASE_URL Supabase Dashboard β†’ Settings β†’ API βœ…
NEXT_PUBLIC_SUPABASE_ANON_KEY Supabase Dashboard β†’ Settings β†’ API βœ…
GMAIL_CLIENT_ID Google Cloud β†’ APIs & Services β†’ Credentials βœ…
GMAIL_CLIENT_SECRET Google Cloud β†’ APIs & Services β†’ Credentials βœ…
GMAIL_REDIRECT_URI Manual entry (callback URL) βœ…
GMAIL_REFRESH_TOKEN OAuth Playground or helper script βœ…
GMAIL_USER Your Gmail address βœ…
NEXT_PUBLIC_POSTHOG_KEY PostHog Dashboard β†’ Settings β†’ Project βœ…
NEXT_PUBLIC_POSTHOG_HOST PostHog Dashboard (usually https://us.posthog.com) βœ…
DATABASE_URL Supabase Dashboard β†’ Settings β†’ Database βšͺ
NEXT_PUBLIC_APP_URL Your app URL βšͺ

Need Help?

Official Documentation:

Common Issues:

  • Check the Troubleshooting section above
  • Review error messages carefully
  • Verify all values are correct
  • Try test scripts to isolate the issue

Support:


Last Updated: January 2026
Version: 1.0.0

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published