Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x 4x 2x 1x 6x 6x 6x 6x 6x 6x 6x 3x 3x 1x 7x 7x 7x 7x 7x 5x 5x 2x 3x 2x 1x 3x 3x 1x 4x 4x 4x 4x 4x 1x 3x | import { Hono } from "hono";
import type { Dal } from "../../../dal";
import { error, handleError, success } from "../../../lib/response";
import { parseRequiredId, requireUser } from "../../../lib/utils";
import { requireWhatsAppClient } from "../../../lib/whatsapp/client";
import type { Services } from "../../../services";
type Env = {
Bindings: CloudflareBindings;
Variables: {
user: { id: string; name: string; email: string } | null;
session: unknown;
dal: Dal;
services: Services;
};
};
const conversations = new Hono<Env>();
// GET / - List conversations
conversations.get("/", async (c) => {
try {
requireUser(c.get("user"));
const services = c.get("services");
const limit = Math.min(
100,
Math.max(1, Number(c.req.query("limit") || 50)),
);
const offset = Math.max(0, Number(c.req.query("offset") || 0));
const contactType = c.req.query("contactType");
const search = c.req.query("search");
const { conversations: items, total } =
await services.waConversation.listConversations(
{ contactType, search },
offset,
limit,
);
return success(c, { conversations: items, total, limit, offset });
} catch (err) {
return handleError(c, err);
}
});
// GET /:id - Get conversation detail with messages
conversations.get("/:id", async (c) => {
try {
requireUser(c.get("user"));
const services = c.get("services");
const id = parseRequiredId(c.req.param("id"), "conversation");
const limit = Math.min(
200,
Math.max(1, Number(c.req.query("limit") || 100)),
);
const offset = Math.max(0, Number(c.req.query("offset") || 0));
const result = await services.waConversation.getConversation(
id,
offset,
limit,
);
return success(c, result);
} catch (err) {
return handleError(c, err);
}
});
// POST /:id/reply - Reply to conversation
conversations.post("/:id/reply", async (c) => {
try {
const user = requireUser(c.get("user"));
const services = c.get("services");
const id = parseRequiredId(c.req.param("id"), "conversation");
const body = await c.req.json<{
message?: string;
templateName?: string;
language?: string;
components?: unknown[];
}>();
const client = requireWhatsAppClient(c.env);
let result: unknown;
if (body.templateName) {
result = await services.waConversation.replyWithTemplate(
id,
body.templateName,
body.language ?? "en",
body.components,
user.id,
client,
);
} else if (body.message) {
result = await services.waConversation.reply(
id,
body.message,
user.id,
client,
);
} else {
return error(
c,
"VALIDATION_ERROR",
"Either message or templateName is required",
400,
);
}
return success(c, { message: result });
} catch (err) {
return handleError(c, err);
}
});
// POST /:id/read - Mark conversation as read
conversations.post("/:id/read", async (c) => {
try {
requireUser(c.get("user"));
const dal = c.get("dal");
const id = parseRequiredId(c.req.param("id"), "conversation");
await dal.waConversations.resetUnread(id);
return success(c, { message: "Marked as read" });
} catch (err) {
return handleError(c, err);
}
});
export default conversations;
|