- Introduction
- Currently Supported Providers
- Version
- Synopsis
- Installation
- Setup
- Usage
- FAQ
- Yahoo
- Troubleshooting
- TODO
- Contributing
- Authors
- License
oauth-helper
is multi-platform tool to obtain OAuth2 access tokens for
SMTP authentication. The tool is created to support OAuth2 authentication
for mailsend-go. At this time mailsend-go itself does not know anything
about obtaining access token for OAuth2. You just pass OAuth2 access token and
it will send email after authentication with OAuth2.
As email providers phase out password authentication in favor of OAuth2,
this tool simplifies the token acquisition process for mailsend-go users.
If you use mailsend-go for automated email sending, oauth-helper
eliminates the complexity of OAuth2 flows and provides ready-to-use tokens
for SMTP XOAUTH2 authentication.
- âś… Gmail/Google Workspace
- đźš§ Microsoft Outlook/Exchange (planned)
- đźš§ Yahoo Mail (planned)
You're welcome to contribute and send pull requests. As I do not use the other providers, it is unlikely I will have time to implement support for them.
Features
- Get initial OAuth2 tokens through interactive browser flow
- Refresh access tokens without browser interaction
- Validate token expiration and status
- Multiple output formats (text, JSON, environment variables)
- Cross-platform support (Windows, macOS, Linux)
- Automatic credential discovery from multiple sources
- Perfect integration with mailsend-go SMTP authentication
The current version is 1.0.1. It only supports gmail oAuth flow to acquire access token. Other providers like Microsoft, Yahoo etc. are TODO.
oauth-helper version 1.0.1
A tool to get OAuth2 access tokens for SMTP authentication
Usage:
oauth-helper <command> [options]
Commands:
get <provider> Get initial OAuth tokens (interactive)
refresh <provider> Refresh access token using refresh token
validate Validate an access token
version Show version information
help Show this help message
Providers:
gmail Google Gmail/Workspace
Examples:
# Get initial tokens for Gmail
oauth-helper get gmail --client-id "your_id" --client-secret "your_secret"
# Get tokens using credentials file
oauth-helper get gmail --credentials-file client_secret.json
# Refresh access token
oauth-helper refresh gmail --refresh-token "your_refresh_token"
# Validate access token
oauth-helper validate --token "your_access_token"
# Output as JSON
oauth-helper get gmail --output json
Global Options:
--output, --format Output format: text, json, env (default: text)
--verbose, -v Show verbose output
--help, -h Show help
Get Command Options:
--client-id OAuth client ID
--client-secret OAuth client secret
--credentials-file Path to credentials JSON file
Refresh Command Options:
--client-id OAuth client ID
--client-secret OAuth client secret
--credentials-file Path to credentials JSON file
--refresh-token, -r Refresh token
Validate Command Options:
--token, -t Access token to validate
--expires-at Unix timestamp when token expires
For detailed setup instructions, visit:
https://github.com/muquit/oauth-helper
git clone https://github.com/muquit/oauth-helper
cd oauth-helper
go build -o oauth-helper ./cmd/oauth-helper
or
make build
To cross-compile for various platforms download and install go-xbuild-go and type
cd oauth-helper
(cd cmd/oauth-helper; go-build-go)
or
make build_all
If you need to compile for one or more specific platform edit
cmd/oauth-helper/platforms.txt
and uncomment the platforms.
It can be compiled for more than 40 platforms.
Pre-build binaries from various platforms can be downloaded from Releases page.
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable Gmail API
- Create OAuth 2.0 credentials (Desktop application)
- Download the credentials JSON file
- Add your Gmail address as a test user in OAuth consent screen
Please look at smtp-oauth-setup-guide project for detail instruction on setting up OAuth authentication for SMTP email providers.
# Using credentials file
oauth-helper get gmail --credentials-file client_secret.json
# Using explicit credentials
oauth-helper get gmail --client-id "your_id" --client-secret "your_secret"
# Verbose output
oauth-helper get gmail --credentials-file client_secret.json --verbose
# With refresh token
oauth-helper refresh gmail --refresh-token "your_refresh_token"
# Prompt for refresh token
oauth-helper refresh gmail --credentials-file client_secret.json
# JSON output for scripts
oauth-helper refresh gmail -r "refresh_token" --output json
# Check token validity
oauth-helper validate --token "your_access_token"
# Check with expiration timestamp
oauth-helper validate --token "token" --expires-at 1642678234
# Get tokens
oauth-helper get gmail --credentials-file client_secret.json
# Use token with mailsend-go
mailsend-go -f you@gmail.com -t recipient@example.com \
-sub "Test Email" -use gmail \
auth -user you@gmail.com -oauth2 \
-token "your_access_token"
# Set token as environment variable
export SMTP_OAUTH_TOKEN="your_access_token"
# Send email without exposing token in command line
mailsend-go -f you@gmail.com -t recipient@example.com \
-sub "Test Email" -use gmail \
auth -user you@gmail.com -oauth2
#!/bin/bash
# daily-report.sh
# Refresh token and extract access token
ACCESS_TOKEN=$(oauth-helper refresh gmail -r "$GMAIL_REFRESH_TOKEN" --output json | jq -r '.access_token')
# Send daily report
mailsend-go -f reports@company.com -t team@company.com \
-sub "Daily Report $(date +%Y-%m-%d)" \
-use gmail \
auth -user reports@company.com -oauth2 -token "$ACCESS_TOKEN" \
attach -file daily-report.pdf
#!/bin/bash
# refresh-if-needed.sh
# Check if token is still valid
if ! oauth-helper validate --token "$SMTP_OAUTH_TOKEN" --expires-at "$TOKEN_EXPIRES_AT"; then
echo "Token expired, refreshing..."
NEW_TOKEN=$(oauth-helper refresh gmail -r "$GMAIL_REFRESH_TOKEN" --output json)
export SMTP_OAUTH_TOKEN=$(echo "$NEW_TOKEN" | jq -r '.access_token')
export TOKEN_EXPIRES_AT=$(echo "$NEW_TOKEN" | jq -r '.expires_at')
fi
# Send email with valid token
mailsend-go -f you@gmail.com -t recipient@example.com \
-sub "Automated Email" -use gmail \
auth -user you@gmail.com -oauth2
# refresh-token.ps1
# Refresh token and parse JSON
$tokenResponse = oauth-helper.exe refresh gmail -r $env:GMAIL_REFRESH_TOKEN --output json | ConvertFrom-Json
$env:SMTP_OAUTH_TOKEN = $tokenResponse.access_token
# Send email
& mailsend-go.exe -f "you@gmail.com" -t "recipient@example.com" `
-sub "Test from PowerShell" -use gmail `
auth -user "you@gmail.com" -oauth2
@echo off
REM get-token.bat
REM Get fresh access token
for /f "tokens=*" %%i in ('oauth-helper refresh gmail -r %GMAIL_REFRESH_TOKEN% --output json') do set TOKEN_JSON=%%i
REM Extract access token (requires jq or similar JSON parser)
for /f "tokens=*" %%i in ('echo %TOKEN_JSON% ^| jq -r .access_token') do set ACCESS_TOKEN=%%i
REM Send email
mailsend-go.exe f you@gmail.com -t recipient@example.com ^
-sub "Automated Email" -use gmail ^
auth -user you@gmail.com -oauth2 -token "%ACCESS_TOKEN%"
=== OAuth Tokens ===
Access Token: ya29.a0AfH6SMC...
Refresh Token: 1//04-rN5...
Token Type: Bearer
Expires In: 3599 seconds
Expires At: 2025-07-14 15:30:34 UTC
Usage with mailsend-go:
mailsend-go auth -oauth2 -token "ya29.a0AfH6SMC..." [other options]
Or using environment variable:
export SMTP_OAUTH_TOKEN="ya29.a0AfH6SMC..."
mailsend-go -f you@gmail.com -t recipient@example.com \
-sub "Test Email" -use gmail \
auth -user you@gmail.com -oauth2
{
"access_token": "ya29.a0AfH6SMC...",
"refresh_token": "1//04-rN5...",
"expires_in": 3599,
"token_type": "Bearer",
"scope": "https://mail.google.com/",
"issued_at": 1642674635,
"expires_at": 1642678234,
"expires_at_human": "2025-07-14 15:30:34 UTC"
}
export ACCESS_TOKEN="ya29.a0AfH6SMC..."
export REFRESH_TOKEN="1//04-rN5..."
export TOKEN_TYPE="Bearer"
export EXPIRES_IN=3599
export EXPIRES_AT=1642678234
export ISSUED_AT=1642674635
export SCOPE="https://mail.google.com/"
Q: Where do I get client_id and client_secret?
A: From Google Cloud Console. Create OAuth 2.0 credentials (Desktop application type) and download the JSON file.
Q: What's the difference between access token and refresh token?
A: Access tokens expire in 1 hour and are used for API calls. Refresh tokens are long-lived and used to get new access tokens.
Q: Why does my token expire every hour?
A: This is Google's security policy. Use the refresh token to get new access tokens without browser interaction.
Q: How do I handle token refresh in cron jobs?
A: Use the refresh command with JSON output to get new tokens programmatically. See automation examples above.
Q: Can I store tokens securely for automation?
A: Store refresh tokens as environment variables or in secure credential stores. Access tokens are temporary and can be regenerated.
Q: Why do I get "Access blocked" from Google?
A: Add your Gmail address as a test user in the OAuth consent screen. Your app must be in "Testing" mode for personal use.
Q: What if my refresh token stops working?
A: Refresh tokens can expire if unused for extended periods. Re-run the initial OAuth flow to get new tokens.
Q: I was using app passwords, why switch to OAuth?
A: Google is deprecating app passwords and "less secure app access" in favor of OAuth2 for better security.
Q: How is this better than the old bash scripts?
A: Single cross-platform binary, no dependencies on curl/jq, automatic credential discovery, and better error handling.
TODO
TODO
"Error 400: redirect_uri_mismatch"
- Ensure OAuth client is configured as "Desktop application"
- Verify redirect URI is set to
urn:ietf:wg:oauth:2.0:oob
"Access blocked: app has not completed verification"
- Add your Gmail address as test user in OAuth consent screen
- Keep app in "Testing" mode for personal use
"Invalid client" errors
- Check client_id and client_secret are correct
- Verify you're using the right Google Cloud project
"Token expired" errors
- Access tokens expire in 1 hour, use refresh token to get new ones
- Refresh tokens expire after 7 days of inactivity
"No valid credentials found"
- Use
--credentials-file
flag with full path - Check JSON file format and permissions
- Try explicit
--client-id
and--client-secret
flags
oauth-helper searches for credentials in this order:
- Command line flags (
--client-id
,--client-secret
) - Specified credentials file (
--credentials-file
) - Environment variables (
OAUTH_CLIENT_ID
,OAUTH_CLIENT_SECRET
) - Default file locations:
./client_secret.json
./credentials.json
./client_secret_*.json
~/.config/oauth-helper/credentials.json
~/.oauth-helper/credentials.json
If you were using manual OAuth flows or bash scripts:
Before:
# Multiple steps with bash scripts
./print_authorization_token_url.sh
# Manual browser interaction and file management
./get_tokens.sh
./get-oauth-token -r "refresh_token" -i "client_id" -s "client_secret"
After:
# Single command interactive flow
oauth-helper get gmail --credentials-file client_secret.json
# Simple refresh
oauth-helper refresh gmail -r "refresh_token"
- Web UI Interface: Planned web interface for easier OAuth setup where users can upload credentials JSON file or enter client_id/client_secret in a form, eliminating the need for command line interaction
- Microsoft Outlook/Exchange support
- Yahoo Mail support
- Token storage and management
- Configuration file support
Please send a pull request if you add features, fix bugs or update the documentation.
If you'd like to contribute to update documents, please do not update this
README.md rather update the individual markdown files in ./docs
directory.
This README.md
is assembled by markdown-toc-go
Developed with Claude AI 4 Sonnet, working under my guidance and instructions.
This project is licensed under the MIT License - see the LICENSE.txt file for details.
TOC is created by https://github.com/muquit/markdown-toc-go on Aug-23-2025