Files
wajs-server/src/server/routes/wa_route.ts
bipproduction c2bd7cd2d7 tambahan
2025-11-03 21:33:01 +08:00

157 lines
4.9 KiB
TypeScript

import Elysia, { t, type Context } from "elysia";
import { startClient, getState } from "../lib/wa/wa_service";
import _ from "lodash";
import mime from "mime-types";
import { MessageMedia } from "whatsapp-web.js";
const WaRoute = new Elysia({
prefix: "/wa",
tags: ["WhatsApp"]
})
.post("/start", async () => {
startClient();
return {
message: "WhatsApp route started",
};
})
.get("/qr", () => {
const state = getState();
return {
qr: state.qr,
};
})
.get("/ready", () => {
const state = getState();
return {
ready: state.ready,
};
})
.post("/restart", async () => {
getState().restart();
return {
message: "WhatsApp route restarted",
};
})
.post("/force-start", async () => {
getState().forceStart();
return {
message: "WhatsApp route force started",
};
})
.post("/stop", async () => {
getState().stop();
return {
message: "WhatsApp route stopped",
};
})
.get("/state", () => {
const state = getState();
return {
state: _.omit(state, "client"),
};
})
.post("send-text", async ({ body }) => {
const state = getState();
if (!state.ready) {
return {
message: "WhatsApp route not ready",
};
}
const client = state.client;
if (!client) {
return {
message: "WhatsApp client not ready",
};
}
const chat = await client.getChatById(`${body.number}@c.us`);
await chat.sendMessage(body.text);
return {
message: "WhatsApp route ready",
};
}, {
body: t.Object({
number: t.String(),
text: t.String(),
}),
detail: {
description: "Send text to WhatsApp",
tags: ["WhatsApp"],
}
})
.post(
"/send-media",
async ({ body }) => {
const state = getState();
if (!state.ready)
return { message: "WhatsApp route not ready" };
const client = state.client;
if (!client)
return { message: "WhatsApp client not ready" };
try {
const { number, caption, media } = body;
const jid = `${number}@c.us`;
// Siapkan data media
const { data, filename, mimetype } = media;
const mimeType = mimetype || mime.lookup(filename) || "application/octet-stream";
const fileName = filename || `file.${mime.extension(mimeType) || "bin"}`;
const waMedia = new MessageMedia(mimeType, data, fileName);
// Tentukan opsi pengiriman otomatis
const sendOptions: any = { caption };
if (mimeType.startsWith("audio/")) {
// kirim voice note jika ogg/opus
sendOptions.sendAudioAsVoice =
mimeType.includes("ogg") || mimeType.includes("opus");
} else if (
!mimeType.startsWith("image/") &&
!mimeType.startsWith("video/")
) {
// selain gambar/video kirim sebagai dokumen
sendOptions.sendMediaAsDocument = true;
}
await client.sendMessage(jid, waMedia, sendOptions);
return {
success: true,
message: `✅ Media sent to ${number}`,
info: { filename: fileName, mimetype: mimeType },
};
} catch (err: any) {
console.error("Send media error:", err);
return {
success: false,
message: "❌ Failed to send media",
error: err.message,
};
}
},
{
body: t.Object({
number: t.String({ minLength: 10, maxLength: 15, examples: ["6281234567890"] }),
caption: t.Optional(t.String({ maxLength: 255, examples: ["Hello World"] })),
media: t.Object({
data: t.String({ examples: ["iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII="] }), // base64 tanpa prefix
filename: t.String({ minLength: 1, maxLength: 255, examples: ["file.png"] }),
mimetype: t.String({ minLength: 1, maxLength: 255, examples: ["image/png"] }),
}),
}),
detail: {
summary: "Send media to WhatsApp",
description:
"Send media (image, audio, video, PDF, or any file) to WhatsApp"
},
}
);
export default WaRoute;