@natyapp/meta 1.6.6 → 1.7.0

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.
Files changed (95) hide show
  1. package/.github/copilot-instructions.md +1540 -0
  2. package/README.md +513 -40
  3. package/dist/elements/index.d.ts +1 -0
  4. package/dist/elements/index.js +1 -0
  5. package/dist/elements/mediaTemplate.d.ts +45 -0
  6. package/dist/elements/mediaTemplate.js +47 -0
  7. package/dist/elements/textTemplate.d.ts +12 -1
  8. package/dist/elements/textTemplate.js +13 -6
  9. package/dist/index.d.ts +7 -2
  10. package/dist/index.js +11 -2
  11. package/dist/interfaces/IConnection.d.ts +2 -2
  12. package/dist/interfaces/ILog.d.ts +2 -2
  13. package/dist/interfaces/ILogger.d.ts +62 -0
  14. package/dist/interfaces/ILogger.js +2 -0
  15. package/dist/interfaces/ISdk.d.ts +4 -2
  16. package/dist/interfaces/IWebhook.d.ts +2 -2
  17. package/dist/interfaces/index.d.ts +1 -0
  18. package/dist/interfaces/index.js +1 -0
  19. package/dist/queue/messageQueue.d.ts +1 -1
  20. package/dist/queue/messageQueue.js +45 -0
  21. package/dist/routes/webhooks/methods/connection.js +78 -11
  22. package/dist/routes/webhooks/methods/messages.js +18 -3
  23. package/dist/services/axiosInstances.d.ts +14 -5
  24. package/dist/services/axiosInstances.js +111 -23
  25. package/dist/services/middlewares/validations.d.ts +2 -2
  26. package/dist/services/middlewares/validations.js +1 -2
  27. package/dist/services/mutations/connection.js +1 -1
  28. package/dist/services/mutations/logs.js +1 -1
  29. package/dist/services/mutations/messages.js +1 -1
  30. package/dist/services/mutations/validation.d.ts +1 -1
  31. package/dist/services/mutations/validation.js +1 -1
  32. package/dist/services/mutations/webhooks.js +1 -1
  33. package/dist/types/logs.d.ts +1 -1
  34. package/dist/types/requestTypes.d.ts +2 -0
  35. package/dist/useCases/connection/index.d.ts +9 -9
  36. package/dist/useCases/connection/index.js +156 -7
  37. package/dist/useCases/events/NatyEvents.d.ts +4 -2
  38. package/dist/useCases/events/NatyEvents.js +13 -1
  39. package/dist/useCases/log/index.d.ts +5 -5
  40. package/dist/useCases/log/index.js +65 -3
  41. package/dist/useCases/message/whatsappResponse.d.ts +48 -22
  42. package/dist/useCases/message/whatsappResponse.js +672 -105
  43. package/dist/useCases/messages/index.d.ts +5 -5
  44. package/dist/useCases/messages/index.js +66 -3
  45. package/dist/useCases/sdk/index.d.ts +8 -4
  46. package/dist/useCases/sdk/index.js +38 -6
  47. package/dist/useCases/webhook/index.d.ts +9 -9
  48. package/dist/useCases/webhook/index.js +154 -7
  49. package/dist/utils/consoleLogger.d.ts +20 -0
  50. package/dist/utils/consoleLogger.js +51 -0
  51. package/dist/utils/index.d.ts +6 -0
  52. package/dist/utils/index.js +6 -0
  53. package/dist/utils/loggerContext.d.ts +57 -0
  54. package/dist/utils/loggerContext.js +90 -0
  55. package/dist/utils/methodContext.d.ts +34 -0
  56. package/dist/utils/methodContext.js +48 -0
  57. package/dist/utils/parseError.d.ts +12 -0
  58. package/dist/utils/parseError.js +27 -3
  59. package/dist/utils/pinoAdapter.d.ts +30 -0
  60. package/dist/utils/pinoAdapter.js +68 -0
  61. package/dist/utils/sanitize.d.ts +42 -0
  62. package/dist/utils/sanitize.js +120 -0
  63. package/dist/utils/tryCatch.d.ts +10 -1
  64. package/dist/utils/tryCatch.js +40 -5
  65. package/docs/01-visao-geral.md +355 -0
  66. package/docs/02-contexto-negocio.md +596 -0
  67. package/docs/03-arquitetura.md +925 -0
  68. package/docs/04-fluxos-funcionais.md +887 -0
  69. package/docs/05-integracoes.md +960 -0
  70. package/docs/06-entidades.md +849 -0
  71. package/docs/07-guia-pratico.md +1133 -0
  72. package/docs/08-troubleshooting.md +816 -0
  73. package/docs/README.md +125 -0
  74. package/examples/logger-example.ts +279 -0
  75. package/package.json +2 -2
  76. /package/dist/{Entities → entities}/Logs.d.ts +0 -0
  77. /package/dist/{Entities → entities}/Logs.js +0 -0
  78. /package/dist/{Entities → entities}/connection.d.ts +0 -0
  79. /package/dist/{Entities → entities}/connection.js +0 -0
  80. /package/dist/{Entities → entities}/errorLogs.d.ts +0 -0
  81. /package/dist/{Entities → entities}/errorLogs.js +0 -0
  82. /package/dist/{Entities → entities}/index.d.ts +0 -0
  83. /package/dist/{Entities → entities}/index.js +0 -0
  84. /package/dist/{Entities → entities}/messages.d.ts +0 -0
  85. /package/dist/{Entities → entities}/messages.js +0 -0
  86. /package/dist/{Entities → entities}/webhooks.d.ts +0 -0
  87. /package/dist/{Entities → entities}/webhooks.js +0 -0
  88. /package/dist/{Entities → entities}/whatsappMessage.d.ts +0 -0
  89. /package/dist/{Entities → entities}/whatsappMessage.js +0 -0
  90. /package/dist/{Errors → errors}/Either.d.ts +0 -0
  91. /package/dist/{Errors → errors}/Either.js +0 -0
  92. /package/dist/{Errors → errors}/ErrorHandling.d.ts +0 -0
  93. /package/dist/{Errors → errors}/ErrorHandling.js +0 -0
  94. /package/dist/{Errors → errors}/index.d.ts +0 -0
  95. /package/dist/{Errors → errors}/index.js +0 -0
