130 lines
4.3 KiB
TypeScript
130 lines
4.3 KiB
TypeScript
import type { IncomingMessage, ServerResponse } from 'http';
|
|
import { PORTS } from '../../utils/config';
|
|
import { getSetting } from '../../utils/store';
|
|
import type { HostApiContext } from '../context';
|
|
import { parseJsonBody, sendJson } from '../route-utils';
|
|
|
|
export async function handleGatewayRoutes(
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
url: URL,
|
|
ctx: HostApiContext,
|
|
): Promise<boolean> {
|
|
if (url.pathname === '/api/app/gateway-info' && req.method === 'GET') {
|
|
const status = ctx.gatewayManager.getStatus();
|
|
const token = await getSetting('gatewayToken');
|
|
const port = status.port || PORTS.OPENCLAW_GATEWAY;
|
|
sendJson(res, 200, {
|
|
wsUrl: `ws://127.0.0.1:${port}/ws`,
|
|
token,
|
|
port,
|
|
});
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/gateway/status' && req.method === 'GET') {
|
|
sendJson(res, 200, ctx.gatewayManager.getStatus());
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/gateway/health' && req.method === 'GET') {
|
|
const health = await ctx.gatewayManager.checkHealth();
|
|
sendJson(res, 200, health);
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/gateway/start' && req.method === 'POST') {
|
|
try {
|
|
await ctx.gatewayManager.start();
|
|
sendJson(res, 200, { success: true });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/gateway/stop' && req.method === 'POST') {
|
|
try {
|
|
await ctx.gatewayManager.stop();
|
|
sendJson(res, 200, { success: true });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/gateway/restart' && req.method === 'POST') {
|
|
try {
|
|
await ctx.gatewayManager.restart();
|
|
sendJson(res, 200, { success: true });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/gateway/control-ui' && req.method === 'GET') {
|
|
try {
|
|
const status = ctx.gatewayManager.getStatus();
|
|
const token = await getSetting('gatewayToken');
|
|
const port = status.port || PORTS.OPENCLAW_GATEWAY;
|
|
const urlValue = `http://127.0.0.1:${port}/?token=${encodeURIComponent(token)}`;
|
|
sendJson(res, 200, { success: true, url: urlValue, token, port });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/chat/send-with-media' && req.method === 'POST') {
|
|
try {
|
|
const body = await parseJsonBody<{
|
|
sessionKey: string;
|
|
message: string;
|
|
deliver?: boolean;
|
|
idempotencyKey: string;
|
|
media?: Array<{ filePath: string; mimeType: string; fileName: string }>;
|
|
}>(req);
|
|
const VISION_MIME_TYPES = new Set([
|
|
'image/png', 'image/jpeg', 'image/bmp', 'image/webp',
|
|
]);
|
|
const imageAttachments: Array<{ content: string; mimeType: string; fileName: string }> = [];
|
|
const fileReferences: string[] = [];
|
|
if (body.media && body.media.length > 0) {
|
|
const fsP = await import('node:fs/promises');
|
|
for (const m of body.media) {
|
|
fileReferences.push(`[media attached: ${m.filePath} (${m.mimeType}) | ${m.filePath}]`);
|
|
if (VISION_MIME_TYPES.has(m.mimeType)) {
|
|
const fileBuffer = await fsP.readFile(m.filePath);
|
|
imageAttachments.push({
|
|
content: fileBuffer.toString('base64'),
|
|
mimeType: m.mimeType,
|
|
fileName: m.fileName,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
const message = fileReferences.length > 0
|
|
? [body.message, ...fileReferences].filter(Boolean).join('\n')
|
|
: body.message;
|
|
const rpcParams: Record<string, unknown> = {
|
|
sessionKey: body.sessionKey,
|
|
message,
|
|
deliver: body.deliver ?? false,
|
|
idempotencyKey: body.idempotencyKey,
|
|
};
|
|
if (imageAttachments.length > 0) {
|
|
rpcParams.attachments = imageAttachments;
|
|
}
|
|
const result = await ctx.gatewayManager.rpc('chat.send', rpcParams, 120000);
|
|
sendJson(res, 200, { success: true, result });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|