@hed-hog/core 0.0.354 → 0.0.356
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/ai/ai.service.d.ts +3 -12
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +34 -125
- package/dist/ai/ai.service.js.map +1 -1
- package/dist/core.module.d.ts.map +1 -1
- package/dist/core.module.js +3 -3
- package/dist/core.module.js.map +1 -1
- package/dist/file/file.service.d.ts +1 -1
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +50 -64
- package/dist/file/file.service.js.map +1 -1
- package/dist/file/provider/provider.enum.d.ts +2 -1
- package/dist/file/provider/provider.enum.d.ts.map +1 -1
- package/dist/file/provider/provider.enum.js +1 -0
- package/dist/file/provider/provider.enum.js.map +1 -1
- package/dist/file/provider/provider.factory.d.ts.map +1 -1
- package/dist/file/provider/provider.factory.js +3 -0
- package/dist/file/provider/provider.factory.js.map +1 -1
- package/dist/file/provider/spaces.provider.d.ts +27 -0
- package/dist/file/provider/spaces.provider.d.ts.map +1 -0
- package/dist/file/provider/spaces.provider.js +218 -0
- package/dist/file/provider/spaces.provider.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/integration-profile/dto/create.dto.d.ts +9 -0
- package/dist/integration-profile/dto/create.dto.d.ts.map +1 -0
- package/dist/integration-profile/dto/create.dto.js +54 -0
- package/dist/integration-profile/dto/create.dto.js.map +1 -0
- package/dist/integration-profile/dto/export.dto.d.ts +5 -0
- package/dist/integration-profile/dto/export.dto.d.ts.map +1 -0
- package/dist/integration-profile/dto/export.dto.js +29 -0
- package/dist/integration-profile/dto/export.dto.js.map +1 -0
- package/dist/integration-profile/dto/import-confirm.dto.d.ts +17 -0
- package/dist/integration-profile/dto/import-confirm.dto.d.ts.map +1 -0
- package/dist/integration-profile/dto/import-confirm.dto.js +77 -0
- package/dist/integration-profile/dto/import-confirm.dto.js.map +1 -0
- package/dist/integration-profile/dto/update.dto.d.ts +6 -0
- package/dist/integration-profile/dto/update.dto.d.ts.map +1 -0
- package/dist/integration-profile/dto/update.dto.js +9 -0
- package/dist/integration-profile/dto/update.dto.js.map +1 -0
- package/dist/integration-profile/integration-profile.controller.d.ts +142 -0
- package/dist/integration-profile/integration-profile.controller.d.ts.map +1 -0
- package/dist/integration-profile/integration-profile.controller.js +165 -0
- package/dist/integration-profile/integration-profile.controller.js.map +1 -0
- package/dist/integration-profile/integration-profile.module.d.ts +3 -0
- package/dist/integration-profile/integration-profile.module.d.ts.map +1 -0
- package/dist/integration-profile/integration-profile.module.js +29 -0
- package/dist/integration-profile/integration-profile.module.js.map +1 -0
- package/dist/integration-profile/integration-profile.service.d.ts +160 -0
- package/dist/integration-profile/integration-profile.service.d.ts.map +1 -0
- package/dist/integration-profile/integration-profile.service.js +606 -0
- package/dist/integration-profile/integration-profile.service.js.map +1 -0
- package/dist/integration-profile/integration-profile.utils.d.ts +24 -0
- package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -0
- package/dist/integration-profile/integration-profile.utils.js +147 -0
- package/dist/integration-profile/integration-profile.utils.js.map +1 -0
- package/dist/mail/mail.module.d.ts.map +1 -1
- package/dist/mail/mail.module.js +27 -19
- package/dist/mail/mail.module.js.map +1 -1
- package/dist/mail/mail.service.d.ts +3 -2
- package/dist/mail/mail.service.d.ts.map +1 -1
- package/dist/mail/mail.service.js +25 -47
- package/dist/mail/mail.service.js.map +1 -1
- package/dist/mcp/mcp.module.js +2 -2
- package/dist/mcp/mcp.module.js.map +1 -1
- package/dist/mcp/tools/core-mail-profile.mcp-tools.d.ts +3 -15
- package/dist/mcp/tools/core-mail-profile.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-mail-profile.mcp-tools.js +12 -94
- package/dist/mcp/tools/core-mail-profile.mcp-tools.js.map +1 -1
- package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
- package/dist/mcp-chat/mcp-chat.service.js +17 -16
- package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
- package/dist/setting/setting.service.d.ts.map +1 -1
- package/dist/setting/setting.service.js +0 -2
- package/dist/setting/setting.service.js.map +1 -1
- package/dist/webhook-integration/event-webhook.controller.d.ts +1 -0
- package/dist/webhook-integration/event-webhook.controller.d.ts.map +1 -1
- package/dist/webhook-integration/event-webhook.controller.js +10 -0
- package/dist/webhook-integration/event-webhook.controller.js.map +1 -1
- package/dist/webhook-integration/event-webhook.service.d.ts +2 -0
- package/dist/webhook-integration/event-webhook.service.d.ts.map +1 -1
- package/dist/webhook-integration/event-webhook.service.js +30 -0
- package/dist/webhook-integration/event-webhook.service.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.controller.d.ts +1 -0
- package/dist/webhook-integration/webhook-integration.controller.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.controller.js +10 -0
- package/dist/webhook-integration/webhook-integration.controller.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.d.ts +2 -1
- package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.js +62 -44
- package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
- package/dist/whatsapp-profile/dto/create.dto.d.ts +11 -0
- package/dist/whatsapp-profile/dto/create.dto.d.ts.map +1 -0
- package/dist/whatsapp-profile/dto/create.dto.js +55 -0
- package/dist/whatsapp-profile/dto/create.dto.js.map +1 -0
- package/dist/whatsapp-profile/dto/update.dto.d.ts +6 -0
- package/dist/whatsapp-profile/dto/update.dto.d.ts.map +1 -0
- package/dist/whatsapp-profile/dto/update.dto.js +9 -0
- package/dist/whatsapp-profile/dto/update.dto.js.map +1 -0
- package/dist/whatsapp-profile/whatsapp-profile.controller.d.ts +54 -0
- package/dist/whatsapp-profile/whatsapp-profile.controller.d.ts.map +1 -0
- package/dist/whatsapp-profile/whatsapp-profile.controller.js +85 -0
- package/dist/whatsapp-profile/whatsapp-profile.controller.js.map +1 -0
- package/dist/whatsapp-profile/whatsapp-profile.module.d.ts +3 -0
- package/dist/whatsapp-profile/whatsapp-profile.module.d.ts.map +1 -0
- package/dist/whatsapp-profile/whatsapp-profile.module.js +26 -0
- package/dist/whatsapp-profile/whatsapp-profile.module.js.map +1 -0
- package/dist/whatsapp-profile/whatsapp-profile.service.d.ts +63 -0
- package/dist/whatsapp-profile/whatsapp-profile.service.d.ts.map +1 -0
- package/dist/whatsapp-profile/whatsapp-profile.service.js +138 -0
- package/dist/whatsapp-profile/whatsapp-profile.service.js.map +1 -0
- package/hedhog/data/file_provider.yaml +9 -1
- package/hedhog/data/integration_provider.yaml +132 -0
- package/hedhog/data/integration_type.yaml +29 -0
- package/hedhog/data/menu.yaml +15 -14
- package/hedhog/data/role.yaml +8 -0
- package/hedhog/data/route.yaml +66 -15
- package/hedhog/data/setting_group.yaml +30 -191
- package/hedhog/data/setting_subgroup.yaml +5 -13
- package/hedhog/data/whatsapp_profile.yaml +6 -0
- package/hedhog/frontend/app/account/components/connected-accounts.tsx.ejs +25 -20
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +579 -204
- package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +1662 -0
- package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +233 -108
- package/hedhog/frontend/app/mail/profiles/page.tsx.ejs +3 -822
- package/hedhog/frontend/app/users/permissions.tsx.ejs +79 -2
- package/hedhog/frontend/app/users/user-sheet.tsx.ejs +7 -2
- package/hedhog/frontend/messages/en.json +172 -0
- package/hedhog/frontend/messages/pt.json +172 -0
- package/hedhog/table/integration_profile.yaml +34 -0
- package/hedhog/table/integration_provider.yaml +23 -0
- package/hedhog/table/integration_type.yaml +19 -0
- package/hedhog/table/webhook_action.yaml +85 -85
- package/hedhog/table/whatsapp_profile.yaml +26 -0
- package/package.json +2 -2
- package/src/ai/ai.service.ts +35 -153
- package/src/core.module.ts +3 -3
- package/src/file/file.service.ts +60 -76
- package/src/file/provider/provider.enum.ts +1 -0
- package/src/file/provider/provider.factory.ts +3 -0
- package/src/file/provider/spaces.provider.ts +261 -0
- package/src/index.ts +6 -3
- package/src/integration-profile/dto/create.dto.ts +44 -0
- package/src/integration-profile/dto/export.dto.ts +15 -0
- package/src/integration-profile/dto/import-confirm.dto.ts +61 -0
- package/src/integration-profile/dto/update.dto.ts +4 -0
- package/src/integration-profile/integration-profile.controller.ts +129 -0
- package/src/integration-profile/integration-profile.module.ts +16 -0
- package/src/integration-profile/integration-profile.service.ts +788 -0
- package/src/integration-profile/integration-profile.utils.ts +156 -0
- package/src/mail/mail.module.ts +27 -18
- package/src/mail/mail.service.ts +31 -60
- package/src/mcp/mcp.module.ts +2 -2
- package/src/mcp/tools/core-mail-profile.mcp-tools.ts +10 -69
- package/src/mcp-chat/mcp-chat.service.ts +23 -20
- package/src/setting/setting.service.ts +0 -2
- package/src/webhook-integration/event-webhook.controller.ts +55 -50
- package/src/webhook-integration/event-webhook.service.ts +422 -384
- package/src/webhook-integration/webhook-integration.controller.ts +5 -0
- package/src/webhook-integration/webhook-integration.service.ts +74 -46
- package/src/whatsapp-profile/dto/create.dto.ts +36 -0
- package/src/whatsapp-profile/dto/update.dto.ts +4 -0
- package/src/whatsapp-profile/whatsapp-profile.controller.ts +51 -0
- package/src/whatsapp-profile/whatsapp-profile.module.ts +13 -0
- package/src/whatsapp-profile/whatsapp-profile.service.ts +160 -0
|
@@ -61,6 +61,11 @@ export class WebhookIntegrationController {
|
|
|
61
61
|
return this.service.regenerateToken(id);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
@Post(':id/duplicate')
|
|
65
|
+
duplicate(@Param('id', ParseIntPipe) id: number) {
|
|
66
|
+
return this.service.duplicate(id);
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
@Get(':id/action')
|
|
65
70
|
listActions(@Param('id', ParseIntPipe) id: number) {
|
|
66
71
|
return this.service.listActions(id);
|
|
@@ -12,6 +12,11 @@ import {
|
|
|
12
12
|
import { EventEmitter } from 'events';
|
|
13
13
|
import { Request, Response } from 'express';
|
|
14
14
|
import { firstValueFrom } from 'rxjs';
|
|
15
|
+
import {
|
|
16
|
+
buildMailConfigFromIntegration,
|
|
17
|
+
getFromAddress,
|
|
18
|
+
getReplyToAddress,
|
|
19
|
+
} from '../integration-profile/integration-profile.utils';
|
|
15
20
|
import { MailService } from '../mail/mail.service';
|
|
16
21
|
import { SettingService } from '../setting/setting.service';
|
|
17
22
|
import {
|
|
@@ -203,6 +208,66 @@ export class WebhookIntegrationService {
|
|
|
203
208
|
};
|
|
204
209
|
}
|
|
205
210
|
|
|
211
|
+
async duplicate(id: number) {
|
|
212
|
+
const original = await this.get(id);
|
|
213
|
+
|
|
214
|
+
const newSlug = await this.generateUniqueSlug(original.slug, this.integrations);
|
|
215
|
+
|
|
216
|
+
let plainToken: string | null = null;
|
|
217
|
+
let tokenHash: string | null = null;
|
|
218
|
+
if (original.require_token) {
|
|
219
|
+
plainToken = createPlainToken();
|
|
220
|
+
tokenHash = hashToken(plainToken);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const record = await this.integrations.create({
|
|
224
|
+
data: {
|
|
225
|
+
slug: newSlug,
|
|
226
|
+
name: `${original.name} (copy)`,
|
|
227
|
+
description: original.description,
|
|
228
|
+
public_uuid: createPublicUuid(),
|
|
229
|
+
status: original.status,
|
|
230
|
+
require_token: original.require_token,
|
|
231
|
+
token_hash: tokenHash,
|
|
232
|
+
allowed_ips: original.allowed_ips,
|
|
233
|
+
body_schema: original.body_schema,
|
|
234
|
+
webhook_action: {
|
|
235
|
+
create: (original.webhook_action ?? []).map((a: any) => ({
|
|
236
|
+
type: a.type,
|
|
237
|
+
name: a.name,
|
|
238
|
+
order: a.order,
|
|
239
|
+
status: a.status,
|
|
240
|
+
mail_profile_id: a.mail_profile_id,
|
|
241
|
+
mail_id: a.mail_id,
|
|
242
|
+
email_to: a.email_to,
|
|
243
|
+
email_cc: a.email_cc,
|
|
244
|
+
email_bcc: a.email_bcc,
|
|
245
|
+
whatsapp_target_type: a.whatsapp_target_type,
|
|
246
|
+
whatsapp_target: a.whatsapp_target,
|
|
247
|
+
whatsapp_template: a.whatsapp_template,
|
|
248
|
+
whatsapp_instance: a.whatsapp_instance,
|
|
249
|
+
whatsapp_base_url: a.whatsapp_base_url,
|
|
250
|
+
whatsapp_token: a.whatsapp_token,
|
|
251
|
+
})),
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
return { ...(await this.withPublicUrl(record)), plainToken };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private async generateUniqueSlug(base: string, table: any): Promise<string> {
|
|
260
|
+
const candidate = `${base}-copy`;
|
|
261
|
+
const existing = await table.findUnique({ where: { slug: candidate } });
|
|
262
|
+
if (!existing) return candidate;
|
|
263
|
+
|
|
264
|
+
for (let i = 2; ; i++) {
|
|
265
|
+
const next = `${base}-copy-${i}`;
|
|
266
|
+
const taken = await table.findUnique({ where: { slug: next } });
|
|
267
|
+
if (!taken) return next;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
206
271
|
private async getApplicationBaseUrl() {
|
|
207
272
|
const settings = await this.settingService.getSettingValues([
|
|
208
273
|
'api-url',
|
|
@@ -539,8 +604,9 @@ export class WebhookIntegrationService {
|
|
|
539
604
|
private async executeEmailAction(action: any, body: any) {
|
|
540
605
|
this.validateActionConfiguration(action);
|
|
541
606
|
|
|
542
|
-
const profile = await (this.prisma as any).
|
|
607
|
+
const profile = await (this.prisma as any).integration_profile.findUnique({
|
|
543
608
|
where: { id: Number(action.mail_profile_id) },
|
|
609
|
+
include: { integration_provider: { select: { slug: true } } },
|
|
544
610
|
});
|
|
545
611
|
const mail = await (this.prisma as any).mail.findUnique({
|
|
546
612
|
where: { id: Number(action.mail_id) },
|
|
@@ -558,15 +624,12 @@ export class WebhookIntegrationService {
|
|
|
558
624
|
}
|
|
559
625
|
|
|
560
626
|
const template = mail.mail_locale[0];
|
|
561
|
-
const config =
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
? `${profile.reply_to_name} <${profile.reply_to_email}>`
|
|
568
|
-
: profile.reply_to_email
|
|
569
|
-
: undefined;
|
|
627
|
+
const config = buildMailConfigFromIntegration(
|
|
628
|
+
profile.integration_provider.slug,
|
|
629
|
+
profile.config,
|
|
630
|
+
);
|
|
631
|
+
const sender = getFromAddress(profile.config);
|
|
632
|
+
const replyTo = getReplyToAddress(profile.config);
|
|
570
633
|
|
|
571
634
|
const renderedTo = String(renderTemplate(action.email_to, body) ?? '').trim();
|
|
572
635
|
const renderedCc = action.email_cc
|
|
@@ -1098,40 +1161,5 @@ export class WebhookIntegrationService {
|
|
|
1098
1161
|
return Number(value);
|
|
1099
1162
|
}
|
|
1100
1163
|
|
|
1101
|
-
private buildMailConfig(profile: any) {
|
|
1102
|
-
switch (profile.provider) {
|
|
1103
|
-
case 'SMTP':
|
|
1104
|
-
return {
|
|
1105
|
-
global: true,
|
|
1106
|
-
type: 'SMTP',
|
|
1107
|
-
host: profile.smtp_host,
|
|
1108
|
-
port: Number(profile.smtp_port || 587),
|
|
1109
|
-
secure: Boolean(profile.smtp_secure),
|
|
1110
|
-
username: profile.smtp_username || '',
|
|
1111
|
-
password: profile.smtp_password || '',
|
|
1112
|
-
};
|
|
1113
|
-
case 'GMAIL':
|
|
1114
|
-
return {
|
|
1115
|
-
global: true,
|
|
1116
|
-
type: 'GMAIL',
|
|
1117
|
-
clientId: profile.gmail_client_id,
|
|
1118
|
-
clientSecret: profile.gmail_client_secret,
|
|
1119
|
-
refreshToken: profile.gmail_refresh_token,
|
|
1120
|
-
from: profile.from_email,
|
|
1121
|
-
};
|
|
1122
|
-
case 'SES':
|
|
1123
|
-
return {
|
|
1124
|
-
global: true,
|
|
1125
|
-
type: 'SES',
|
|
1126
|
-
region: profile.ses_region,
|
|
1127
|
-
accessKeyId: profile.ses_access_key_id,
|
|
1128
|
-
secretAccessKey: profile.ses_secret_access_key,
|
|
1129
|
-
from: profile.from_email,
|
|
1130
|
-
};
|
|
1131
|
-
default:
|
|
1132
|
-
throw new BadRequestException(
|
|
1133
|
-
`Invalid mail profile provider: ${profile.provider}`,
|
|
1134
|
-
);
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
1164
|
}
|
|
1165
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getLocaleText } from '@hed-hog/api-locale';
|
|
2
|
+
import { Transform } from 'class-transformer';
|
|
3
|
+
import { IsIn, IsString, MaxLength } from 'class-validator';
|
|
4
|
+
|
|
5
|
+
const providerOptions = ['WHATSAPP_API'] as const;
|
|
6
|
+
|
|
7
|
+
export class CreateDTO {
|
|
8
|
+
@IsString({ message: (args) => getLocaleText('validation.stringRequired', args.value) })
|
|
9
|
+
@MaxLength(127)
|
|
10
|
+
@Transform(({ value }) => String(value ?? '').trim())
|
|
11
|
+
slug: string;
|
|
12
|
+
|
|
13
|
+
@IsString({ message: (args) => getLocaleText('validation.stringRequired', args.value) })
|
|
14
|
+
@MaxLength(127)
|
|
15
|
+
@Transform(({ value }) => String(value ?? '').trim())
|
|
16
|
+
name: string;
|
|
17
|
+
|
|
18
|
+
@IsIn(providerOptions)
|
|
19
|
+
@Transform(({ value }) => String(value ?? '').trim().toUpperCase())
|
|
20
|
+
provider: (typeof providerOptions)[number];
|
|
21
|
+
|
|
22
|
+
@IsString({ message: (args) => getLocaleText('validation.stringRequired', args.value) })
|
|
23
|
+
@MaxLength(255)
|
|
24
|
+
@Transform(({ value }) => String(value ?? '').trim())
|
|
25
|
+
host: string;
|
|
26
|
+
|
|
27
|
+
@IsString({ message: (args) => getLocaleText('validation.stringRequired', args.value) })
|
|
28
|
+
@MaxLength(255)
|
|
29
|
+
@Transform(({ value }) => String(value ?? '').trim())
|
|
30
|
+
token: string;
|
|
31
|
+
|
|
32
|
+
@IsString({ message: (args) => getLocaleText('validation.stringRequired', args.value) })
|
|
33
|
+
@MaxLength(127)
|
|
34
|
+
@Transform(({ value }) => String(value ?? '').trim())
|
|
35
|
+
instance_name: string;
|
|
36
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DeleteDTO, Role } from '@hed-hog/api';
|
|
2
|
+
import { Pagination } from '@hed-hog/api-pagination';
|
|
3
|
+
import {
|
|
4
|
+
Body,
|
|
5
|
+
Controller,
|
|
6
|
+
Delete,
|
|
7
|
+
Get,
|
|
8
|
+
Inject,
|
|
9
|
+
Param,
|
|
10
|
+
ParseIntPipe,
|
|
11
|
+
Patch,
|
|
12
|
+
Post,
|
|
13
|
+
forwardRef,
|
|
14
|
+
} from '@nestjs/common';
|
|
15
|
+
import { CreateDTO } from './dto/create.dto';
|
|
16
|
+
import { UpdateDTO } from './dto/update.dto';
|
|
17
|
+
import { WhatsAppProfileService } from './whatsapp-profile.service';
|
|
18
|
+
|
|
19
|
+
@Role()
|
|
20
|
+
@Controller('whatsapp-profile')
|
|
21
|
+
export class WhatsAppProfileController {
|
|
22
|
+
constructor(
|
|
23
|
+
@Inject(forwardRef(() => WhatsAppProfileService))
|
|
24
|
+
private readonly whatsappProfileService: WhatsAppProfileService,
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
@Get()
|
|
28
|
+
async list(@Pagination() paginationParams) {
|
|
29
|
+
return this.whatsappProfileService.list(paginationParams);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Get(':id')
|
|
33
|
+
async get(@Param('id', ParseIntPipe) id: number) {
|
|
34
|
+
return this.whatsappProfileService.get(id);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Post()
|
|
38
|
+
async create(@Body() data: CreateDTO) {
|
|
39
|
+
return this.whatsappProfileService.create(data);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Patch(':id')
|
|
43
|
+
async update(@Param('id', ParseIntPipe) id: number, @Body() data: UpdateDTO) {
|
|
44
|
+
return this.whatsappProfileService.update({ id, data });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Delete()
|
|
48
|
+
async delete(@Body() data: DeleteDTO) {
|
|
49
|
+
return this.whatsappProfileService.delete(data);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PaginationModule } from '@hed-hog/api-pagination';
|
|
2
|
+
import { PrismaModule } from '@hed-hog/api-prisma';
|
|
3
|
+
import { forwardRef, Module } from '@nestjs/common';
|
|
4
|
+
import { WhatsAppProfileController } from './whatsapp-profile.controller';
|
|
5
|
+
import { WhatsAppProfileService } from './whatsapp-profile.service';
|
|
6
|
+
|
|
7
|
+
@Module({
|
|
8
|
+
imports: [forwardRef(() => PrismaModule), forwardRef(() => PaginationModule)],
|
|
9
|
+
controllers: [WhatsAppProfileController],
|
|
10
|
+
providers: [WhatsAppProfileService],
|
|
11
|
+
exports: [WhatsAppProfileService],
|
|
12
|
+
})
|
|
13
|
+
export class WhatsAppProfileModule {}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { DeleteDTO } from '@hed-hog/api';
|
|
2
|
+
import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
|
|
3
|
+
import { PrismaService } from '@hed-hog/api-prisma';
|
|
4
|
+
import {
|
|
5
|
+
BadRequestException,
|
|
6
|
+
Inject,
|
|
7
|
+
Injectable,
|
|
8
|
+
NotFoundException,
|
|
9
|
+
forwardRef,
|
|
10
|
+
} from '@nestjs/common';
|
|
11
|
+
import { CreateDTO } from './dto/create.dto';
|
|
12
|
+
import { UpdateDTO } from './dto/update.dto';
|
|
13
|
+
|
|
14
|
+
@Injectable()
|
|
15
|
+
export class WhatsAppProfileService {
|
|
16
|
+
constructor(
|
|
17
|
+
@Inject(forwardRef(() => PrismaService))
|
|
18
|
+
private readonly prismaService: PrismaService,
|
|
19
|
+
@Inject(forwardRef(() => PaginationService))
|
|
20
|
+
private readonly paginationService: PaginationService,
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
async list(paginationParams: PaginationDTO) {
|
|
24
|
+
const fields = ['slug', 'name', 'host', 'instance_name'];
|
|
25
|
+
const OR = this.prismaService.createInsensitiveSearch(fields, paginationParams);
|
|
26
|
+
|
|
27
|
+
return this.paginationService.paginate(
|
|
28
|
+
this.prismaService.whatsapp_profile,
|
|
29
|
+
paginationParams,
|
|
30
|
+
{
|
|
31
|
+
where: OR.length > 0 ? { OR } : {},
|
|
32
|
+
select: {
|
|
33
|
+
id: true,
|
|
34
|
+
slug: true,
|
|
35
|
+
name: true,
|
|
36
|
+
provider: true,
|
|
37
|
+
host: true,
|
|
38
|
+
token: true,
|
|
39
|
+
instance_name: true,
|
|
40
|
+
created_at: true,
|
|
41
|
+
updated_at: true,
|
|
42
|
+
},
|
|
43
|
+
orderBy: [{ updated_at: 'desc' }, { id: 'desc' }],
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async get(id: number) {
|
|
49
|
+
const profile = await this.prismaService.whatsapp_profile.findUnique({
|
|
50
|
+
where: { id },
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (!profile) {
|
|
54
|
+
throw new NotFoundException(`WhatsApp profile with id ${id} not found.`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return profile;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async create(data: CreateDTO) {
|
|
61
|
+
await this.ensureSlugIsAvailable(data.slug);
|
|
62
|
+
this.validateProviderFields(data as unknown as Record<string, unknown>);
|
|
63
|
+
|
|
64
|
+
return this.prismaService.whatsapp_profile.create({
|
|
65
|
+
data: this.normalizeData(data as unknown as Record<string, unknown>) as any,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async update({ id, data }: { id: number; data: UpdateDTO }) {
|
|
70
|
+
const existing = await this.prismaService.whatsapp_profile.findUnique({
|
|
71
|
+
where: { id },
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (!existing) {
|
|
75
|
+
throw new NotFoundException(`WhatsApp profile with id ${id} not found.`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (data.slug && data.slug !== existing.slug) {
|
|
79
|
+
await this.ensureSlugIsAvailable(data.slug);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const merged = {
|
|
83
|
+
...existing,
|
|
84
|
+
...data,
|
|
85
|
+
} satisfies Record<string, unknown>;
|
|
86
|
+
|
|
87
|
+
this.validateProviderFields(merged);
|
|
88
|
+
|
|
89
|
+
return this.prismaService.whatsapp_profile.update({
|
|
90
|
+
where: { id },
|
|
91
|
+
data: this.normalizeData(merged) as any,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async delete({ ids }: DeleteDTO): Promise<{ count: number }> {
|
|
96
|
+
if (!ids?.length) {
|
|
97
|
+
throw new BadRequestException('You must select at least one item to delete.');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return this.prismaService.whatsapp_profile.deleteMany({
|
|
101
|
+
where: {
|
|
102
|
+
id: {
|
|
103
|
+
in: ids,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private async ensureSlugIsAvailable(slug: string) {
|
|
110
|
+
const existing = await this.prismaService.whatsapp_profile.findUnique({
|
|
111
|
+
where: { slug },
|
|
112
|
+
select: { id: true },
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (existing) {
|
|
116
|
+
throw new BadRequestException(
|
|
117
|
+
`WhatsApp profile with slug "${slug}" already exists.`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private validateProviderFields(input: Record<string, unknown>) {
|
|
123
|
+
const provider = String(input.provider ?? '').toUpperCase();
|
|
124
|
+
|
|
125
|
+
if (!provider) {
|
|
126
|
+
throw new BadRequestException('Provider is required.');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (provider !== 'WHATSAPP_API') {
|
|
130
|
+
throw new BadRequestException(`Invalid provider: ${provider}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!String(input.host ?? '').trim()) {
|
|
134
|
+
throw new BadRequestException('WhatsApp host is required.');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!String(input.token ?? '').trim()) {
|
|
138
|
+
throw new BadRequestException('WhatsApp token is required.');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!String(input.instance_name ?? '').trim()) {
|
|
142
|
+
throw new BadRequestException('WhatsApp instance name is required.');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private normalizeData(input: Record<string, unknown>) {
|
|
147
|
+
return {
|
|
148
|
+
slug: this.normalizeString(input.slug),
|
|
149
|
+
name: this.normalizeString(input.name),
|
|
150
|
+
provider: 'WHATSAPP_API',
|
|
151
|
+
host: this.normalizeString(input.host),
|
|
152
|
+
token: this.normalizeString(input.token),
|
|
153
|
+
instance_name: this.normalizeString(input.instance_name),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private normalizeString(value: unknown) {
|
|
158
|
+
return String(value ?? '').trim();
|
|
159
|
+
}
|
|
160
|
+
}
|