@@ -2,17 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TextTemplate = void 0;
4
4
  class TextTemplate {
5
- constructor({ template, language, to }) {
5
+ constructor({ template, language, to, bodyParameters }) {
6
6
  this.messaging_product = "whatsapp";
7
7
  this.recipient_type = "individual";
8
8
  this.to = to;
9
9
  this.type = "template";
10
- this.template = {
11
- name: template,
12
- language: {
10
+ const components = [];
11
+ if (bodyParameters && bodyParameters.length > 0) {
12
+ components.push({
13
+ type: "body",
14
+ parameters: bodyParameters.map(param => ({
15
+ type: param.type,
16
+ text: param.text
17
+ }))
18
+ });
19
+ }
20
+ this.template = Object.assign({ name: template, language: {
13
21
  code: language,
14
- },
15
- };
22
+ } }, (components.length > 0 && { components }));
16
23
  }
17
24
  }
18
25
  exports.TextTemplate = TextTemplate;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,11 @@ import { WhatsappResponse } from "./useCases/message/whatsappResponse";
3
3
  import { Button as CadastroIncorporado } from "./ui/Button";
4
4
  import * as interfaces from "./interfaces";
5
5
  import * as types from "./types";
6
- import * as entities from "./Entities";
6
+ import * as entities from "./entities";
7
7
  import * as elements from "./elements";
8
- export { NatyMeta as default, WhatsappResponse, entities, elements, Connection, Message, Webhook, Log, interfaces, types, CadastroIncorporado, };
8
+ import * as utils from "./utils";
9
+ export type { ILogger, LogLevel } from "./interfaces/ILogger";
10
+ export { consoleLogger } from "./utils/consoleLogger";
11
+ export { createPinoAdapter } from "./utils/pinoAdapter";
12
+ export { logger, setGlobalLogger } from "./utils/loggerContext";
13
+ export { NatyMeta as default, WhatsappResponse, entities, elements, Connection, Message, Webhook, Log, interfaces, types, utils, CadastroIncorporado, };
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.CadastroIncorporado = exports.types = exports.interfaces = exports.Log = exports.Webhook = exports.Message = exports.Connection = exports.elements = exports.entities = exports.WhatsappResponse = exports.default = void 0;
26
+ exports.CadastroIncorporado = exports.utils = exports.types = exports.interfaces = exports.Log = exports.Webhook = exports.Message = exports.Connection = exports.elements = exports.entities = exports.WhatsappResponse = exports.default = exports.setGlobalLogger = exports.logger = exports.createPinoAdapter = exports.consoleLogger = void 0;
27
27
  const useCases_1 = require("./useCases");
28
28
  Object.defineProperty(exports, "default", { enumerable: true, get: function () { return useCases_1.NatyMeta; } });
29
29
  Object.defineProperty(exports, "Log", { enumerable: true, get: function () { return useCases_1.Log; } });
@@ -38,7 +38,16 @@ const interfaces = __importStar(require("./interfaces"));
38
38
  exports.interfaces = interfaces;
39
39
  const types = __importStar(require("./types"));
40
40
  exports.types = types;
41
- const entities = __importStar(require("./Entities"));
41
+ const entities = __importStar(require("./entities"));
42
42
  exports.entities = entities;
43
43
  const elements = __importStar(require("./elements"));
44
44
  exports.elements = elements;
45
+ const utils = __importStar(require("./utils"));
46
+ exports.utils = utils;
47
+ var consoleLogger_1 = require("./utils/consoleLogger");
48
+ Object.defineProperty(exports, "consoleLogger", { enumerable: true, get: function () { return consoleLogger_1.consoleLogger; } });
49
+ var pinoAdapter_1 = require("./utils/pinoAdapter");
50
+ Object.defineProperty(exports, "createPinoAdapter", { enumerable: true, get: function () { return pinoAdapter_1.createPinoAdapter; } });
51
+ var loggerContext_1 = require("./utils/loggerContext");
52
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return loggerContext_1.logger; } });
53
+ Object.defineProperty(exports, "setGlobalLogger", { enumerable: true, get: function () { return loggerContext_1.setGlobalLogger; } });
@@ -1,5 +1,5 @@
1
- import { ConnectionEntity } from "../Entities/connection";
2
- import { Either } from "../Errors";
1
+ import { ConnectionEntity } from "../entities/connection";
2
+ import { Either } from "../errors";
3
3
  import { getAllProps, getAllReturn } from "../types/requestTypes";
