Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

codedpro/ai-chat-api-server

Repository files navigation

AI Chat API Server

A production-ready Node.js HTTP API server that powers an AI chat feature with conversation continuity and multiple tools including ping, weather, DNS lookup, and timezone support.

Features

  • AI-powered conversations using Google Gemini (gemini-2.0-flash-exp)
  • Conversation continuity - maintain context across multiple messages
  • Multiple tools for the AI to use:
    • Ping - Check if hosts are reachable with latency info
    • Weather - Get current weather for any city (via Open-Meteo API)
    • DNS - Look up DNS records for domains
    • DateTime - Get current time in any timezone
  • Result caching - tool results are cached in SQLite to reduce redundant requests
  • Rate limiting - configurable protection against API abuse
  • Security hardened - helmet.js headers, CORS configuration, input sanitization
  • Request logging - track all incoming requests with structured logging
  • SQLite database - persistent storage for conversations and cache
  • Docker support - easy containerized deployment
  • OpenAPI documentation - complete API specification
  • Unit tests - Jest-based test suite

Prerequisites

Setup

Local Development

  1. Clone the repository
git clone <repository-url>
cd ai-chat-api-server
  1. Install dependencies
npm install
  1. Configure environment variables
cp .env.example .env

Edit .env and add your Google AI API key:

GOOGLE_AI_API_KEY=your_api_key_here
  1. Start the server

Development mode (with hot reload):

npm run dev

Production mode:

npm run build
npm start

The server will start on http://localhost:3000 (or the port specified in .env).

Docker Deployment

  1. Build and run with Docker Compose
# Set your API key
export GOOGLE_AI_API_KEY=your_api_key_here
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
  1. Or build manually
docker build -t ai-chat-api .
docker run -p 3000:3000 -e GOOGLE_AI_API_KEY=your_key ai-chat-api

API Documentation

Health Check

GET /api/health

Response:

{
 "success": true,
 "data": { "status": "ok", "uptime": 123.45 }
}

Send Message

Send a message to the AI assistant and receive a response.

POST /api/chat/message
Content-Type: application/json

Request Body:

{
 "message": "What's the weather in Tokyo?",
 "conversationId": "optional-uuid-for-continuing-conversation"
}

Response:

{
 "success": true,
 "data": {
 "conversationId": "550e8400-e29b-41d4-a716-446655440000",
 "message": {
 "role": "assistant",
 "content": "The current weather in Tokyo is 18°C with clear skies...",
 "toolCalls": [
 {
 "name": "weather",
 "input": { "location": "Tokyo" },
 "result": {
 "success": true,
 "data": {
 "location": "Tokyo, Japan",
 "temperature": "18°C",
 "conditions": "Clear sky",
 "humidity": "65%"
 }
 }
 }
 ]
 }
 }
}

Get Conversation History

Retrieve the full history of a conversation.

GET /api/chat/conversations/:conversationId

Response:

{
 "success": true,
 "data": {
 "id": "550e8400-e29b-41d4-a716-446655440000",
 "messages": [
 {
 "id": 1,
 "role": "user",
 "content": "Hello!",
 "timestamp": 1702345678000
 },
 {
 "id": 2,
 "role": "assistant",
 "content": "Hello! How can I help you today?",
 "timestamp": 1702345679000
 }
 ],
 "createdAt": 1702345678000,
 "updatedAt": 1702345679000
 }
}

Error Responses

All errors follow a consistent format:

{
 "success": false,
 "error": {
 "code": "ERROR_CODE",
 "message": "Human-readable error message",
 "details": {}
 }
}

Error Codes:

Code HTTP Status Description
VALIDATION_ERROR 400 Invalid request body or parameters
NOT_FOUND 404 Resource not found
RATE_LIMITED 429 Too many requests
AI_SERVICE_ERROR 502 AI provider error
TOOL_EXECUTION_ERROR 500 Tool execution failed
INTERNAL_ERROR 500 Unexpected server error

Available Tools

The AI assistant has access to the following tools:

1. Ping Tool

Check if a host is reachable and get latency information.

Example prompts:

  • "Can you check if google.com is reachable?"
  • "Is 8.8.8.8 online?"
  • "Ping cloudflare.com for me"

Security: Only public hostnames/IPs are allowed. Private/internal addresses (localhost, 192.168.x.x, etc.) are blocked.

2. Weather Tool

Get current weather for any city using the free Open-Meteo API.

Example prompts:

  • "What's the weather in London?"
  • "How's the weather in New York?"
  • "Tell me the temperature in Tokyo"

3. DNS Tool

Look up DNS records for a domain.

Example prompts:

  • "What are the DNS records for google.com?"
  • "Look up the MX records for example.org"
  • "What's the IP address of github.com?"

Supported record types: A, AAAA, MX, TXT, NS, CNAME, SOA

4. DateTime Tool

Get current date/time in any timezone.

Example prompts:

  • "What time is it in Tokyo?"
  • "What's the current time in PST?"
  • "Tell me the date in London"

