@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.
- package/.github/copilot-instructions.md +1540 -0
- package/README.md +513 -40
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +1 -0
- package/dist/elements/mediaTemplate.d.ts +45 -0
- package/dist/elements/mediaTemplate.js +47 -0
- package/dist/elements/textTemplate.d.ts +12 -1
- package/dist/elements/textTemplate.js +13 -6
- package/dist/index.d.ts +7 -2
- package/dist/index.js +11 -2
- package/dist/interfaces/IConnection.d.ts +2 -2
- package/dist/interfaces/ILog.d.ts +2 -2
- package/dist/interfaces/ILogger.d.ts +62 -0
- package/dist/interfaces/ILogger.js +2 -0
- package/dist/interfaces/ISdk.d.ts +4 -2
- package/dist/interfaces/IWebhook.d.ts +2 -2
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.js +1 -0
- package/dist/queue/messageQueue.d.ts +1 -1
- package/dist/queue/messageQueue.js +45 -0
- package/dist/routes/webhooks/methods/connection.js +78 -11
- package/dist/routes/webhooks/methods/messages.js +18 -3
- package/dist/services/axiosInstances.d.ts +14 -5
- package/dist/services/axiosInstances.js +111 -23
- package/dist/services/middlewares/validations.d.ts +2 -2
- package/dist/services/middlewares/validations.js +1 -2
- package/dist/services/mutations/connection.js +1 -1
- package/dist/services/mutations/logs.js +1 -1
- package/dist/services/mutations/messages.js +1 -1
- package/dist/services/mutations/validation.d.ts +1 -1
- package/dist/services/mutations/validation.js +1 -1
- package/dist/services/mutations/webhooks.js +1 -1
- package/dist/types/logs.d.ts +1 -1
- package/dist/types/requestTypes.d.ts +2 -0
- package/dist/useCases/connection/index.d.ts +9 -9
- package/dist/useCases/connection/index.js +156 -7
- package/dist/useCases/events/NatyEvents.d.ts +4 -2
- package/dist/useCases/events/NatyEvents.js +13 -1
- package/dist/useCases/log/index.d.ts +5 -5
- package/dist/useCases/log/index.js +65 -3
- package/dist/useCases/message/whatsappResponse.d.ts +48 -22
- package/dist/useCases/message/whatsappResponse.js +672 -105
- package/dist/useCases/messages/index.d.ts +5 -5
- package/dist/useCases/messages/index.js +66 -3
- package/dist/useCases/sdk/index.d.ts +8 -4
- package/dist/useCases/sdk/index.js +38 -6
- package/dist/useCases/webhook/index.d.ts +9 -9
- package/dist/useCases/webhook/index.js +154 -7
- package/dist/utils/consoleLogger.d.ts +20 -0
- package/dist/utils/consoleLogger.js +51 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/loggerContext.d.ts +57 -0
- package/dist/utils/loggerContext.js +90 -0
- package/dist/utils/methodContext.d.ts +34 -0
- package/dist/utils/methodContext.js +48 -0
- package/dist/utils/parseError.d.ts +12 -0
- package/dist/utils/parseError.js +27 -3
- package/dist/utils/pinoAdapter.d.ts +30 -0
- package/dist/utils/pinoAdapter.js +68 -0
- package/dist/utils/sanitize.d.ts +42 -0
- package/dist/utils/sanitize.js +120 -0
- package/dist/utils/tryCatch.d.ts +10 -1
- package/dist/utils/tryCatch.js +40 -5
- package/docs/01-visao-geral.md +355 -0
- package/docs/02-contexto-negocio.md +596 -0
- package/docs/03-arquitetura.md +925 -0
- package/docs/04-fluxos-funcionais.md +887 -0
- package/docs/05-integracoes.md +960 -0
- package/docs/06-entidades.md +849 -0
- package/docs/07-guia-pratico.md +1133 -0
- package/docs/08-troubleshooting.md +816 -0
- package/docs/README.md +125 -0
- package/examples/logger-example.ts +279 -0
- package/package.json +2 -2
- /package/dist/{Entities → entities}/Logs.d.ts +0 -0
- /package/dist/{Entities → entities}/Logs.js +0 -0
- /package/dist/{Entities → entities}/connection.d.ts +0 -0
- /package/dist/{Entities → entities}/connection.js +0 -0
- /package/dist/{Entities → entities}/errorLogs.d.ts +0 -0
- /package/dist/{Entities → entities}/errorLogs.js +0 -0
- /package/dist/{Entities → entities}/index.d.ts +0 -0
- /package/dist/{Entities → entities}/index.js +0 -0
- /package/dist/{Entities → entities}/messages.d.ts +0 -0
- /package/dist/{Entities → entities}/messages.js +0 -0
- /package/dist/{Entities → entities}/webhooks.d.ts +0 -0
- /package/dist/{Entities → entities}/webhooks.js +0 -0
- /package/dist/{Entities → entities}/whatsappMessage.d.ts +0 -0
- /package/dist/{Entities → entities}/whatsappMessage.js +0 -0
- /package/dist/{Errors → errors}/Either.d.ts +0 -0
- /package/dist/{Errors → errors}/Either.js +0 -0
- /package/dist/{Errors → errors}/ErrorHandling.d.ts +0 -0
- /package/dist/{Errors → errors}/ErrorHandling.js +0 -0
- /package/dist/{Errors → errors}/index.d.ts +0 -0
- /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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 "./
|
|
6
|
+
import * as entities from "./entities";
|
|
7
7
|
import * as elements from "./elements";
|
|
8
|
-
|
|
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("./
|
|
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 "../
|
|
2
|
-
import { Either } from "../
|
|
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 "../
|
|
2
|
-
import { Either } from "../
|
|
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";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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 "../
|
|
2
|
-
import { Either } from "../
|
|
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>>;
|
package/dist/interfaces/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
32
|
-
if (
|
|
33
|
-
|
|
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
|
-
|
|
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("../../../
|
|
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
|
-
|
|
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
|
-
}) =>
|
|
6
|
+
}) => AxiosInstance;
|
|
6
7
|
export declare const axiosInstanceForDownloadMedia: ({ url, accessToken, }: {
|
|
7
8
|
url?: string | undefined;
|
|
8
9
|
accessToken: string;
|
|
9
|
-
}) =>
|
|
10
|
+
}) => AxiosInstance;
|
|
10
11
|
export declare const axiosInstanceGeneral: ({ url, accessToken, }: {
|
|
11
12
|
url?: string | undefined;
|
|
12
13
|
accessToken: string;
|
|
13
|
-
}) =>
|
|
14
|
-
declare const api:
|
|
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: () =>
|
|
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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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, }) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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, }) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 = () =>
|
|
46
|
-
|
|
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 {
|
|
1
|
+
import { Either } from "../../errors/Either";
|
|
2
2
|
export declare const middlewares: {
|
|
3
|
-
confirmAppToken: (appToken: string) => Promise<
|
|
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
|
|
6
|
+
confirmAppToken: async (appToken) => await validation_1.validateMutations.confirmAppToken(appToken),
|
|
8
7
|
};
|