plenna_utilities 1.5.2 → 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/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/src/alerts/application/send-alert-impl.service.d.ts +8 -0
- package/dist/src/alerts/application/send-alert-impl.service.js +20 -0
- package/dist/src/alerts/domain/interfaces/alerts.d.ts +49 -0
- package/dist/src/alerts/domain/interfaces/alerts.js +2 -0
- package/dist/src/alerts/domain/services/send-alert.service.d.ts +4 -0
- package/dist/src/alerts/domain/services/send-alert.service.js +6 -0
- package/dist/src/alerts/domain/usecases/send-alert.usecase.d.ts +9 -0
- package/dist/src/alerts/domain/usecases/send-alert.usecase.js +48 -0
- package/dist/src/alerts/presenter/index.d.ts +2 -0
- package/dist/src/alerts/presenter/index.js +11 -0
- package/dist/src/common/domain/alerts/alerts.d.ts +4 -0
- package/dist/src/common/domain/alerts/alerts.js +6 -0
- package/dist/src/common/domain/configurations/configurations.d.ts +3 -0
- package/dist/src/common/domain/configurations/configurations.js +6 -0
- package/dist/src/common/domain/interfaces/products.interfaces.d.ts +3 -0
- package/dist/src/common/domain/interfaces/products.interfaces.js +7 -0
- package/dist/src/common/domain/interfaces/usecases.interface.d.ts +3 -0
- package/dist/src/common/domain/interfaces/usecases.interface.js +2 -0
- package/dist/src/common/domain/shared/interpolation.transformer.d.ts +2 -0
- package/dist/src/common/domain/shared/interpolation.transformer.js +13 -0
- package/dist/src/common/infrastructure/slack/slack.d.ts +7 -0
- package/dist/src/common/infrastructure/slack/slack.js +37 -0
- package/dist/src/common/infrastructure/yaml-converter/configurations/slack.yaml +32 -0
- package/dist/src/common/infrastructure/yaml-converter/yaml-converter.d.ts +4 -0
- package/dist/src/common/infrastructure/yaml-converter/yaml-converter.js +28 -0
- package/dist/src/customerio/index.d.ts +3 -1
- package/dist/src/customerio/index.js +13 -0
- package/dist/src/time/index.d.ts +1 -0
- package/dist/src/time/index.js +5 -1
- package/package.json +10 -5
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -13,7 +13,12 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
13
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
16
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
21
|
+
dotenv_1.default.config();
|
|
17
22
|
__exportStar(require("./src/lambdas"), exports);
|
|
18
23
|
__exportStar(require("./src/time"), exports);
|
|
19
24
|
__exportStar(require("./src/s3"), exports);
|
|
@@ -22,3 +27,4 @@ __exportStar(require("./src/general"), exports);
|
|
|
22
27
|
__exportStar(require("./src/customerio"), exports);
|
|
23
28
|
__exportStar(require("./src/mailer"), exports);
|
|
24
29
|
__exportStar(require("./src/airTable"), exports);
|
|
30
|
+
__exportStar(require("./src/alerts/presenter"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type AlertsHandler } from '../../common/domain/alerts/alerts';
|
|
2
|
+
import { type AlertResponse, type IAlert } from '../domain/interfaces/alerts';
|
|
3
|
+
import { AlertService } from '../domain/services/send-alert.service';
|
|
4
|
+
export declare class AlertServiceImpl extends AlertService {
|
|
5
|
+
private readonly alertImpl;
|
|
6
|
+
constructor(alertImpl: AlertsHandler);
|
|
7
|
+
sendAlert(alert: IAlert): Promise<AlertResponse | undefined>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AlertServiceImpl = void 0;
|
|
4
|
+
const send_alert_service_1 = require("../domain/services/send-alert.service");
|
|
5
|
+
class AlertServiceImpl extends send_alert_service_1.AlertService {
|
|
6
|
+
alertImpl;
|
|
7
|
+
constructor(alertImpl) {
|
|
8
|
+
super();
|
|
9
|
+
this.alertImpl = alertImpl;
|
|
10
|
+
}
|
|
11
|
+
async sendAlert(alert) {
|
|
12
|
+
try {
|
|
13
|
+
return await this.alertImpl.sendAlert(alert);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
console.info(error);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.AlertServiceImpl = AlertServiceImpl;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface TextObject {
|
|
2
|
+
type: 'plain_text' | 'mrkdwn';
|
|
3
|
+
text: string;
|
|
4
|
+
emoji?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface FieldObject {
|
|
7
|
+
type: 'mrkdwn';
|
|
8
|
+
text: string;
|
|
9
|
+
}
|
|
10
|
+
export interface HeaderBlock {
|
|
11
|
+
type: 'header';
|
|
12
|
+
text: TextObject;
|
|
13
|
+
}
|
|
14
|
+
export interface SectionBlock {
|
|
15
|
+
type: 'section';
|
|
16
|
+
text: TextObject;
|
|
17
|
+
fields?: FieldObject[];
|
|
18
|
+
}
|
|
19
|
+
export interface DividerBlock {
|
|
20
|
+
type: 'divider';
|
|
21
|
+
}
|
|
22
|
+
export interface ContextBlock {
|
|
23
|
+
type: 'context';
|
|
24
|
+
elements: TextObject[];
|
|
25
|
+
}
|
|
26
|
+
export type Block = HeaderBlock | SectionBlock | DividerBlock | ContextBlock;
|
|
27
|
+
export interface IAlert {
|
|
28
|
+
channel: string;
|
|
29
|
+
text: string;
|
|
30
|
+
blocks?: Block[];
|
|
31
|
+
threadTs?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ITemplatesConfiguration {
|
|
34
|
+
templates: Record<string, IAlert>;
|
|
35
|
+
}
|
|
36
|
+
export interface AlertTemplateInput {
|
|
37
|
+
template?: string;
|
|
38
|
+
date?: string;
|
|
39
|
+
text?: string;
|
|
40
|
+
bookingUser?: string;
|
|
41
|
+
channel?: string;
|
|
42
|
+
origin?: string;
|
|
43
|
+
huliId?: string;
|
|
44
|
+
threadTs?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface AlertResponse {
|
|
47
|
+
channel: string;
|
|
48
|
+
ts: string;
|
|
49
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Configuration } from '../../../common/domain/configurations/configurations';
|
|
2
|
+
import { type UseCase } from '../../../common/domain/interfaces/usecases.interface';
|
|
3
|
+
import { type AlertService } from '../services/send-alert.service';
|
|
4
|
+
export declare class SendAlertUseCase implements UseCase {
|
|
5
|
+
private readonly configuration;
|
|
6
|
+
private readonly alertService;
|
|
7
|
+
constructor(configuration: Configuration, alertService: AlertService);
|
|
8
|
+
exec(...args: any[]): Promise<any>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SendAlertUseCase = void 0;
|
|
4
|
+
const products_interfaces_1 = require("../../../common/domain/interfaces/products.interfaces");
|
|
5
|
+
const interpolation_transformer_1 = require("../../../common/domain/shared/interpolation.transformer");
|
|
6
|
+
class SendAlertUseCase {
|
|
7
|
+
configuration;
|
|
8
|
+
alertService;
|
|
9
|
+
constructor(configuration, alertService) {
|
|
10
|
+
this.configuration = configuration;
|
|
11
|
+
this.alertService = alertService;
|
|
12
|
+
}
|
|
13
|
+
async exec(...args) {
|
|
14
|
+
try {
|
|
15
|
+
const [input] = args;
|
|
16
|
+
const alertData = input;
|
|
17
|
+
if (alertData?.origin === null || alertData?.origin === undefined)
|
|
18
|
+
return;
|
|
19
|
+
if (alertData?.channel !== '' && alertData?.channel !== undefined) {
|
|
20
|
+
const alert = {
|
|
21
|
+
channel: alertData.channel ?? '',
|
|
22
|
+
text: alertData.text ?? '',
|
|
23
|
+
threadTs: alertData?.threadTs
|
|
24
|
+
};
|
|
25
|
+
return await this.alertService.sendAlert(alert);
|
|
26
|
+
}
|
|
27
|
+
const getConfiguration = await this.configuration.getConfiguration(products_interfaces_1.Products.SLACK);
|
|
28
|
+
if (getConfiguration === undefined)
|
|
29
|
+
throw new Error('configuration not found');
|
|
30
|
+
const templateKey = alertData.template ?? '';
|
|
31
|
+
const templateInfo = getConfiguration.templates[templateKey];
|
|
32
|
+
if (templateInfo === null && templateInfo === undefined)
|
|
33
|
+
throw new Error('template not found');
|
|
34
|
+
if (templateInfo.blocks !== undefined) {
|
|
35
|
+
templateInfo.blocks.forEach((block) => {
|
|
36
|
+
if (block.type === 'section' && block.fields != null) {
|
|
37
|
+
block.fields = (0, interpolation_transformer_1.interpolateFields)(block.fields, alertData);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return await this.alertService.sendAlert(templateInfo);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error(error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.SendAlertUseCase = SendAlertUseCase;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendAlert = void 0;
|
|
4
|
+
const slack_1 = require("../../common/infrastructure/slack/slack");
|
|
5
|
+
const yaml_converter_1 = require("../../common/infrastructure/yaml-converter/yaml-converter");
|
|
6
|
+
const send_alert_impl_service_1 = require("../application/send-alert-impl.service");
|
|
7
|
+
const send_alert_usecase_1 = require("../domain/usecases/send-alert.usecase");
|
|
8
|
+
const alertImpl = new slack_1.SlackImpl(process.env.SLACK_TOKEN ?? '');
|
|
9
|
+
const configuration = new yaml_converter_1.ConfigurationYaml();
|
|
10
|
+
const alertService = new send_alert_impl_service_1.AlertServiceImpl(alertImpl);
|
|
11
|
+
exports.sendAlert = new send_alert_usecase_1.SendAlertUseCase(configuration, alertService);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interpolateFields = interpolateFields;
|
|
4
|
+
function interpolateFields(fields, input) {
|
|
5
|
+
return fields.map((field) => {
|
|
6
|
+
let text = field.text;
|
|
7
|
+
text = text.replace(/\{(\w+)\}/g, (_, key) => {
|
|
8
|
+
const value = input[key];
|
|
9
|
+
return value ?? `{${key}}`;
|
|
10
|
+
});
|
|
11
|
+
return { ...field, text };
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type AlertResponse } from '../../../alerts/domain/interfaces/alerts';
|
|
2
|
+
import { AlertsHandler } from '../../domain/alerts/alerts';
|
|
3
|
+
export declare class SlackImpl extends AlertsHandler {
|
|
4
|
+
private readonly client;
|
|
5
|
+
constructor(token: string);
|
|
6
|
+
sendAlert(...args: any[]): Promise<AlertResponse | undefined>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SlackImpl = void 0;
|
|
4
|
+
const alerts_1 = require("../../domain/alerts/alerts");
|
|
5
|
+
const web_api_1 = require("@slack/web-api");
|
|
6
|
+
class SlackImpl extends alerts_1.AlertsHandler {
|
|
7
|
+
client;
|
|
8
|
+
constructor(token) {
|
|
9
|
+
super();
|
|
10
|
+
this.client = new web_api_1.WebClient(token);
|
|
11
|
+
}
|
|
12
|
+
async sendAlert(...args) {
|
|
13
|
+
try {
|
|
14
|
+
const [input] = args;
|
|
15
|
+
const data = input;
|
|
16
|
+
const { channel, text, blocks, threadTs } = data;
|
|
17
|
+
if (typeof channel !== 'string' || channel.trim() === '' ||
|
|
18
|
+
typeof text !== 'string' || text.trim() === '') {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const response = await this.client.chat.postMessage({
|
|
22
|
+
channel,
|
|
23
|
+
text,
|
|
24
|
+
blocks,
|
|
25
|
+
thread_ts: threadTs
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
channel: response?.channel ?? '',
|
|
29
|
+
ts: response?.ts ?? ''
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.info(JSON.stringify(error));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.SlackImpl = SlackImpl;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
templates:
|
|
2
|
+
noInfo:
|
|
3
|
+
channel: 'C08S575SWCF'
|
|
4
|
+
text: 'Alerta !!!'
|
|
5
|
+
blocks:
|
|
6
|
+
- type: header
|
|
7
|
+
text:
|
|
8
|
+
type: plain_text
|
|
9
|
+
text: '🚨 Error de Agenda'
|
|
10
|
+
emoji: true
|
|
11
|
+
- type: section
|
|
12
|
+
text:
|
|
13
|
+
type: mrkdwn
|
|
14
|
+
text: '*Motivo:* Se ha creado una agenda con información erronea!!'
|
|
15
|
+
fields:
|
|
16
|
+
- type: mrkdwn
|
|
17
|
+
text: "*ID de cita en Huli:*\n{huliId}"
|
|
18
|
+
- type: mrkdwn
|
|
19
|
+
text: "*Persona que intentó agendar:*\n<{bookingUser}>"
|
|
20
|
+
- type: mrkdwn
|
|
21
|
+
text: "*¿Qué pasó?:*\n{text}"
|
|
22
|
+
- type: mrkdwn
|
|
23
|
+
text: "*¿Qué debes hacer?:*\ncancelar y volver a crear la cita correctamente."
|
|
24
|
+
- type: mrkdwn
|
|
25
|
+
text: "*Fecha:*\n{date}"
|
|
26
|
+
- type: mrkdwn
|
|
27
|
+
text: "*Origen:*\n{origin}"
|
|
28
|
+
- type: divider
|
|
29
|
+
- type: context
|
|
30
|
+
elements:
|
|
31
|
+
- type: mrkdwn
|
|
32
|
+
text: 'Generado automáticamente por el sistema de validación de agendas.'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConfigurationYaml = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
10
|
+
const configurations_1 = require("../../../common/domain/configurations/configurations");
|
|
11
|
+
class ConfigurationYaml extends configurations_1.Configuration {
|
|
12
|
+
async getConfiguration(product, customPath) {
|
|
13
|
+
try {
|
|
14
|
+
const finalPath = typeof customPath === 'string' && customPath.trim() !== ''
|
|
15
|
+
? path_1.default.resolve(customPath)
|
|
16
|
+
: path_1.default.resolve(__dirname, 'configurations');
|
|
17
|
+
const yamlFilePath = path_1.default.join(finalPath, `${product.replace(/ /g, '_').toLocaleLowerCase()}.yaml`);
|
|
18
|
+
const yamlContent = fs_1.default.readFileSync(yamlFilePath, 'utf-8');
|
|
19
|
+
const yamlObject = yaml_1.default.parse(yamlContent);
|
|
20
|
+
return yamlObject;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(`Error loading YAML configuration for ${product}:`, error);
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.ConfigurationYaml = ConfigurationYaml;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { type SendPushRequestOptions } from 'customerio-node/dist/lib/api/requests';
|
|
1
|
+
import { type SendEmailRequestOptions, type SendPushRequestOptions } from 'customerio-node/dist/lib/api/requests';
|
|
2
2
|
export type PushRequestOptions = SendPushRequestOptions;
|
|
3
|
+
export type EmailRequestOptions = SendEmailRequestOptions;
|
|
3
4
|
export declare class CustomerIo {
|
|
4
5
|
private readonly key;
|
|
5
6
|
constructor(key: string);
|
|
6
7
|
sendPushNotification(requestOptions: PushRequestOptions): Promise<boolean>;
|
|
8
|
+
sendEmail(requestOptions: EmailRequestOptions): Promise<boolean>;
|
|
7
9
|
}
|
|
@@ -20,5 +20,18 @@ class CustomerIo {
|
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
async sendEmail(requestOptions) {
|
|
24
|
+
try {
|
|
25
|
+
const request = new customerio_node_1.SendEmailRequest(requestOptions);
|
|
26
|
+
const api = new customerio_node_1.APIClient(this.key, { region: customerio_node_1.RegionUS });
|
|
27
|
+
const response = await api.sendEmail(request);
|
|
28
|
+
console.log('Sent email success: ', response);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error('Failed to send email: ', error);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
23
36
|
}
|
|
24
37
|
exports.CustomerIo = CustomerIo;
|
package/dist/src/time/index.d.ts
CHANGED
|
@@ -5,3 +5,4 @@ export declare const getAge: (date: Date) => string;
|
|
|
5
5
|
export declare const getDeltaTime: (start: Date, end: Date) => number;
|
|
6
6
|
export declare const getMonthDifference: (startDate: Date, endDate: Date) => number;
|
|
7
7
|
export declare const addWorkDays: (startDate: Date, days: number) => Date;
|
|
8
|
+
export declare const helloTime: () => void;
|
package/dist/src/time/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.addWorkDays = exports.getMonthDifference = exports.getDeltaTime = exports.getAge = exports.compare = exports.isValidNumeric = exports.fixAppointmentDateStart = void 0;
|
|
3
|
+
exports.helloTime = exports.addWorkDays = exports.getMonthDifference = exports.getDeltaTime = exports.getAge = exports.compare = exports.isValidNumeric = exports.fixAppointmentDateStart = void 0;
|
|
4
4
|
const fixAppointmentDateStart = (date, start) => {
|
|
5
5
|
const [hour, minutes] = start.split(':');
|
|
6
6
|
const fixedDate = new Date(date).setUTCHours(parseInt(hour ?? 0) + 6, parseInt(minutes ?? 0));
|
|
@@ -47,3 +47,7 @@ const addWorkDays = (startDate, days) => {
|
|
|
47
47
|
return targetDate;
|
|
48
48
|
};
|
|
49
49
|
exports.addWorkDays = addWorkDays;
|
|
50
|
+
const helloTime = () => {
|
|
51
|
+
console.log('hola');
|
|
52
|
+
};
|
|
53
|
+
exports.helloTime = helloTime;
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plenna_utilities",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "plenna's utils for backend projects",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist
|
|
8
|
+
"dist/**/*"
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
|
-
"lint": "
|
|
12
|
-
"build": "npm run lint && tsc"
|
|
11
|
+
"lint": "eslint '**/*.{ts,tsx}' --fix",
|
|
12
|
+
"build": "npm run lint && tsc && npm run copy-assets",
|
|
13
|
+
"copy-assets": "npx copyfiles -u 1 \"src/**/*.yaml\" dist/src/"
|
|
13
14
|
},
|
|
14
15
|
"repository": {
|
|
15
16
|
"type": "git"
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"eslint-plugin-import": "^2.29.1",
|
|
31
32
|
"eslint-plugin-n": "^16.6.2",
|
|
32
33
|
"eslint-plugin-promise": "^6.1.1",
|
|
34
|
+
"@types/yamljs": "^0.2.34",
|
|
33
35
|
"typescript": "^5.4.5"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
@@ -39,6 +41,9 @@
|
|
|
39
41
|
"@googleapis/drive": "^8.10.0",
|
|
40
42
|
"@googleapis/sheets": "^8.0.0",
|
|
41
43
|
"customerio-node": "^4.1.1",
|
|
42
|
-
"google-auth-library": "^9.11.0"
|
|
44
|
+
"google-auth-library": "^9.11.0",
|
|
45
|
+
"yaml": "^2.3.0",
|
|
46
|
+
"@slack/web-api": "^6.9.1",
|
|
47
|
+
"dotenv": "^16.4.5"
|
|
43
48
|
}
|
|
44
49
|
}
|