4
4
  export interface IConnection {
5
5
  insert(connection: Partial<ConnectionEntity>): Promise<Either<connectionErrors, ConnectionEntity>>;
@@ -1,5 +1,5 @@
1
- import { LogsEntity } from "../Entities/Logs";
2
- import { Either } from "../Errors";
1
+ import { LogsEntity } from "../entities/Logs";
2
+ import { Either } from "../errors";
3
3
  import { getAllProps, getAllReturn } from "../types/requestTypes";
4
4
  export interface ILog {
5
5
  getSingle(key: string): Promise<Either<logErrors, LogsEntity>>;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Logger interface for the SDK
3
+ *
4
+ * Compatible with popular loggers like Pino, Winston, Bunyan, and console.
5
+ * Provides separate methods for each log level for better developer experience.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Using with Pino
10
+ * import pino from 'pino';
11
+ * import { setGlobalLogger } from '@natyapp/meta';
12
+ *
13
+ * const pinoLogger = pino({ level: 'info' });
14
+ * setGlobalLogger({
15
+ * debug: (msg, meta) => pinoLogger.debug(meta, msg),
16
+ * info: (msg, meta) => pinoLogger.info(meta, msg),
17
+ * warn: (msg, meta) => pinoLogger.warn(meta, msg),
18
+ * error: (msg, meta) => pinoLogger.error(meta, msg),
19
+ * });
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Custom logger implementation
25
+ * const customLogger: ILogger = {
26
+ * debug: (message, meta) => myService.log('debug', message, meta),
27
+ * info: (message, meta) => myService.log('info', message, meta),
28
+ * warn: (message, meta) => myService.log('warn', message, meta),
29
+ * error: (message, meta) => myService.log('error', message, meta),
30
+ * };
31
+ * ```
32
+ */
33
+ export interface ILogger {
34
+ /**
35
+ * Log debug-level message (verbose technical details)
36
+ * @param message - The log message
37
+ * @param meta - Optional metadata object
38
+ */
39
+ debug(message: string, meta?: Record<string, any>): void;
40
+ /**
41
+ * Log info-level message (general informational messages)
42
+ * @param message - The log message
43
+ * @param meta - Optional metadata object
44
+ */
45
+ info(message: string, meta?: Record<string, any>): void;
46
+ /**
47
+ * Log warn-level message (warning conditions)
48
+ * @param message - The log message
49
+ * @param meta - Optional metadata object
50
+ */
51
+ warn(message: string, meta?: Record<string, any>): void;
52
+ /**
53
+ * Log error-level message (error conditions)
54
+ * @param message - The log message
55
+ * @param meta - Optional metadata object
56
+ */
57
+ error(message: string, meta?: Record<string, any>): void;
58
+ }
59
+ /**
60
+ * @deprecated Use ILogger interface methods directly (debug, info, warn, error)
61
+ */
62
+ export type LogLevel = "debug" | "info" | "warn" | "error";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,8 +1,9 @@
1
- import { Response } from "../Errors/ErrorHandling";
1
+ import { Either } from "../errors/Either";
2
2
  import { Connection, Log, Message, Webhook } from "../useCases";
3
3
  import { Express } from "express";
4
+ import { ILogger } from "./ILogger";
4
5
  export interface ISdk {
5
- connect({ appToken, }: ConnectProps): Promise<Response<ConnectErrors, boolean>>;
6
+ connect({ appToken }: ConnectProps): Promise<Either<string, boolean>>;
6
7
  Connection: typeof Connection;
7
8
  Message: typeof Message;
8
9
  Webhook: typeof Webhook;
@@ -12,5 +13,6 @@ export type ConnectProps = {
12
13
  appToken: string;
13
14
  pathname?: string;
14
15
  app?: Express;
16
+ logger?: ILogger;
15
17
  };
16
18
  export type ConnectErrors = "AppToken inválido";
@@ -1,5 +1,5 @@
1
- import { WebhooksEntity } from "../Entities/webhooks";
2
- import { Either } from "../Errors";
1
+ import { WebhooksEntity } from "../entities/webhooks";
2
+ import { Either } from "../errors";
3
3
  import { getAllProps, getAllReturn } from "../types/requestTypes";
4
4
  export interface IWebhook {
5
5
  insert(webhook: Partial<WebhooksEntity>): Promise<Either<webhookErrors, WebhooksEntity>>;
@@ -3,3 +3,4 @@ export * from "./IWebhook";
3
3
  export * from "./IMessage";
4
4
  export * from "./ILog";
5
5
  export * from "./ISdk";
6
+ export * from "./ILogger";
@@ -19,3 +19,4 @@ __exportStar(require("./IWebhook"), exports);
19
19
  __exportStar(require("./IMessage"), exports);
20
20
  __exportStar(require("./ILog"), exports);
21
21
  __exportStar(require("./ISdk"), exports);
22
+ __exportStar(require("./ILogger"), exports);
@@ -1,4 +1,4 @@
1
- import { WhatsappMessage } from "../Entities/whatsappMessage";
1
+ import { WhatsappMessage } from "../entities/whatsappMessage";
2
2
  export declare class MessageQueue {
3
3
  private queueItems;
4
4
  constructor();
@@ -1,20 +1,65 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MessageQueue = void 0;
4
+ const loggerContext_1 = require("../utils/loggerContext");
5
+ const utils_1 = require("../utils");
4
6
  class MessageQueue {
5
7
  constructor() {
6
8
  this.queueItems = {};
7
9
  }
8
10
  addQueueItemForTopic(queueItem, topic) {
11
+ var _a;
12
+ const queueSizeBefore = ((_a = this.queueItems[topic]) === null || _a === void 0 ? void 0 : _a.length) || 0;
9
13
  if (this.queueItems[topic] === undefined) {
10
14
  this.queueItems[topic] = [queueItem];
11
15
  }
12
16
  else {
13
17
  this.queueItems[topic].push(queueItem);
14
18
  }
19
+ const queueSizeAfter = this.queueItems[topic].length;
20
+ loggerContext_1.logger.info("Adding item to queue", {
21
+ operation: (0, utils_1.getMethodContext)("MessageQueue", "addQueueItemForTopic"),
22
+ topic,
23
+ itemId: queueItem.id,
24
+ queueSize: queueSizeAfter,
25
+ });
26
+ loggerContext_1.logger.debug("Queue state after add", {
27
+ operation: (0, utils_1.getMethodContext)("MessageQueue", "addQueueItemForTopic"),
28
+ topic,
29
+ totalItems: queueSizeAfter,
30
+ addedItems: queueSizeAfter - queueSizeBefore,
31
+ });
15
32
  }
16
33
  processSingleItemForQueueTopic(topic, itemId) {
34
+ var _a, _b, _c;
35
+ const startTime = Date.now();
36
+ const queueSizeBefore = ((_a = this.queueItems[topic]) === null || _a === void 0 ? void 0 : _a.length) || 0;
37
+ const item = (_b = this.queueItems[topic]) === null || _b === void 0 ? void 0 : _b.find((i) => i.id === itemId);
38
+ if (!item) {
39
+ loggerContext_1.logger.warn("Queue item not found for processing", {
40
+ operation: (0, utils_1.getMethodContext)("MessageQueue", "processSingleItemForQueueTopic"),
41
+ topic,
42
+ itemId,
43
+ queueSize: queueSizeBefore,
44
+ });
45
+ return;
46
+ }
47
+ loggerContext_1.logger.info("Processing queue item", {
48
+ operation: (0, utils_1.getMethodContext)("MessageQueue", "processSingleItemForQueueTopic"),
49
+ topic,
50
+ itemId,
51
+ queueSize: queueSizeBefore,
52
+ });
17
53
  this.queueItems[topic] = this.queueItems[topic].filter((item) => item.id !== itemId);
54
+ const duration = Date.now() - startTime;
55
+ const queueSizeAfter = ((_c = this.queueItems[topic]) === null || _c === void 0 ? void 0 : _c.length) || 0;
56
+ loggerContext_1.logger.debug("Queue item processed successfully", {
57
+ operation: (0, utils_1.getMethodContext)("MessageQueue", "processSingleItemForQueueTopic"),
58
+ topic,
59
+ itemId,
60
+ duration,
61
+ remainingItems: queueSizeAfter,
62
+ });
18
63
  }
19
64
  }
20
65
  exports.MessageQueue = MessageQueue;
@@ -4,6 +4,9 @@ exports.connectionRouter = void 0;
4
4
  const express_1 = require("express");
5
5
  const whatsappResponse_1 = require("../../../useCases/message/whatsappResponse");
6
6
  const services_1 = require("../../../services");
7
+ const loggerContext_1 = require("../../../utils/loggerContext");
8
+ const parseError_1 = require("../../../utils/parseError");
9
+ const utils_1 = require("../../../utils");
7
10
  const connectionRouter = (naty) => {
8
11
  const router = (0, express_1.Router)();
9
12
  router.post("/", async (req, res) => {
@@ -17,32 +20,96 @@ const connectionRouter = (naty) => {
17
20
  if (message === "confirm_connection") {
18
21
  try {
19
22
  const connectionId = (_a = (data["hub.verify_token"] || data["verify_token"])) === null || _a === void 0 ? void 0 : _a.split("/")[0];
23
+ loggerContext_1.logger.info("Webhook connection confirmation", {
24
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
25
+ companyId,
26
+ connectionId,
27
+ });
20
28
  const getConnections = await services_1.connectionMutations.getAll({
21
29
  page: 0,
22
30
  size: 1000,
23
31
  });
24
- if (getConnections.isError)
25
- throw new Error("Não foi possível encontrar a instância");
32
+ if (getConnections.isError) {
33
+ loggerContext_1.logger.error("Connection webhook: Failed to fetch connections", {
34
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
35
+ companyId,
36
+ phoneNumberId: data.phone_number_id,
37
+ stage: "fetching_connections",
38
+ error: (0, parseError_1.parseError)(getConnections.isError),
39
+ });
40
+ naty.emit("error", getConnections.isError);
41
+ return res.status(500).json({
42
+ error: "Não foi possível encontrar a instância"
43
+ });
44
+ }
26
45
  const connectionInfo = (_b = getConnections.isSuccess) === null || _b === void 0 ? void 0 : _b.find((item) => item._id === connectionId);
27
- if (!connectionInfo)
28
- throw new Error("Não foi possível encontrar Connection");
46
+ if (!connectionInfo) {
47
+ loggerContext_1.logger.error("Connection webhook: Connection not found", {
48
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
49
+ companyId,
50
+ connectionId,
51
+ stage: "finding_connection",
52
+ });
53
+ return res.status(404).json({
54
+ error: "Não foi possível encontrar Connection"
55
+ });
56
+ }
29
57
  dataReturn.connection = connectionInfo;
30
58
  const whatsAppResponse = new whatsappResponse_1.WhatsappResponse(companyId, connectionInfo.phoneNumberId);
31
- const accountInfo = await whatsAppResponse.get_account_info();
32
- if (!accountInfo)
33
- throw new Error("Não foi possível encontrar Account");
59
+ const accountInfoResult = await whatsAppResponse.get_account_info();
60
+ if (accountInfoResult.isError) {
61
+ loggerContext_1.logger.error("Connection webhook: Account info not found", {
62
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
63
+ companyId,
64
+ connectionId,
65
+ phoneNumberId: connectionInfo.phoneNumberId,
66
+ stage: "fetching_account_info",
67
+ error: (0, parseError_1.parseError)(accountInfoResult.isError),
68
+ });
69
+ naty.emit("error", accountInfoResult.isError);
70
+ return res.status(500).json({
71
+ error: "Não foi possível encontrar Account"
72
+ });
73
+ }
74
+ const accountInfo = accountInfoResult.isSuccess;
75
+ if (!accountInfo) {
76
+ loggerContext_1.logger.error("Connection webhook: Account info undefined", {
77
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
78
+ companyId,
79
+ connectionId,
80
+ });
81
+ return res.status(500).json({
82
+ error: "Account info is undefined"
83
+ });
84
+ }
34
85
  dataReturn.accountInfo = accountInfo;
86
+ loggerContext_1.logger.info("Connection confirmed successfully", {
87
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
88
+ companyId,
89
+ connectionId,
90
+ phoneNumber: accountInfo.display_phone_number,
91
+ });
35
92
  naty.emit("connection", dataReturn);
36
- res.json({ connection: req.body });
93
+ return res.json({ connection: req.body });
37
94
  }
38
95
  catch (err) {
39
- console.log(err);
96
+ const errorDetails = (0, parseError_1.parseError)(err, "Webhook connection error");
97
+ loggerContext_1.logger.error("Webhook connection error", {
98
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "connection"),
99
+ error: errorDetails.message,
100
+ code: errorDetails.code,
101
+ companyId,
102
+ });
40
103
  naty.emit("error", err);
41
- res.status(500).json({
42
- error: err.message,
104
+ return res.status(500).json({
105
+ error: err.message || "Internal server error",
43
106
  });
44
107
  }
45
108
  }
109
+ else {
110
+ // Handle other message types or return 200 for unhandled messages
111
+ return res.status(200).json({ message: "Webhook received" });
112
+ }
46
113
  });
47
114
  return router;
48
115
  };
@@ -2,21 +2,36 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.messagesRouter = void 0;
4
4
  const express_1 = require("express");
5
- const whatsappMessage_1 = require("../../../Entities/whatsappMessage");
5
+ const whatsappMessage_1 = require("../../../entities/whatsappMessage");
6
6
  const whatsappResponse_1 = require("../../../useCases/message/whatsappResponse");
7
+ const loggerContext_1 = require("../../../utils/loggerContext");
8
+ const parseError_1 = require("../../../utils/parseError");
9
+ const utils_1 = require("../../../utils");
7
10
  const messagesRouter = (naty) => {
8
11
  const router = (0, express_1.Router)();
9
12
  router.post("/", (req, res) => {
10
- var _a, _b, _c, _d, _e, _f, _g;
13
+ var _a, _b, _c, _d, _e, _f, _g, _h;
11
14
  try {
12
15
  const { companyId, data } = req.body;
13
16
  const phone_number_id = (_c = (_b = (_a = data.entry[0]) === null || _a === void 0 ? void 0 : _a.changes[0]) === null || _b === void 0 ? void 0 : _b.value.metadata) === null || _c === void 0 ? void 0 : _c.phone_number_id;
14
17
  const clientNumber = (_g = (_f = (_e = (_d = data.entry[0]) === null || _d === void 0 ? void 0 : _d.changes[0]) === null || _e === void 0 ? void 0 : _e.value) === null || _f === void 0 ? void 0 : _f.contacts[0]) === null || _g === void 0 ? void 0 : _g.wa_id;
18
+ loggerContext_1.logger.info("Webhook message received", {
19
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "messages"),
20
+ companyId,
21
+ phone_number_id,
22
+ clientNumber,
23
+ });
15
24
  naty.emit("message", new whatsappResponse_1.WhatsappResponse(companyId, phone_number_id, clientNumber, new whatsappMessage_1.WhatsappMessage(data)));
16
25
  res.json(true);
17
26
  }
18
27
  catch (err) {
19
- console.log(err);
28
+ const errorDetails = (0, parseError_1.parseError)(err, "Webhook message processing failed");
29
+ loggerContext_1.logger.error("Webhook message error", {
30
+ operation: (0, utils_1.getMethodContext)("WebhookHandler", "messages"),
31
+ error: errorDetails.message,
32
+ code: errorDetails.code,
33
+ companyId: (_h = req.body) === null || _h === void 0 ? void 0 : _h.companyId,
34
+ });
20
35
  naty.emit("error", err);
21
36
  res.status(500).json({
22
37
  error: err.message,
@@ -1,19 +1,28 @@
1
+ import { AxiosInstance } from "axios";
1
2
  export declare const newAxiosInstance: ({ url, phone_number_id, accessToken, }: {
2
3
  url?: string | undefined;
3
4
  phone_number_id?: string | undefined;
4
5
  accessToken: string;
5
- }) => import("axios").AxiosInstance;
6
+ }) => AxiosInstance;
6
7
  export declare const axiosInstanceForDownloadMedia: ({ url, accessToken, }: {
7
8
  url?: string | undefined;
8
9
  accessToken: string;
9
- }) => import("axios").AxiosInstance;
10
+ }) => AxiosInstance;
10
11
  export declare const axiosInstanceGeneral: ({ url, accessToken, }: {
11
12
  url?: string | undefined;
12
13
  accessToken: string;
13
- }) => import("axios").AxiosInstance;
14
- declare const api: import("axios").AxiosInstance;
14
+ }) => AxiosInstance;
15
+ declare const api: AxiosInstance;
15
16
  export { api };
16
17
  export declare const updateInterceptor: (interceptors: {
17
18
  [key: string]: string;
18
19
  }, callback?: ((bool: boolean) => void) | undefined) => Promise<number>;
19
- export declare const newFacebookInstance: () => import("axios").AxiosInstance;
20
+ export declare const newFacebookInstance: () => AxiosInstance;
21
+ /**
22
+ * Configure logging interceptors for axios instance
23
+ * Logs all HTTP requests and responses using the global logger
24
+ *
25
+ * @param instance - Axios instance to configure
26
+ * @returns The configured axios instance
27
+ */
28
+ export declare function configureLoggingInterceptors(instance: AxiosInstance): AxiosInstance;
@@ -3,36 +3,49 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.newFacebookInstance = exports.updateInterceptor = exports.api = exports.axiosInstanceGeneral = exports.axiosInstanceForDownloadMedia = exports.newAxiosInstance = void 0;
6
+ exports.configureLoggingInterceptors = exports.newFacebookInstance = exports.updateInterceptor = exports.api = exports.axiosInstanceGeneral = exports.axiosInstanceForDownloadMedia = exports.newAxiosInstance = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const axiosInterceptors_1 = require("../configs/axiosInterceptors");
9
- const newAxiosInstance = ({ url = "https://graph.facebook.com/v18.0/", phone_number_id, accessToken, }) => axios_1.default.create({
10
- baseURL: url + phone_number_id,
11
- headers: {
12
- Authorization: `Bearer ${accessToken}`,
13
- },
14
- });
9
+ const loggerContext_1 = require("../utils/loggerContext");
10
+ const utils_1 = require("../utils");
11
+ const newAxiosInstance = ({ url = "https://graph.facebook.com/v18.0/", phone_number_id, accessToken, }) => {
12
+ const instance = axios_1.default.create({
13
+ baseURL: url + phone_number_id,
14
+ headers: {
15
+ Authorization: `Bearer ${accessToken}`,
16
+ },
17
+ });
18
+ return configureLoggingInterceptors(instance);
19
+ };
15
20
  exports.newAxiosInstance = newAxiosInstance;
16
- const axiosInstanceForDownloadMedia = ({ url = "https://graph.facebook.com/v18.0/media/", accessToken, }) => axios_1.default.create({
17
- baseURL: url,
18
- headers: {
19
- Authorization: `Bearer ${accessToken}`,
20
- },
21
- });
21
+ const axiosInstanceForDownloadMedia = ({ url = "https://graph.facebook.com/v18.0/media/", accessToken, }) => {
22
+ const instance = axios_1.default.create({
23
+ baseURL: url,
24
+ headers: {
25
+ Authorization: `Bearer ${accessToken}`,
26
+ },
27
+ });
28
+ return configureLoggingInterceptors(instance);
29
+ };
22
30
  exports.axiosInstanceForDownloadMedia = axiosInstanceForDownloadMedia;
23
- const axiosInstanceGeneral = ({ url = "https://graph.facebook.com/v18.0/", accessToken, }) => axios_1.default.create({
24
- baseURL: url,
25
- headers: {
26
- Authorization: `Bearer ${accessToken}`,
27
- },
28
- params: { query: { access_token: accessToken }, access_token: accessToken },
29
- });
31
+ const axiosInstanceGeneral = ({ url = "https://graph.facebook.com/v18.0/", accessToken, }) => {
32
+ const instance = axios_1.default.create({
33
+ baseURL: url,
34
+ headers: {
35
+ Authorization: `Bearer ${accessToken}`,
36
+ },
37
+ params: { query: { access_token: accessToken }, access_token: accessToken },
38
+ });
39
+ return configureLoggingInterceptors(instance);
40
+ };
30
41
  exports.axiosInstanceGeneral = axiosInstanceGeneral;
31
42
  const api = axios_1.default.create({
32
43
  baseURL: `${process.env.API_META}/v1`,
33
44
  headers: axiosInterceptors_1.configInterceptors,
34
45
  });
35
46
  exports.api = api;
47
+ // Configure logging interceptors for the main API instance
48
+ configureLoggingInterceptors(api);
36
49
  const updateInterceptor = async (interceptors, callback) => {
37
50
  return api.interceptors.request.use((config) => {
38
51
  // if (!config.headers) config.headers = configInterceptors;
@@ -42,7 +55,82 @@ const updateInterceptor = async (interceptors, callback) => {
42
55
  });
43
56
  };
44
57
  exports.updateInterceptor = updateInterceptor;
45
- const newFacebookInstance = () => axios_1.default.create({
46
- baseURL: "https://graph.facebook.com/v18.0/"
47
- });
58
+ const newFacebookInstance = () => {
59
+ const instance = axios_1.default.create({
60
+ baseURL: "https://graph.facebook.com/v18.0/",
61
+ });
62
+ return configureLoggingInterceptors(instance);
63
+ };
48
64
  exports.newFacebookInstance = newFacebookInstance;
65
+ /**
66
+ * Sanitize headers to remove sensitive data from logs
67
+ */
68
+ function sanitizeHeaders(headers) {
69
+ if (!headers)
70
+ return {};
71
+ const sanitized = Object.assign({}, headers);
72
+ // Remove or mask sensitive headers
73
+ if (sanitized.Authorization) {
74
+ sanitized.Authorization = "Bearer [REDACTED]";
75
+ }
76
+ if (sanitized["x-access-token"]) {
77
+ sanitized["x-access-token"] = "[REDACTED]";
78
+ }
79
+ return sanitized;
80
+ }
81
+ /**
82
+ * Configure logging interceptors for axios instance
83
+ * Logs all HTTP requests and responses using the global logger
84
+ *
85
+ * @param instance - Axios instance to configure
86
+ * @returns The configured axios instance
87
+ */
88
+ function configureLoggingInterceptors(instance) {
89
+ // Request interceptor
90
+ instance.interceptors.request.use((config) => {
91
+ var _a;
92
+ loggerContext_1.logger.debug("HTTP Request", {
93
+ operation: (0, utils_1.getMethodContext)("AxiosInterceptor", "request"),
94
+ method: (_a = config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase(),
95
+ url: config.url,
96
+ baseURL: config.baseURL,
97
+ headers: sanitizeHeaders(config.headers),
98
+ hasData: !!config.data,
99
+ });
100
+ return config;
101
+ }, (error) => {
102
+ loggerContext_1.logger.error("HTTP Request Error", {
103
+ operation: (0, utils_1.getMethodContext)("AxiosInterceptor", "request.error"),
104
+ message: error.message,
105
+ config: error.config,
106
+ });
107
+ return Promise.reject(error);
108
+ });
109
+ // Response interceptor
110
+ instance.interceptors.response.use((response) => {
111
+ loggerContext_1.logger.debug("HTTP Response", {
112
+ operation: (0, utils_1.getMethodContext)("AxiosInterceptor", "response"),
113
+ status: response.status,
114
+ statusText: response.statusText,
115
+ url: response.config.url,
116
+ dataType: typeof response.data,
117
+ });
118
+ return response;
119
+ }, (error) => {
120
+ var _a, _b, _c;
121
+ const errorDetails = {
122
+ message: error.message,
123
+ url: (_a = error.config) === null || _a === void 0 ? void 0 : _a.url,
124
+ method: (_c = (_b = error.config) === null || _b === void 0 ? void 0 : _b.method) === null || _c === void 0 ? void 0 : _c.toUpperCase(),
125
+ };
126
+ if (error.response) {
127
+ errorDetails.status = error.response.status;
128
+ errorDetails.statusText = error.response.statusText;
129
+ errorDetails.data = error.response.data;
130
+ }
131
+ loggerContext_1.logger.error("HTTP Response Error", Object.assign({ operation: (0, utils_1.getMethodContext)("AxiosInterceptor", "response.error") }, errorDetails));
132
+ return Promise.reject(error);
133
+ });
134
+ return instance;
135
+ }
136
+ exports.configureLoggingInterceptors = configureLoggingInterceptors;
@@ -1,4 +1,4 @@
1
- import { Response } from "../../Errors/ErrorHandling";
1
+ import { Either } from "../../errors/Either";
2
2
  export declare const middlewares: {
3
- confirmAppToken: (appToken: string) => Promise<Response<void, boolean>>;
3
+ confirmAppToken: (appToken: string) => Promise<Either<string, boolean>>;
4
4
  };
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.middlewares = void 0;
4
4
  const validation_1 = require("../mutations/validation");
5
- const tryCatch_1 = require("../../utils/tryCatch");
6
5
  exports.middlewares = {
7
- confirmAppToken: async (appToken) => await (0, tryCatch_1.Try)(validation_1.validateMutations.confirmAppToken, appToken),
6
+ confirmAppToken: async (appToken) => await validation_1.validateMutations.confirmAppToken(appToken),
8
7
  };