@better-zap/hono 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -75,7 +75,7 @@ async function runPluginStatusHooks(options) {
75
75
  async function handleListConversations(c) {
76
76
  try {
77
77
  const conversations = await c.get("store").getConversations();
78
- return c.json(conversations);
78
+ return c.json((0, better_zap.normalizeConversationRecords)(conversations));
79
79
  } catch (error) {
80
80
  c.get("logger").error("conversations.list_error", (0, better_zap.serializeError)(error));
81
81
  return c.json({ error: "Internal error fetching conversations" }, 500);
@@ -89,7 +89,7 @@ async function handleGetConversation(c) {
89
89
  const normalized = (0, better_zap.formatPhone)(decodeURIComponent(phone));
90
90
  const conversation = await store.getConversationByPhone(normalized);
91
91
  if (!conversation) return c.json({ error: "Conversation not found" }, 404);
92
- return c.json(conversation);
92
+ return c.json((0, better_zap.normalizeConversationRecord)(conversation));
93
93
  } catch (error) {
94
94
  c.get("logger").error("conversations.get_error", (0, better_zap.serializeError)(error));
95
95
  return c.json({ error: "Internal error fetching conversation" }, 500);
@@ -115,6 +115,9 @@ async function handleGetMessages(c) {
115
115
  }
116
116
  //#endregion
117
117
  //#region src/handler/send.ts
118
+ function getSendResponseStatus(result) {
119
+ return result.success ? 200 : result.httpStatus ?? 500;
120
+ }
118
121
  async function handleSendText(c) {
119
122
  const { to, body, messageType, userId, metadata } = await c.req.json();
120
123
  if (!to || !body) return c.json({ error: "to and body are required" }, 400);
@@ -125,7 +128,7 @@ async function handleSendText(c) {
125
128
  metadata
126
129
  } : void 0;
127
130
  const result = await whatsapp.sendText(to, body, logging);
128
- return c.json(result, result.success ? 200 : 500);
131
+ return c.json(result, getSendResponseStatus(result));
129
132
  }
130
133
  function createSendTemplateHandler(templates) {
131
134
  return async function handleSendTemplate(c) {
@@ -155,7 +158,7 @@ function createSendTemplateHandler(templates) {
155
158
  }
156
159
  }
157
160
  const result = await whatsapp.sendTemplate(body.to, body.template, language, components, logging);
158
- return c.json(result, result.success ? 200 : 500);
161
+ return c.json(result, getSendResponseStatus(result));
159
162
  };
160
163
  }
161
164
  async function handleSendInteractive(c) {
@@ -170,7 +173,7 @@ async function handleSendInteractive(c) {
170
173
  if (type === "list") {
171
174
  if (!buttonLabel || !sections) return c.json({ error: "buttonLabel and sections are required for list type" }, 400);
172
175
  const result = await whatsapp.sendInteractiveList(to, body, buttonLabel, sections, logging);
173
- return c.json(result, result.success ? 200 : 500);
176
+ return c.json(result, getSendResponseStatus(result));
174
177
  }
175
178
  if (type === "carousel") {
176
179
  if (!cards) return c.json({ error: "cards are required for carousel type" }, 400);
@@ -180,11 +183,11 @@ async function handleSendInteractive(c) {
180
183
  body,
181
184
  cards
182
185
  }, logging);
183
- return c.json(result, result.success ? 200 : 500);
186
+ return c.json(result, getSendResponseStatus(result));
184
187
  }
185
188
  if (!buttons) return c.json({ error: "buttons are required for button type" }, 400);
186
189
  const result = await whatsapp.sendInteractiveButtons(to, body, buttons, logging);
187
- return c.json(result, result.success ? 200 : 500);
190
+ return c.json(result, getSendResponseStatus(result));
188
191
  }
189
192
  async function handleSendLocation(c) {
190
193
  const { to, latitude, longitude, name, address, messageType, userId, metadata } = await c.req.json();
@@ -196,7 +199,7 @@ async function handleSendLocation(c) {
196
199
  metadata
197
200
  } : void 0;
198
201
  const result = await whatsapp.sendLocation(to, latitude, longitude, name, address, logging);
199
- return c.json(result, result.success ? 200 : 500);
202
+ return c.json(result, getSendResponseStatus(result));
200
203
  }
201
204
  //#endregion
202
205
  //#region src/webhook/signature-verification.ts
@@ -379,11 +382,14 @@ async function processIncomingMessage(message, contact, config, log) {
379
382
  return;
380
383
  }
381
384
  const content = getMessageContent(message);
385
+ const sentAt = /* @__PURE__ */ new Date(parseInt(message.timestamp, 10) * 1e3);
386
+ const normalizedSentAt = Number.isNaN(sentAt.getTime()) ? (/* @__PURE__ */ new Date()).toISOString() : sentAt.toISOString();
382
387
  const { id, type, text, from, timestamp, ...rawMetadata } = message;
383
388
  await config.logger.logIncoming({
384
389
  phone,
385
390
  waMessageId: message.id,
386
391
  content,
392
+ sentAt: normalizedSentAt,
387
393
  senderName: contact?.profile?.name,
388
394
  metadata: Object.keys(rawMetadata).length > 0 ? rawMetadata : void 0
389
395
  });
@@ -549,8 +555,11 @@ function betterZap(options) {
549
555
  reaction: (to, messageId, emoji) => whatsapp.sendReaction(to, messageId, emoji)
550
556
  },
551
557
  conversations: {
552
- list: () => database.whatsappLog.getConversations(),
553
- get: (phone) => database.whatsappLog.getConversationByPhone((0, better_zap.formatPhone)(phone)),
558
+ list: async () => (0, better_zap.normalizeConversationRecords)(await database.whatsappLog.getConversations()),
559
+ get: async (phone) => {
560
+ const conversation = await database.whatsappLog.getConversationByPhone((0, better_zap.formatPhone)(phone));
561
+ return conversation ? (0, better_zap.normalizeConversationRecord)(conversation) : null;
562
+ },
554
563
  messages: async (phone, opts) => {
555
564
  const conversation = await database.whatsappLog.getConversationByPhone((0, better_zap.formatPhone)(phone));
556
565
  if (!conversation) return [];
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Hono } from "hono";
2
- import { EMPTY_TEMPLATE_REGISTRY, MessageLoggerService, WhatsAppService, createLogger, formatPhone, hasConfiguredTemplates, serializeError, serializeTemplateFromRegistry } from "better-zap";
2
+ import { EMPTY_TEMPLATE_REGISTRY, MessageLoggerService, WhatsAppService, createLogger, formatPhone, hasConfiguredTemplates, normalizeConversationRecord, normalizeConversationRecords, serializeError, serializeTemplateFromRegistry } from "better-zap";
3
3
  //#region src/plugins/runtime.ts
4
4
  function initializePlugins(options) {
5
5
  let pluginContext = {};
@@ -74,7 +74,7 @@ async function runPluginStatusHooks(options) {
74
74
  async function handleListConversations(c) {
75
75
  try {
76
76
  const conversations = await c.get("store").getConversations();
77
- return c.json(conversations);
77
+ return c.json(normalizeConversationRecords(conversations));
78
78
  } catch (error) {
79
79
  c.get("logger").error("conversations.list_error", serializeError(error));
80
80
  return c.json({ error: "Internal error fetching conversations" }, 500);
@@ -88,7 +88,7 @@ async function handleGetConversation(c) {
88
88
  const normalized = formatPhone(decodeURIComponent(phone));
89
89
  const conversation = await store.getConversationByPhone(normalized);
90
90
  if (!conversation) return c.json({ error: "Conversation not found" }, 404);
91
- return c.json(conversation);
91
+ return c.json(normalizeConversationRecord(conversation));
92
92
  } catch (error) {
93
93
  c.get("logger").error("conversations.get_error", serializeError(error));
94
94
  return c.json({ error: "Internal error fetching conversation" }, 500);
@@ -114,6 +114,9 @@ async function handleGetMessages(c) {
114
114
  }
115
115
  //#endregion
116
116
  //#region src/handler/send.ts
117
+ function getSendResponseStatus(result) {
118
+ return result.success ? 200 : result.httpStatus ?? 500;
119
+ }
117
120
  async function handleSendText(c) {
118
121
  const { to, body, messageType, userId, metadata } = await c.req.json();
119
122
  if (!to || !body) return c.json({ error: "to and body are required" }, 400);
@@ -124,7 +127,7 @@ async function handleSendText(c) {
124
127
  metadata
125
128
  } : void 0;
126
129
  const result = await whatsapp.sendText(to, body, logging);
127
- return c.json(result, result.success ? 200 : 500);
130
+ return c.json(result, getSendResponseStatus(result));
128
131
  }
129
132
  function createSendTemplateHandler(templates) {
130
133
  return async function handleSendTemplate(c) {
@@ -154,7 +157,7 @@ function createSendTemplateHandler(templates) {
154
157
  }
155
158
  }
156
159
  const result = await whatsapp.sendTemplate(body.to, body.template, language, components, logging);
157
- return c.json(result, result.success ? 200 : 500);
160
+ return c.json(result, getSendResponseStatus(result));
158
161
  };
159
162
  }
160
163
  async function handleSendInteractive(c) {
@@ -169,7 +172,7 @@ async function handleSendInteractive(c) {
169
172
  if (type === "list") {
170
173
  if (!buttonLabel || !sections) return c.json({ error: "buttonLabel and sections are required for list type" }, 400);
171
174
  const result = await whatsapp.sendInteractiveList(to, body, buttonLabel, sections, logging);
172
- return c.json(result, result.success ? 200 : 500);
175
+ return c.json(result, getSendResponseStatus(result));
173
176
  }
174
177
  if (type === "carousel") {
175
178
  if (!cards) return c.json({ error: "cards are required for carousel type" }, 400);
@@ -179,11 +182,11 @@ async function handleSendInteractive(c) {
179
182
  body,
180
183
  cards
181
184
  }, logging);
182
- return c.json(result, result.success ? 200 : 500);
185
+ return c.json(result, getSendResponseStatus(result));
183
186
  }
184
187
  if (!buttons) return c.json({ error: "buttons are required for button type" }, 400);
185
188
  const result = await whatsapp.sendInteractiveButtons(to, body, buttons, logging);
186
- return c.json(result, result.success ? 200 : 500);
189
+ return c.json(result, getSendResponseStatus(result));
187
190
  }
188
191
  async function handleSendLocation(c) {
189
192
  const { to, latitude, longitude, name, address, messageType, userId, metadata } = await c.req.json();
@@ -195,7 +198,7 @@ async function handleSendLocation(c) {
195
198
  metadata
196
199
  } : void 0;
197
200
  const result = await whatsapp.sendLocation(to, latitude, longitude, name, address, logging);
198
- return c.json(result, result.success ? 200 : 500);
201
+ return c.json(result, getSendResponseStatus(result));
199
202
  }
200
203
  //#endregion
201
204
  //#region src/webhook/signature-verification.ts
@@ -378,11 +381,14 @@ async function processIncomingMessage(message, contact, config, log) {
378
381
  return;
379
382
  }
380
383
  const content = getMessageContent(message);
384
+ const sentAt = /* @__PURE__ */ new Date(parseInt(message.timestamp, 10) * 1e3);
385
+ const normalizedSentAt = Number.isNaN(sentAt.getTime()) ? (/* @__PURE__ */ new Date()).toISOString() : sentAt.toISOString();
381
386
  const { id, type, text, from, timestamp, ...rawMetadata } = message;
382
387
  await config.logger.logIncoming({
383
388
  phone,
384
389
  waMessageId: message.id,
385
390
  content,
391
+ sentAt: normalizedSentAt,
386
392
  senderName: contact?.profile?.name,
387
393
  metadata: Object.keys(rawMetadata).length > 0 ? rawMetadata : void 0
388
394
  });
@@ -548,8 +554,11 @@ function betterZap(options) {
548
554
  reaction: (to, messageId, emoji) => whatsapp.sendReaction(to, messageId, emoji)
549
555
  },
550
556
  conversations: {
551
- list: () => database.whatsappLog.getConversations(),
552
- get: (phone) => database.whatsappLog.getConversationByPhone(formatPhone(phone)),
557
+ list: async () => normalizeConversationRecords(await database.whatsappLog.getConversations()),
558
+ get: async (phone) => {
559
+ const conversation = await database.whatsappLog.getConversationByPhone(formatPhone(phone));
560
+ return conversation ? normalizeConversationRecord(conversation) : null;
561
+ },
553
562
  messages: async (phone, opts) => {
554
563
  const conversation = await database.whatsappLog.getConversationByPhone(formatPhone(phone));
555
564
  if (!conversation) return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-zap/hono",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Hono adapter and webhook runtime for Better Zap.",
5
5
  "license": "ISC",
6
6
  "type": "module",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "hono": "4.12.5",
31
- "better-zap": "0.0.1"
31
+ "better-zap": "0.0.2"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "hono": "4.12.5"