Query your own database for real customer context, then generate intelligent replies using your own AI API key. Full control. Your credentials. Your data — never shared.
From incoming message to intelligent, data-driven reply
Your database credentials and AI keys never touch AutoReply Mate servers
AI sees real customer data — orders, history, status — before generating a reply
Any database, any AI model, any business logic — you control everything
Configure all credentials once in a .env
file — never hardcode them
Create this file in your project root. Add it to
.gitignore immediately.
# ── AutoReply Mate ──────────────────────────────
API_KEY=your-secret-key-here # same key you set in the app
# ── Database: MySQL / PostgreSQL ─────────────────
DB_HOST=localhost
DB_PORT=3306
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_NAME=your_database
# ── Database: MongoDB (alternative) ─────────────
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/dbname
DB_NAME=autoreply
# ── AI API Keys (use only what you need) ─────────
OPENAI_API_KEY=sk-proj-...
ANTHROPIC_API_KEY=sk-ant-api03-...
Install the packages for your chosen stack.
# MySQL + OpenAI
npm install express dotenv mysql2 openai
# PostgreSQL + OpenAI
npm install express dotenv pg openai
# MongoDB + OpenAI
npm install express dotenv mongodb openai
# Swap OpenAI for Claude
npm install @anthropic-ai/sdk
# PostgreSQL + Claude
pip install fastapi uvicorn asyncpg anthropic python-dotenv
# MySQL + OpenAI
pip install fastapi uvicorn aiomysql openai python-dotenv
Choose your stack and copy the full ready-to-run implementation
Looks up the customer in your MySQL database, then generates a context-aware reply with GPT-4
require('dotenv').config();
const express = require('express');
const mysql = require('mysql2/promise');
const OpenAI = require('openai');
const app = express();
app.use(express.json());
// Persistent connection pool — created once, reused for every request
const db = mysql.createPool({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10
});
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const API_KEY = process.env.API_KEY;
app.post('/api/autoreply', async (req, res) => {
// ── 1. Verify AutoReply Mate API key ─────────────────────────────────────
if (req.headers['x-api-key'] !== API_KEY) {
return res.status(403).json({ error: 'Forbidden', status: 'forbidden' });
}
const { type, sender, name, message } = req.body;
try {
// ── 2. Query YOUR database for customer context ───────────────────────
const [rows] = await db.query(
'SELECT id, name, status, membership FROM customers WHERE phone = ? LIMIT 1',
[sender]
);
let dbContext = 'No customer record found for this phone number.';
if (rows.length > 0) {
const customer = rows[0];
// Fetch the last 3 orders for this customer
const [orders] = await db.query(
`SELECT order_id, status, total
FROM orders
WHERE customer_id = ?
ORDER BY created_at DESC
LIMIT 3`,
[customer.id]
);
const orderLines = orders.length > 0
? orders.map(o => ` - Order #${o.order_id}: ${o.status} (${o.total} RON)`).join('\n')
: ' No recent orders.';
dbContext =
`Customer : ${customer.name}\n` +
`Status : ${customer.status}\n` +
`Membership: ${customer.membership}\n` +
`Recent orders:\n${orderLines}`;
}
// ── 3. Generate AI reply with YOUR OpenAI key ─────────────────────────
const completion = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content:
'You are a helpful customer support agent.\n' +
'Reply in maximum 2 short sentences. Be friendly and specific.\n\n' +
'Customer data from the database:\n' + dbContext
},
{ role: 'user', content: message }
],
max_tokens: 150,
temperature: 0.7
});
const reply = completion.choices[0].message.content;
console.log(`[${type}] Reply to ${sender}: ${reply}`);
res.json({ text: reply, status: 'success' });
} catch (err) {
console.error('Error:', err.message);
res.json({ text: "We'll get back to you shortly!", status: 'success' });
}
});
app.listen(process.env.PORT || 3000, () => console.log('Server started'));
.env file with DB and
OpenAI credentialsnpm install express dotenv mysql2
openainode server.jshttps://your-domain.com/api/autoreplyAsync PostgreSQL queries with Anthropic Claude for natural, context-aware replies
import os
from fastapi import FastAPI, Header, HTTPException
from anthropic import Anthropic
from pydantic import BaseModel
import asyncpg
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
anthropic_client = Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))
API_KEY = os.getenv('API_KEY')
class IncomingMessage(BaseModel):
type: str
sender: str
name: str = None
message: str
timestamp: str
async def fetch_customer_context(phone: str) -> str:
"""Query YOUR PostgreSQL database for customer and order data."""
conn = await asyncpg.connect(
host=os.getenv('DB_HOST'),
port=int(os.getenv('DB_PORT', '5432')),
user=os.getenv('DB_USER'),
password=os.getenv('DB_PASSWORD'),
database=os.getenv('DB_NAME')
)
try:
# Look up customer by phone number
customer = await conn.fetchrow(
'SELECT id, name, status, membership FROM customers WHERE phone = $1',
phone
)
if not customer:
return 'No customer record found for this phone number.'
# Fetch last 3 orders
orders = await conn.fetch(
'''SELECT order_id, status, total
FROM orders
WHERE customer_id = $1
ORDER BY created_at DESC
LIMIT 3''',
customer['id']
)
order_lines = '\n'.join(
f" - Order #{o['order_id']}: {o['status']} ({o['total']} RON)"
for o in orders
) or ' No recent orders.'
return (
f"Customer : {customer['name']}\n"
f"Status : {customer['status']}\n"
f"Membership: {customer['membership']}\n"
f"Recent orders:\n{order_lines}"
)
finally:
await conn.close()
@app.post('/api/autoreply')
async def handle_message(data: IncomingMessage, x_api_key: str = Header(None)):
# ── 1. Verify AutoReply Mate API key ─────────────────────────────────
if x_api_key != API_KEY:
raise HTTPException(status_code=403, detail='Invalid API key')
# ── 2. Pull context from YOUR database ───────────────────────────────
db_context = await fetch_customer_context(data.sender)
print(f'[{data.type}] From {data.sender}: {data.message}')
print(f'DB context: {db_context}')
# ── 3. Generate reply with YOUR Claude key ────────────────────────────
try:
response = anthropic_client.messages.create(
model='claude-3-5-sonnet-20241022',
max_tokens=150,
system=(
'You are a helpful customer support agent.\n'
'Reply in maximum 2 short sentences. Be friendly and specific.\n\n'
'Customer data from the database:\n' + db_context
),
messages=[{'role': 'user', 'content': data.message}]
)
reply = response.content[0].text
print(f'Reply: {reply}')
return {'text': reply, 'status': 'success'}
except Exception as e:
print(f'AI Error: {e}')
return {'text': "We'll respond shortly!", 'status': 'success'}
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host='0.0.0.0', port=8000)
.env with PostgreSQL and
Anthropic credentialspip install fastapi uvicorn asyncpg anthropic
python-dotenvuvicorn main:app --host 0.0.0.0 --port
8000https://your-domain.com/api/autoreplyFlexible NoSQL documents with optional conversation logging built in
require('dotenv').config();
const express = require('express');
const { MongoClient } = require('mongodb');
const OpenAI = require('openai');
const app = express();
app.use(express.json());
const mongoClient = new MongoClient(process.env.MONGODB_URI);
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const API_KEY = process.env.API_KEY;
let db;
// Connect to YOUR MongoDB on startup
mongoClient.connect()
.then(client => {
db = client.db(process.env.DB_NAME || 'autoreply');
console.log('MongoDB connected');
})
.catch(err => {
console.error('MongoDB connection error:', err);
process.exit(1);
});
app.post('/api/autoreply', async (req, res) => {
// ── 1. Verify AutoReply Mate API key ─────────────────────────────────────
if (req.headers['x-api-key'] !== API_KEY) {
return res.status(403).json({ error: 'Forbidden', status: 'forbidden' });
}
const { type, sender, name, message } = req.body;
try {
// ── 2. Query YOUR MongoDB for customer context ────────────────────────
const customer = await db.collection('customers').findOne({ phone: sender });
let dbContext = 'No customer record found for this phone number.';
if (customer) {
const orders = await db.collection('orders')
.find({ customerId: customer._id })
.sort({ createdAt: -1 })
.limit(3)
.toArray();
const orderLines = orders.length > 0
? orders.map(o => ` - Order #${o.orderId}: ${o.status} (${o.total} RON)`).join('\n')
: ' No recent orders.';
dbContext =
`Customer : ${customer.name}\n` +
`Status : ${customer.status}\n` +
`Plan : ${customer.plan}\n` +
`Notes : ${customer.notes || 'None'}\n` +
`Recent orders:\n${orderLines}`;
}
// ── 3. Generate AI reply with YOUR OpenAI key ─────────────────────────
const completion = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content:
'You are a helpful customer support agent.\n' +
'Reply in maximum 2 short sentences. Be friendly and specific.\n\n' +
'Customer data from the database:\n' + dbContext
},
{ role: 'user', content: message }
],
max_tokens: 150,
temperature: 0.7
});
const reply = completion.choices[0].message.content;
console.log(`[${type}] Reply to ${sender}: ${reply}`);
// ── 4. Log conversation to MongoDB (optional) ─────────────────────────
await db.collection('conversations').insertOne({
phone: sender,
messageIn: message,
messageOut: reply,
type,
createdAt: new Date()
});
res.json({ text: reply, status: 'success' });
} catch (err) {
console.error('Error:', err.message);
res.json({ text: "We'll get back to you shortly!", status: 'success' });
}
});
app.listen(process.env.PORT || 3000, () => console.log('Server started'));
MONGODB_URI and
OPENAI_API_KEY in your
.envnpm install express dotenv mongodb
openainode server.jsSample tables to get your database ready in minutes
-- Customers table
CREATE TABLE customers (
id INT PRIMARY KEY AUTO_INCREMENT,
phone VARCHAR(20) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
email VARCHAR(100),
status VARCHAR(20) DEFAULT 'active',
membership VARCHAR(20) DEFAULT 'standard',
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Orders table
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(30) UNIQUE NOT NULL,
customer_id INT NOT NULL,
status VARCHAR(30) NOT NULL DEFAULT 'pending',
total DECIMAL(10,2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
-- Sample data
INSERT INTO customers (phone, name, email, membership) VALUES
('+40712345678', 'Ion Popescu', 'ion@example.com', 'premium'),
('+40723456789', 'Maria Ionescu', 'maria@example.com', 'standard');
INSERT INTO orders (order_id, customer_id, status, total) VALUES
('ORD-001', 1, 'delivered', 250.00),
('ORD-002', 1, 'processing', 180.50),
('ORD-003', 2, 'shipped', 95.00);
// db.customers
{
"_id": ObjectId("64ab1234..."),
"phone": "+40712345678",
"name": "Ion Popescu",
"email": "ion@example.com",
"status": "active",
"plan": "premium",
"notes": "VIP customer since 2024",
"createdAt": ISODate("2024-01-15")
}
// db.orders
{
"_id": ObjectId("64ac5678..."),
"orderId": "ORD-001",
"customerId": ObjectId("64ab1234..."),
"status": "delivered",
"total": 250.00,
"items": [
{ "name": "Product A", "qty": 2, "price": 125.00 }
],
"createdAt": ISODate("2026-02-20")
}
// db.conversations (auto-logged by the MongoDB example)
{
"_id": ObjectId("..."),
"phone": "+40712345678",
"messageIn": "Where is my order?",
"messageOut": "Your Order #ORD-001 was delivered on Feb 20.",
"type": "WHATSAPP",
"createdAt": ISODate("2026-02-28")
}
Protect your database and AI keys — non-negotiable in production
.env files or
hosting environment variables.env to .gitignore
before your first commit.env or config files
to GitX-API-Key check —
anyone could hit your endpoint# Credentials — NEVER commit these
.env
.env.local
.env.production
# Dependencies
node_modules/
__pycache__/
*.pyc
# OS
.DS_Store
Copy a code example, fill in your .env
credentials, deploy, and connect to AutoReply Mate