Core API Overview
Relevant source files
The following files were used as context for generating this wiki page:The @messagejs/core package is the backend API for the MessageJS platform. It is a Node.js/Express application responsible for handling all incoming requests from the client SDK, authenticating those requests, managing data persistence, and routing messages to the appropriate third-party messaging services. It serves as the central hub that connects user applications with various chat platforms like WhatsApp and Telegram.
The core architecture is designed to be secure and pluggable. It ensures that sensitive credentials for messaging platforms are never exposed to the frontend. The API manages projects, API keys, connectors, and message templates, providing a complete backend solution for the messaging service.
Sources: packages/core/package.json:5, README.md:19-21
Architecture
The Core API sits between the client-side SDK and the external messaging provider APIs. Its primary role is to receive a standardized request from the SDK, process it securely, and translate it into a provider-specific request.
Sources: README.md:50-52
High-Level Data Flow
The following diagram illustrates the general flow of a message request through the system.
This diagram shows a request originating from the Client SDK, being authenticated by the Core API, processed by a controller, and finally routed to the correct third-party service.
Sources: README.md:50, packages/core/src/api/middleware/authMiddleware.ts
Server Initialization
The API is an Express application initialized in packages/core/src/index.ts. It uses dotenv for environment variable management and sets up global middleware, such as express.json() for parsing request bodies. The server listens on a port defined by the PORT environment variable, defaulting to 3001.
Key dependencies for the core service include:
express: Web frameworkdotenv: Environment variable loading@prisma/client: Database ORMcors: Cross-Origin Resource Sharing middleware
Sources: packages/core/src/index.ts:9-20, packages/core/package.json:18-22
A simple health check endpoint is available at the root (/) to confirm the API is operational.
// packages/core/src/index.ts:25-31
app.get('/', (req: Request, res: Response) => {
res.status(200).json({
status: 'ok',
message: 'Welcome to the MessageJS Core API!',
});
});
Sources: packages/core/src/index.ts:25-31
API Endpoints and Routing
The Core API exposes a set of RESTful endpoints for managing resources. The primary route for sending messages is mounted at /api/v1/messages.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/messages | Queues a new message for sending. Authenticated via API Key. |
GET | /api/v1/messages | Lists message logs for a project. Authenticated via JWT. |
POST | /api/v1/projects | Creates a new project. |
GET | /api/v1/projects | Lists all projects for the authenticated user. |
POST | /api/v1/projects/:projectId/keys | Creates a new API key for a project. |
POST | /api/v1/projects/:projectId/connectors | Adds a new connector (e.g., WhatsApp) to a project. |
Sources: packages/core/src/index.ts:35, API_REFERENCE.md
Authentication and Authorization
The API uses two primary forms of authentication:
- API Keys: For requests from the client SDK to send messages.
- JWT (JSON Web Tokens): For users interacting with the dashboard API to manage projects, keys, and connectors.
Sources: API_REFERENCE.md:10, 52, packages/core/src/api/middleware/authMiddleware.ts
API Key Validation
The validateApiKey middleware is responsible for protecting the message-sending endpoint. It inspects the Authorization header for a Bearer token, which is expected to be the project's API key.
The validation process is as follows:
- Check for the presence of the
Authorizationheader. - Ensure the header is formatted as
Bearer <api_key>. - Extract the API key.
- (In a full implementation) Look up the key in the database to verify its existence, check if it's active, and retrieve its associated
projectId. - If valid, attach the key's details (
idandprojectId) to thereq.apiKeyobject for use in downstream controllers. - If invalid, return a
401or403error response.
Sources: packages/core/src/api/middleware/authMiddleware.ts:17-76, packages/core/src/types/security.ts:16-19
The following sequence diagram illustrates this flow.
Core Feature: Sending a Message
The main function of the API is to process and queue messages. This is handled by the sendMessage controller.
Sources: packages/core/src/api/controllers/messageController.ts:15-18
Request and Response
To send a message, the client must make a POST request to /api/v1/messages with a specific payload.
Request Body (SendMessageRequest)
| Field | Type | Description |
|---|---|---|
connectorId | string | The ID of the connector to use. |
templateId | string | The ID of the message template. |
to | string | The recipient's identifier (e.g., phone number). |
variables | Record<string, any> | Key-value pairs to populate the template. |
metadata | Record<string, any> (optional) | Extra data for logging. |
Sources: packages/core/src/types/apiTypes.ts:31-40
Upon successful validation and queuing, the API returns a 202 Accepted status code, indicating the message is queued for processing, not yet sent.
Success Response (SendMessageSuccessResponse)
| Field | Type | Description |
|---|---|---|
messageId | string | The unique ID for the message log entry. |
status | "queued" | The initial status of the message. |
externalId | `string | null` |
details | string | A human-readable confirmation message. |
Sources: packages/core/src/types/apiTypes.ts:46-52, packages/core/src/api/controllers/messageController.ts:61-66
Processing Logic
The sendMessage controller outlines a series of steps to process a request. The current implementation is a mock, but the planned logic is detailed in code comments.
This flowchart shows the intended robust, asynchronous processing of a message.
Sources: packages/core/src/api/controllers/messageController.ts:25-49
Data Models and Database Schema
The Core API uses Prisma as its ORM to interact with a PostgreSQL database. The schema defines the structure for all core entities in the system.
Sources: packages/core/prisma/schema.prisma:7-12, packages/core/package.json:19
Entity Relationship Diagram
The following diagram shows the relationships between the main database models.
This ER diagram illustrates that a USER has many PROJECTs. Each PROJECT contains its own SERVICEs (Connectors), TEMPLATEs, and MESSAGELOGs.
Sources: packages/core/prisma/schema.prisma:31-105
Key Data Models
The data models are defined in both schema.prisma and mirrored as TypeScript interfaces in packages/core/src/types/dataModels.ts.
Project Model
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier. |
name | string | User-defined name for the project. |
apiKey | string | The unique API key for this project. |
userId | string | Foreign key linking to the User model. |
Sources: packages/core/prisma/schema.prisma:52-59
Service (Connector) Model
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier. |
type | ServiceType | Enum (WHATSAPP, TELEGRAM, etc.). |
credentials | string | AES-256 encrypted credentials blob. |
projectId | string | Foreign key linking to the Project model. |
Sources: packages/core/prisma/schema.prisma:68-77, packages/core/src/types/dataModels.ts:58-65
MessageLog Model
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier. |
status | MessageStatus | Enum (QUEUED, SENT, FAILED, etc.). |
recipient | string | The destination address (e.g., phone number). |
externalMessageId | string? | The ID returned by the third-party provider. |
error | string? | Error message if the status is FAILED. |
projectId | string | Foreign key linking to the Project. |
serviceId | string | Foreign key linking to the Service used. |
Sources: packages/core/prisma/schema.prisma:87-105, packages/core/src/types/dataModels.ts:87-99
Summary
The MessageJS Core API is a well-structured Express application that serves as the engine of the platform. It provides a secure and scalable backend for sending messages through various providers. Its architecture relies on API key authentication for SDK requests, a clear separation of concerns with controllers and middleware, and a robust data model defined with Prisma. The asynchronous processing design ensures that the API can handle message requests efficiently without blocking, returning a 202 Accepted response to the client immediately.