| name | evernote-multi-env-setup |
| description | Configure multi-environment setup for Evernote integrations.
Use when setting up dev, staging, and production environments,
or managing environment-specific configurations.
Trigger with phrases like "evernote environments", "evernote staging",
"evernote dev setup", "multiple environments evernote".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Evernote Multi-Environment Setup
Overview
Configure separate development, staging, and production environments for Evernote integrations with proper isolation and configuration management.
Prerequisites
- Multiple Evernote API keys (sandbox and production)
- Environment management infrastructure
- CI/CD pipeline
Environment Strategy
| Environment | Evernote Mode | Purpose | Users |
|---|
| Development | Sandbox | Local development | Developers |
| Staging | Sandbox | Integration testing | QA team |
| Production | Production | Live users | Customers |
Instructions
Step 1: Environment Configuration Files
project/
├── config/
│ ├── default.js
│ ├── development.js
│ ├── staging.js
│ └── production.js
├── .env.development
├── .env.staging
├── .env.production
└── .env.example
module.exports = {
evernote: {
requestTimeout: 30000,
connectionTimeout: 10000,
maxRetries: 3
},
cache: {
ttl: 300,
prefix: 'evernote:'
},
logging: {
redactTokens: true
}
};
module.exports = {
evernote: {
sandbox: true,
serviceHost: 'sandbox.evernote.com',
requestTimeout: 60000,
maxRetries: 1
},
cache: {
ttl: 60,
prefix: 'evernote:dev:'
},
logging: {
level: 'debug'
}
};
module.exports = {
evernote: {
sandbox: true,
serviceHost: 'sandbox.evernote.com',
requestTimeout: 30000,
maxRetries: 2
},
cache: {
ttl: 180,
prefix: 'evernote:staging:'
},
logging: {
level: 'info'
}
};
module.exports = {
evernote: {
sandbox: false,
serviceHost: 'www.evernote.com',
requestTimeout: 30000,
maxRetries: 3
},
cache: {
ttl: 300,
prefix: 'evernote:prod:'
},
logging: {
level: 'warn'
}
};
Step 2: Environment Variables
NODE_ENV=development
EVERNOTE_CONSUMER_KEY=
EVERNOTE_CONSUMER_SECRET=
EVERNOTE_SANDBOX=true
APP_URL=http://localhost:3000
SESSION_SECRET=change-this-secret
DATABASE_URL=
REDIS_URL=
NODE_ENV=development
EVERNOTE_CONSUMER_KEY=your-sandbox-key
EVERNOTE_CONSUMER_SECRET=your-sandbox-secret
EVERNOTE_SANDBOX=true
APP_URL=http://localhost:3000
SESSION_SECRET=dev-secret-not-secure
DATABASE_URL=postgresql://localhost:5432/evernote_dev
REDIS_URL=redis://localhost:6379/0
NODE_ENV=staging
EVERNOTE_CONSUMER_KEY=your-sandbox-key
EVERNOTE_CONSUMER_SECRET=your-sandbox-secret
EVERNOTE_SANDBOX=true
APP_URL=https://staging.yourapp.com
NODE_ENV=production
EVERNOTE_SANDBOX=false
APP_URL=https://yourapp.com
Step 3: Configuration Loader
const path = require('path');
const deepMerge = require('lodash.merge');
class ConfigLoader {
constructor() {
this.env = process.env.NODE_ENV || 'development';
this.config = this.loadConfig();
}
loadConfig() {
const defaultConfig = require('./default');
let envConfig = {};
try {
envConfig = require(`./${this.env}`);
} catch (error) {
console.warn(`No config file for environment: ${this.env}`);
}
const merged = deepMerge({}, defaultConfig, envConfig);
return this.applyEnvOverrides(merged);
}
applyEnvOverrides(config) {
(process..) {
config.. = process..;
}
(process..) {
config.. = process..;
}
(process.. !== ) {
config.. = process.. === ;
}
(process..) {
config. = config. || {};
config.. = process..;
}
(process..) {
config. = config. || {};
config.. = process..;
}
(process..) {
config. = config. || {};
config.. = process..;
}
config;
}
() {
keys = key.();
value = .;
( k keys) {
(value === ) ;
value = value[k];
}
value;
}
() {
.;
}
() {
. === ;
}
() {
. === ;
}
() {
. === ;
}
}
. = ();
Step 4: Environment-Aware Client Factory
const Evernote = require('evernote');
const config = require('../config');
class EvernoteClientFactory {
static createOAuthClient() {
return new Evernote.Client({
consumerKey: config.get('evernote.consumerKey'),
consumerSecret: config.get('evernote.consumerSecret'),
sandbox: config.get('evernote.sandbox'),
china: false
});
}
static createAuthenticatedClient(accessToken) {
return new Evernote.Client({
token: accessToken,
sandbox: config.get('evernote.sandbox')
});
}
static getEnvironmentInfo() {
return {
environment: process.env.NODE_ENV,
sandbox: config.get('evernote.sandbox'),
serviceHost: config.()
?
:
};
}
() {
errors = [];
(!config.()) {
errors.();
}
(!config.()) {
errors.();
}
(config.() && config.()) {
errors.();
}
{
: errors. === ,
errors
};
}
}
. = ;
Step 5: Docker Compose for Local Development
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
- NODE_ENV=development
env_file:
- .env.development
depends_on:
- postgres
- redis
postgres:
image: postgres:15-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: evernote_dev
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Step 6: Environment-Specific Middleware
const config = require('../config');
function environmentMiddleware(req, res, next) {
req.environment = {
name: process.env.NODE_ENV,
sandbox: config.get('evernote.sandbox'),
isProduction: config.isProduction()
};
if (config.isDevelopment()) {
res.setHeader('X-Environment', 'development');
res.setHeader('X-Evernote-Mode', 'sandbox');
}
if (config.isProduction()) {
if (req.protocol !== 'https') {
return res.redirect(301, `https://${req.hostname}${req.url}`);
}
}
next();
}
function requireProduction(req, res, next) {
if (!config.isProduction()) {
return res.status().({
:
});
}
();
}
() {
(config.()) {
res.().({
:
});
}
();
}
. = {
environmentMiddleware,
requireProduction,
blockInProduction
};
Step 7: CI/CD Environment Configuration
name: Deploy
on:
push:
branches: [main, develop]
jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- branch: develop
environment: staging
evernote_sandbox: 'true'
- branch: main
environment: production
evernote_sandbox: 'false'
steps:
- uses: actions/checkout@v4
- name: Set environment
if: github.ref == format('refs/heads/{0}', matrix.branch)
run: echo "DEPLOY_ENV=${{ matrix.environment }}" >> $GITHUB_ENV
- name: Deploy to ${{ matrix.environment }}
Step 8: Environment Health Check
const config = require('../config');
const EvernoteClientFactory = require('../services/evernote-factory');
router.get('/health/environment', async (req, res) => {
const envInfo = EvernoteClientFactory.getEnvironmentInfo();
const validation = EvernoteClientFactory.validateEnvironment();
res.json({
status: validation.valid ? 'ok' : 'error',
environment: {
...envInfo,
nodeEnv: process.env.NODE_ENV,
version: process.env.APP_VERSION || 'unknown'
},
validation,
checks: {
database: await checkDatabase(),
redis: await checkRedis(),
evernote: await checkEvernoteConnectivity()
}
});
});
async function checkEvernoteConnectivity() {
try {
const https = require();
host = config.()
?
: ;
( {
req = https.(, { : }, {
({ : , host });
});
req.(, {
({ : , host, : });
});
req.(, {
req.();
({ : , host, : });
});
});
} (error) {
{ : , : error. };
}
}
Output
- Environment-specific configuration files
- Configuration loader with environment variable support
- Environment-aware client factory
- Docker Compose for local development
- CI/CD environment configuration
- Health check endpoints
Environment Checklist
## Per-Environment Checklist
### Development
- [ ] Sandbox credentials configured
- [ ] Local database running
- [ ] Redis cache running
- [ ] Debug logging enabled
### Staging
- [ ] Sandbox credentials (separate from dev)
- [ ] Staging database provisioned
- [ ] Staging Redis provisioned
- [ ] Monitoring configured
### Production
- [ ] Production API key approved
- [ ] Secrets in secure storage
- [ ] Production database provisioned
- [ ] Production Redis provisioned
- [ ] Monitoring and alerting
- [ ] Backup procedures
Resources
Next Steps
For observability setup, see evernote-observability.