Supported formats: City names, timezone abbreviations (PST, EST, UTC), and IANA timezones (America/New_York)

Usage Examples

Start a new conversation

curl -X POST http://localhost:3000/api/chat/message \
 -H "Content-Type: application/json" \
 -d '{"message": "Hello! What can you do?"}'

Check the weather

curl -X POST http://localhost:3000/api/chat/message \
 -H "Content-Type: application/json" \
 -d '{"message": "What is the weather like in Paris?"}'

Check host reachability

curl -X POST http://localhost:3000/api/chat/message \
 -H "Content-Type: application/json" \
 -d '{"message": "Is github.com reachable?"}'

DNS lookup

curl -X POST http://localhost:3000/api/chat/message \
 -H "Content-Type: application/json" \
 -d '{"message": "What are the MX records for gmail.com?"}'

Get time in different timezone

curl -X POST http://localhost:3000/api/chat/message \
 -H "Content-Type: application/json" \
 -d '{"message": "What time is it in Sydney?"}'

Design Decisions

Technology Choices

  1. Express.js - Chosen for its maturity, extensive middleware ecosystem, and excellent TypeScript support.

  2. Google Gemini (gemini-1.5-flash) - Selected because:

    • Free tier available via Google AI Studio
    • Excellent function/tool calling support
    • Good documentation and SDK
  3. SQLite with better-sqlite3 - Perfect for this use case because:

    • Zero configuration (no external database server)
    • Single file storage (portable)
    • Synchronous API for simpler code
    • Sufficient performance for conversation storage and caching
  4. TypeScript - Provides type safety and better developer experience.

  5. Open-Meteo API - Free weather API with no API key required.

Architecture

  • Layered architecture: Routes → Controllers → Services → Database
  • Tool registry pattern: Easily extensible for adding new tools
  • Caching layer: Tool results are cached (default 5 minutes) to reduce external requests
  • Conversation persistence: Full conversation history stored for context
  • Rate limiting: Protects API from abuse (60 req/min general, 20 req/min for chat)

Security Considerations

  • Input validation: All API inputs are validated using Zod schemas
  • Command injection prevention: Ping/DNS tools validate inputs using strict regex patterns
  • Private IP blocking: Internal network addresses are blocked from ping tool
  • Rate limiting: Prevents API abuse
  • No sensitive data in responses: Error messages don't leak internal details
  • Non-root Docker user: Container runs as non-privileged user

Rate Limits

Endpoint Limit
General API 60 requests/minute
Chat messages 20 requests/minute

Project Structure

ai-chat-api-server/
├── src/
│ ├── index.ts # Entry point
│ ├── config/
│ │ └── index.ts # Environment configuration
│ ├── routes/
│ │ ├── index.ts # Route aggregator
│ │ └── chat.routes.ts # Chat endpoints
│ ├── controllers/
│ │ └── chat.controller.ts # Request handlers
│ ├── services/
│ │ ├── chat.service.ts # AI/chat logic
│ │ └── cache.service.ts # Caching layer
│ ├── tools/
│ │ ├── index.ts # Tool registry
│ │ ├── ping.tool.ts # Ping implementation
│ │ ├── weather.tool.ts # Weather lookup
│ │ ├── dns.tool.ts # DNS lookup
│ │ └── datetime.tool.ts # Timezone/datetime
│ ├── db/
│ │ ├── index.ts # Database connection
│ │ └── schema.ts # Table definitions
│ ├── types/
│ │ └── index.ts # TypeScript types
│ ├── middleware/
│ │ ├── error.middleware.ts # Global error handler
│ │ ├── rate-limit.middleware.ts # Rate limiting
│ │ ├── request-logger.middleware.ts
│ │ └── validation.middleware.ts
│ └── utils/
│ ├── logger.ts
│ ├── errors.ts # Custom error classes
│ └── sanitize.ts # Input sanitization
├── data/ # SQLite database (created at runtime)
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
├── .env.example
├── .gitignore
├── package.json
├── tsconfig.json
└── README.md

Testing

Run the test suite:

# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage report
npm run test:coverage

OpenAPI Documentation

Full API documentation is available in openapi.yaml. You can view it using:

  • Swagger Editor - Paste the contents of openapi.yaml
  • Redoc - For beautiful documentation rendering

Security Features

This server implements multiple security measures:

  • Helmet.js - Adds security HTTP headers (CSP, X-Frame-Options, etc.)
  • CORS - Configurable cross-origin resource sharing
  • Rate Limiting - Prevents API abuse (configurable limits)
  • Input Sanitization - All inputs are sanitized before storage
  • Command Injection Prevention - Ping tool uses execFile() with strict validation
  • Private IP Blocking - Internal network addresses are blocked from ping tool
  • No Sensitive Data Leakage - Error messages don't expose internal details

License

MIT

About

Node.js HTTP API server for AI chat with conversation continuity and tool support (ping, weather, datetime, DNS). Built with Express, TypeScript, Google Gemini AI, and SQLite.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

AltStyle によって変換されたページ (->オリジナル) /