@hed-hog/core 0.0.355 → 0.0.358
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/auth/guards/auth.guard.d.ts +6 -1
- package/dist/auth/guards/auth.guard.d.ts.map +1 -1
- package/dist/auth/guards/auth.guard.js +33 -2
- package/dist/auth/guards/auth.guard.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.controller.d.ts +4 -2
- package/dist/file/file.controller.d.ts.map +1 -1
- package/dist/file/file.controller.js +44 -38
- package/dist/file/file.controller.js.map +1 -1
- package/dist/file/file.service.d.ts +2 -2
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +58 -89
- package/dist/file/file.service.js.map +1 -1
- package/dist/file/provider/azure.provider.d.ts.map +1 -1
- package/dist/file/provider/azure.provider.js +10 -15
- package/dist/file/provider/azure.provider.js.map +1 -1
- package/dist/file/provider/gcs.provider.d.ts.map +1 -1
- package/dist/file/provider/gcs.provider.js +8 -9
- package/dist/file/provider/gcs.provider.js.map +1 -1
- package/dist/file/provider/local.provider.d.ts.map +1 -1
- package/dist/file/provider/local.provider.js +11 -10
- package/dist/file/provider/local.provider.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 +1 -1
- package/dist/file/provider/provider.factory.d.ts.map +1 -1
- package/dist/file/provider/provider.factory.js +18 -5
- package/dist/file/provider/provider.factory.js.map +1 -1
- package/dist/file/provider/s3.provider.d.ts.map +1 -1
- package/dist/file/provider/s3.provider.js +4 -20
- package/dist/file/provider/s3.provider.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 +203 -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.map +1 -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 +166 -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/{mail-profile/mail-profile.module.js → integration-profile/integration-profile.module.js} +11 -13
- 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 +609 -0
- package/dist/integration-profile/integration-profile.service.js.map +1 -0
- package/dist/integration-profile/integration-profile.utils.d.ts +30 -0
- package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -0
- package/dist/integration-profile/integration-profile.utils.js +156 -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 +36 -23
- package/dist/mail/mail.module.js.map +1 -1
- package/dist/mail/mail.service.d.ts +4 -2
- package/dist/mail/mail.service.d.ts.map +1 -1
- package/dist/mail/mail.service.js +33 -51
- package/dist/mail/mail.service.js.map +1 -1
- package/dist/mcp/guards/mcp-auth.guard.js +1 -1
- package/dist/mcp/guards/mcp-auth.guard.js.map +1 -1
- package/dist/mcp/mcp-api-key.controller.d.ts +2 -0
- package/dist/mcp/mcp-api-key.controller.d.ts.map +1 -1
- package/dist/mcp/mcp-api-key.controller.js +1 -1
- package/dist/mcp/mcp-api-key.controller.js.map +1 -1
- package/dist/mcp/mcp-api-key.service.d.ts +2 -1
- package/dist/mcp/mcp-api-key.service.d.ts.map +1 -1
- package/dist/mcp/mcp-api-key.service.js +6 -2
- package/dist/mcp/mcp-api-key.service.js.map +1 -1
- package/dist/mcp/mcp.module.d.ts.map +1 -1
- package/dist/mcp/mcp.module.js +3 -5
- package/dist/mcp/mcp.module.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/oauth/interfaces/OAuthProvider.d.ts +1 -1
- package/dist/oauth/interfaces/OAuthProvider.d.ts.map +1 -1
- package/dist/oauth/oauth.controller.d.ts +4 -1
- package/dist/oauth/oauth.controller.d.ts.map +1 -1
- package/dist/oauth/oauth.controller.js +31 -5
- package/dist/oauth/oauth.controller.js.map +1 -1
- package/dist/oauth/oauth.service.d.ts +12 -1
- package/dist/oauth/oauth.service.d.ts.map +1 -1
- package/dist/oauth/oauth.service.js +125 -23
- package/dist/oauth/oauth.service.js.map +1 -1
- package/dist/oauth/providers/abstract.provider.d.ts +1 -1
- package/dist/oauth/providers/abstract.provider.d.ts.map +1 -1
- package/dist/oauth/providers/facebook.provider.d.ts +5 -2
- package/dist/oauth/providers/facebook.provider.d.ts.map +1 -1
- package/dist/oauth/providers/facebook.provider.js +34 -19
- package/dist/oauth/providers/facebook.provider.js.map +1 -1
- package/dist/oauth/providers/github.provider.d.ts +6 -2
- package/dist/oauth/providers/github.provider.d.ts.map +1 -1
- package/dist/oauth/providers/github.provider.js +43 -20
- package/dist/oauth/providers/github.provider.js.map +1 -1
- package/dist/oauth/providers/google.provider.d.ts +5 -2
- package/dist/oauth/providers/google.provider.d.ts.map +1 -1
- package/dist/oauth/providers/google.provider.js +34 -19
- package/dist/oauth/providers/google.provider.js.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.d.ts +5 -2
- package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.js +43 -40
- package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
- package/dist/oauth/providers/microsoft.provider.d.ts +5 -2
- package/dist/oauth/providers/microsoft.provider.d.ts.map +1 -1
- package/dist/oauth/providers/microsoft.provider.js +34 -19
- package/dist/oauth/providers/microsoft.provider.js.map +1 -1
- package/dist/profile/profile.controller.js +1 -1
- package/dist/profile/profile.controller.js.map +1 -1
- package/dist/security/security.service.d.ts +2 -0
- package/dist/security/security.service.d.ts.map +1 -1
- package/dist/security/security.service.js +21 -0
- package/dist/security/security.service.js.map +1 -1
- package/dist/setting/setting.service.d.ts +26 -1
- package/dist/setting/setting.service.d.ts.map +1 -1
- package/dist/setting/setting.service.js +240 -7
- package/dist/setting/setting.service.js.map +1 -1
- package/dist/user/user.controller.d.ts +2 -1
- package/dist/user/user.controller.d.ts.map +1 -1
- package/dist/user/user.controller.js +5 -4
- package/dist/user/user.controller.js.map +1 -1
- package/dist/user/user.service.d.ts +4 -2
- package/dist/user/user.service.d.ts.map +1 -1
- package/dist/user/user.service.js +19 -4
- package/dist/user/user.service.js.map +1 -1
- package/dist/webhook-integration/dto/webhook-action.dto.d.ts +17 -2
- package/dist/webhook-integration/dto/webhook-action.dto.d.ts.map +1 -1
- package/dist/webhook-integration/dto/webhook-action.dto.js +93 -2
- package/dist/webhook-integration/dto/webhook-action.dto.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-command.registry.d.ts +15 -0
- package/dist/webhook-integration/webhook-command.registry.d.ts.map +1 -0
- package/dist/webhook-integration/webhook-command.registry.js +36 -0
- package/dist/webhook-integration/webhook-command.registry.js.map +1 -0
- package/dist/webhook-integration/webhook-integration.controller.d.ts +20 -0
- package/dist/webhook-integration/webhook-integration.controller.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.controller.js +48 -0
- package/dist/webhook-integration/webhook-integration.controller.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.module.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.module.js +5 -0
- package/dist/webhook-integration/webhook-integration.module.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.d.ts +27 -2
- package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.js +377 -50
- package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
- package/hedhog/data/file_provider.yaml +9 -1
- package/hedhog/data/integration_provider.yaml +148 -0
- package/hedhog/data/integration_type.yaml +29 -0
- package/hedhog/data/menu.yaml +6 -21
- package/hedhog/data/role.yaml +8 -0
- package/hedhog/data/route.yaml +73 -373
- package/hedhog/data/setting_group.yaml +209 -365
- package/hedhog/data/setting_subgroup.yaml +21 -13
- package/hedhog/frontend/app/account/components/connected-accounts.tsx.ejs +25 -20
- package/hedhog/frontend/app/account/components/tokens.tsx.ejs +421 -0
- package/hedhog/frontend/app/account/layout.tsx.ejs +6 -3
- package/hedhog/frontend/app/account/mcp-tokens/page.tsx.ejs +2 -2
- package/hedhog/frontend/app/account/tokens/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +938 -225
- package/hedhog/frontend/app/configurations/layout.tsx.ejs +1 -1
- package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +3 -1
- package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +1830 -0
- package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +829 -128
- package/hedhog/frontend/app/mail/profiles/page.tsx.ejs +1 -820
- package/hedhog/frontend/app/setting-list/page.tsx.ejs +229 -395
- 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 +239 -3
- package/hedhog/frontend/messages/pt.json +239 -3
- package/hedhog/table/file.yaml +1 -1
- 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/mcp_api_key.yaml +4 -0
- package/hedhog/table/webhook_action.yaml +141 -85
- package/package.json +4 -3
- package/src/ai/ai.service.ts +35 -153
- package/src/auth/guards/auth.guard.ts +32 -0
- package/src/core.module.ts +3 -3
- package/src/file/file.controller.ts +51 -42
- package/src/file/file.service.ts +67 -104
- package/src/file/provider/azure.provider.ts +14 -28
- package/src/file/provider/gcs.provider.ts +9 -9
- package/src/file/provider/local.provider.ts +10 -13
- package/src/file/provider/provider.enum.ts +1 -0
- package/src/file/provider/provider.factory.ts +21 -6
- package/src/file/provider/s3.provider.ts +4 -20
- package/src/file/provider/spaces.provider.ts +246 -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/integration-profile.controller.ts +131 -0
- package/src/integration-profile/integration-profile.module.ts +16 -0
- package/src/integration-profile/integration-profile.service.ts +793 -0
- package/src/integration-profile/integration-profile.utils.ts +173 -0
- package/src/mail/mail.module.ts +41 -22
- package/src/mail/mail.service.ts +40 -64
- package/src/mcp/guards/mcp-auth.guard.ts +1 -1
- package/src/mcp/mcp-api-key.controller.ts +2 -2
- package/src/mcp/mcp-api-key.service.ts +6 -2
- package/src/mcp/mcp.module.ts +3 -5
- package/src/mcp-chat/mcp-chat.service.ts +23 -20
- package/src/oauth/interfaces/OAuthProvider.ts +1 -1
- package/src/oauth/oauth.controller.ts +30 -2
- package/src/oauth/oauth.service.ts +194 -35
- package/src/oauth/providers/abstract.provider.ts +1 -1
- package/src/oauth/providers/facebook.provider.ts +36 -20
- package/src/oauth/providers/github.provider.ts +46 -23
- package/src/oauth/providers/google.provider.ts +36 -20
- package/src/oauth/providers/microsoft-entra-id.provider.ts +42 -46
- package/src/oauth/providers/microsoft.provider.ts +36 -21
- package/src/profile/profile.controller.ts +2 -2
- package/src/security/security.service.ts +34 -1
- package/src/setting/setting.service.ts +307 -9
- package/src/user/user.controller.ts +4 -1
- package/src/user/user.service.ts +20 -2
- package/src/webhook-integration/dto/webhook-action.dto.ts +85 -4
- 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-command.registry.ts +42 -0
- package/src/webhook-integration/webhook-integration.controller.ts +25 -0
- package/src/webhook-integration/webhook-integration.module.ts +50 -45
- package/src/webhook-integration/webhook-integration.service.ts +444 -53
- package/dist/mail-profile/dto/create.dto.d.ts +0 -23
- package/dist/mail-profile/dto/create.dto.d.ts.map +0 -1
- package/dist/mail-profile/dto/create.dto.js +0 -139
- package/dist/mail-profile/dto/create.dto.js.map +0 -1
- package/dist/mail-profile/dto/update.dto.d.ts.map +0 -1
- package/dist/mail-profile/dto/update.dto.js.map +0 -1
- package/dist/mail-profile/mail-profile.controller.d.ts +0 -94
- package/dist/mail-profile/mail-profile.controller.d.ts.map +0 -1
- package/dist/mail-profile/mail-profile.controller.js +0 -95
- package/dist/mail-profile/mail-profile.controller.js.map +0 -1
- package/dist/mail-profile/mail-profile.module.d.ts +0 -3
- package/dist/mail-profile/mail-profile.module.d.ts.map +0 -1
- package/dist/mail-profile/mail-profile.module.js.map +0 -1
- package/dist/mail-profile/mail-profile.service.d.ts +0 -109
- package/dist/mail-profile/mail-profile.service.d.ts.map +0 -1
- package/dist/mail-profile/mail-profile.service.js +0 -278
- package/dist/mail-profile/mail-profile.service.js.map +0 -1
- package/dist/mcp/tools/core-mail-profile.mcp-tools.d.ts +0 -32
- package/dist/mcp/tools/core-mail-profile.mcp-tools.d.ts.map +0 -1
- package/dist/mcp/tools/core-mail-profile.mcp-tools.js +0 -178
- package/dist/mcp/tools/core-mail-profile.mcp-tools.js.map +0 -1
- package/hedhog/data/mail_profile.yaml +0 -18
- package/hedhog/table/mail_profile.yaml +0 -75
- package/src/mail-profile/dto/create.dto.ts +0 -145
- package/src/mail-profile/mail-profile.controller.ts +0 -56
- package/src/mail-profile/mail-profile.module.ts +0 -18
- package/src/mail-profile/mail-profile.service.ts +0 -308
- package/src/mcp/tools/core-mail-profile.mcp-tools.ts +0 -128
- /package/dist/{mail-profile → integration-profile}/dto/update.dto.d.ts +0 -0
- /package/dist/{mail-profile → integration-profile}/dto/update.dto.js +0 -0
- /package/src/{mail-profile → integration-profile}/dto/update.dto.ts +0 -0
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
BookOpenText,
|
|
75
75
|
ChevronRight,
|
|
76
76
|
Clock3,
|
|
77
|
+
Copy,
|
|
77
78
|
GripVertical,
|
|
78
79
|
Pencil,
|
|
79
80
|
Plus,
|
|
@@ -114,11 +115,16 @@ type EventCatalog = {
|
|
|
114
115
|
|
|
115
116
|
type IncomingAction = {
|
|
116
117
|
id: number;
|
|
117
|
-
type:
|
|
118
|
+
type:
|
|
119
|
+
| 'email'
|
|
120
|
+
| 'whatsapp_evolution'
|
|
121
|
+
| 'http_request'
|
|
122
|
+
| 'internal_api'
|
|
123
|
+
| 'app_command';
|
|
118
124
|
name: string;
|
|
119
125
|
order: number;
|
|
120
126
|
status: Status;
|
|
121
|
-
|
|
127
|
+
integration_profile_id?: number | null;
|
|
122
128
|
mail_id?: number | null;
|
|
123
129
|
email_to?: string | null;
|
|
124
130
|
email_cc?: string | null;
|
|
@@ -129,6 +135,21 @@ type IncomingAction = {
|
|
|
129
135
|
whatsapp_instance?: string | null;
|
|
130
136
|
whatsapp_base_url?: string | null;
|
|
131
137
|
whatsapp_token?: string | null;
|
|
138
|
+
http_url?: string | null;
|
|
139
|
+
http_method?: string | null;
|
|
140
|
+
http_headers?: string | null;
|
|
141
|
+
http_query?: string | null;
|
|
142
|
+
http_body?: string | null;
|
|
143
|
+
http_timeout_ms?: number | null;
|
|
144
|
+
http_retry_count?: number | null;
|
|
145
|
+
internal_api_path?: string | null;
|
|
146
|
+
internal_api_method?: string | null;
|
|
147
|
+
internal_api_query?: string | null;
|
|
148
|
+
internal_api_body?: string | null;
|
|
149
|
+
internal_api_token?: string | null;
|
|
150
|
+
internal_api_user_id?: number | null;
|
|
151
|
+
app_command_slug?: string | null;
|
|
152
|
+
app_command_params?: string | null;
|
|
132
153
|
};
|
|
133
154
|
|
|
134
155
|
type IncomingActionForm = {
|
|
@@ -136,7 +157,7 @@ type IncomingActionForm = {
|
|
|
136
157
|
name: string;
|
|
137
158
|
order: number;
|
|
138
159
|
status: Status;
|
|
139
|
-
|
|
160
|
+
integration_profile_id: number | null;
|
|
140
161
|
mail_id: number | null;
|
|
141
162
|
email_to: string;
|
|
142
163
|
email_cc: string;
|
|
@@ -147,6 +168,21 @@ type IncomingActionForm = {
|
|
|
147
168
|
whatsapp_instance: string;
|
|
148
169
|
whatsapp_base_url: string;
|
|
149
170
|
whatsapp_token: string;
|
|
171
|
+
http_url: string;
|
|
172
|
+
http_method: string;
|
|
173
|
+
http_headers: string;
|
|
174
|
+
http_query: string;
|
|
175
|
+
http_body: string;
|
|
176
|
+
http_timeout_ms: number;
|
|
177
|
+
http_retry_count: number;
|
|
178
|
+
internal_api_path: string;
|
|
179
|
+
internal_api_method: string;
|
|
180
|
+
internal_api_query: string;
|
|
181
|
+
internal_api_body: string;
|
|
182
|
+
internal_api_token: string;
|
|
183
|
+
internal_api_user_id: number | null;
|
|
184
|
+
app_command_slug: string;
|
|
185
|
+
app_command_params: string;
|
|
150
186
|
};
|
|
151
187
|
|
|
152
188
|
type IncomingIntegration = {
|
|
@@ -225,22 +261,32 @@ type MailProfileDetail = {
|
|
|
225
261
|
id: number;
|
|
226
262
|
slug: string;
|
|
227
263
|
name: string;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
264
|
+
type_id: number;
|
|
265
|
+
provider_id: number;
|
|
266
|
+
config?: Record<string, unknown> | null;
|
|
267
|
+
integration_provider?: {
|
|
268
|
+
slug?: string | null;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
type IntegrationProvider = {
|
|
273
|
+
id: number;
|
|
274
|
+
slug: string;
|
|
275
|
+
type_id: number;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const EMAIL_TYPE_SLUG = 'email';
|
|
279
|
+
|
|
280
|
+
const MAIL_PROVIDER_SLUG_BY_LABEL: Record<MailProfileProvider, string> = {
|
|
281
|
+
SMTP: 'smtp',
|
|
282
|
+
GMAIL: 'gmail',
|
|
283
|
+
SES: 'ses',
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const MAIL_PROVIDER_LABEL_BY_SLUG: Record<string, MailProfileProvider> = {
|
|
287
|
+
smtp: 'SMTP',
|
|
288
|
+
gmail: 'GMAIL',
|
|
289
|
+
ses: 'SES',
|
|
244
290
|
};
|
|
245
291
|
|
|
246
292
|
type MailTemplateDetail = {
|
|
@@ -274,6 +320,51 @@ const defaultMailProfileEditForm = {
|
|
|
274
320
|
ses_region: '',
|
|
275
321
|
};
|
|
276
322
|
|
|
323
|
+
function trimString(value: unknown) {
|
|
324
|
+
return String(value ?? '').trim();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function buildMailConfigFromForm(
|
|
328
|
+
providerSlug: string,
|
|
329
|
+
form: typeof defaultMailProfileEditForm
|
|
330
|
+
) {
|
|
331
|
+
if (providerSlug === 'smtp') {
|
|
332
|
+
return {
|
|
333
|
+
host: trimString(form.smtp_host),
|
|
334
|
+
port: Number(trimString(form.smtp_port) || 587),
|
|
335
|
+
username: trimString(form.smtp_username),
|
|
336
|
+
password: trimString(form.smtp_password),
|
|
337
|
+
secure: Boolean(form.smtp_secure),
|
|
338
|
+
from_email: trimString(form.from_email),
|
|
339
|
+
from_name: trimString(form.from_name),
|
|
340
|
+
reply_to_email: trimString(form.reply_to_email),
|
|
341
|
+
reply_to_name: trimString(form.reply_to_name),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (providerSlug === 'gmail') {
|
|
346
|
+
return {
|
|
347
|
+
client_id: trimString(form.gmail_client_id),
|
|
348
|
+
client_secret: trimString(form.gmail_client_secret),
|
|
349
|
+
refresh_token: trimString(form.gmail_refresh_token),
|
|
350
|
+
from_email: trimString(form.from_email),
|
|
351
|
+
from_name: trimString(form.from_name),
|
|
352
|
+
reply_to_email: trimString(form.reply_to_email),
|
|
353
|
+
reply_to_name: trimString(form.reply_to_name),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
access_key_id: trimString(form.ses_access_key_id),
|
|
359
|
+
secret_access_key: trimString(form.ses_secret_access_key),
|
|
360
|
+
region: trimString(form.ses_region),
|
|
361
|
+
from_email: trimString(form.from_email),
|
|
362
|
+
from_name: trimString(form.from_name),
|
|
363
|
+
reply_to_email: trimString(form.reply_to_email),
|
|
364
|
+
reply_to_name: trimString(form.reply_to_name),
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
277
368
|
const defaultMailTemplateEditForm = {
|
|
278
369
|
slug: '',
|
|
279
370
|
locale_code: 'en',
|
|
@@ -317,7 +408,7 @@ const defaultActionForm: IncomingActionForm = {
|
|
|
317
408
|
name: '',
|
|
318
409
|
order: 0,
|
|
319
410
|
status: 'active' as Status,
|
|
320
|
-
|
|
411
|
+
integration_profile_id: null,
|
|
321
412
|
mail_id: null,
|
|
322
413
|
email_to: '',
|
|
323
414
|
email_cc: '',
|
|
@@ -328,6 +419,21 @@ const defaultActionForm: IncomingActionForm = {
|
|
|
328
419
|
whatsapp_instance: '',
|
|
329
420
|
whatsapp_base_url: '',
|
|
330
421
|
whatsapp_token: '',
|
|
422
|
+
http_url: '',
|
|
423
|
+
http_method: 'POST',
|
|
424
|
+
http_headers: '',
|
|
425
|
+
http_query: '',
|
|
426
|
+
http_body: '',
|
|
427
|
+
http_timeout_ms: 30000,
|
|
428
|
+
http_retry_count: 0,
|
|
429
|
+
internal_api_path: '',
|
|
430
|
+
internal_api_method: 'POST',
|
|
431
|
+
internal_api_query: '',
|
|
432
|
+
internal_api_body: '',
|
|
433
|
+
internal_api_token: '',
|
|
434
|
+
internal_api_user_id: null,
|
|
435
|
+
app_command_slug: '',
|
|
436
|
+
app_command_params: '',
|
|
331
437
|
};
|
|
332
438
|
|
|
333
439
|
const defaultEventWebhookForm = {
|
|
@@ -431,6 +537,7 @@ export default function IntegrationsWebhooksPage() {
|
|
|
431
537
|
const [incomingForm, setIncomingForm] = useState(defaultIncomingForm);
|
|
432
538
|
const [incomingSheetTab, setIncomingSheetTab] = useState('settings');
|
|
433
539
|
const [oneTimeToken, setOneTimeToken] = useState<string | null>(null);
|
|
540
|
+
const [generatedToken, setGeneratedToken] = useState<string | null>(null);
|
|
434
541
|
const [allowedIpDraft, setAllowedIpDraft] = useState('');
|
|
435
542
|
const [incomingActions, setIncomingActions] = useState<IncomingAction[]>([]);
|
|
436
543
|
const [actionSheetOpen, setActionSheetOpen] = useState(false);
|
|
@@ -493,17 +600,46 @@ export default function IntegrationsWebhooksPage() {
|
|
|
493
600
|
const { data: mailProfiles = [], refetch: refetchMailProfiles } = useQuery<
|
|
494
601
|
SelectOption[]
|
|
495
602
|
>({
|
|
496
|
-
queryKey: ['webhook-
|
|
603
|
+
queryKey: ['webhook-integration-profiles', currentLocaleCode],
|
|
497
604
|
queryFn: async () => {
|
|
498
|
-
const response = await request<{
|
|
499
|
-
|
|
605
|
+
const response = await request<{
|
|
606
|
+
data: Array<{
|
|
607
|
+
id: number;
|
|
608
|
+
slug: string;
|
|
609
|
+
name: string;
|
|
610
|
+
integration_provider?: { slug?: string | null };
|
|
611
|
+
}>;
|
|
612
|
+
}>({
|
|
613
|
+
url: '/integration-profile?pageSize=100&typeSlug=email',
|
|
500
614
|
method: 'GET',
|
|
501
615
|
});
|
|
502
|
-
return response.data.data || []
|
|
616
|
+
return (response.data.data || []).map((item) => ({
|
|
617
|
+
id: item.id,
|
|
618
|
+
slug: item.slug,
|
|
619
|
+
name: item.name,
|
|
620
|
+
provider: String(item.integration_provider?.slug ?? ''),
|
|
621
|
+
}));
|
|
503
622
|
},
|
|
504
623
|
placeholderData: (previous) => previous ?? [],
|
|
505
624
|
});
|
|
506
625
|
|
|
626
|
+
const resolveEmailProviderMeta = async (providerSlug: string) => {
|
|
627
|
+
const response = await request<IntegrationProvider[]>({
|
|
628
|
+
url: `/integration-profile/providers?typeSlug=${EMAIL_TYPE_SLUG}`,
|
|
629
|
+
method: 'GET',
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
const provider = (response.data ?? []).find(
|
|
633
|
+
(item) => item.slug === providerSlug
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
if (!provider) {
|
|
637
|
+
throw new Error(`Integration provider "${providerSlug}" not found.`);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return provider;
|
|
641
|
+
};
|
|
642
|
+
|
|
507
643
|
const { data: mailTemplates = [], refetch: refetchMailTemplates } = useQuery<
|
|
508
644
|
SelectOption[]
|
|
509
645
|
>({
|
|
@@ -518,6 +654,56 @@ export default function IntegrationsWebhooksPage() {
|
|
|
518
654
|
placeholderData: (previous) => previous ?? [],
|
|
519
655
|
});
|
|
520
656
|
|
|
657
|
+
const { data: appCommands = [] } = useQuery<
|
|
658
|
+
Array<{
|
|
659
|
+
slug: string;
|
|
660
|
+
name: string;
|
|
661
|
+
description: string;
|
|
662
|
+
inputSchema: Record<string, unknown>;
|
|
663
|
+
}>
|
|
664
|
+
>({
|
|
665
|
+
queryKey: ['webhook-app-commands'],
|
|
666
|
+
queryFn: async () => {
|
|
667
|
+
const response = await request<
|
|
668
|
+
Array<{
|
|
669
|
+
slug: string;
|
|
670
|
+
name: string;
|
|
671
|
+
description: string;
|
|
672
|
+
inputSchema: Record<string, unknown>;
|
|
673
|
+
}>
|
|
674
|
+
>({
|
|
675
|
+
url: '/webhook-integration/app-commands',
|
|
676
|
+
method: 'GET',
|
|
677
|
+
});
|
|
678
|
+
return response.data || [];
|
|
679
|
+
},
|
|
680
|
+
placeholderData: (previous) => previous ?? [],
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
const { data: internalRoutes = [] } = useQuery<
|
|
684
|
+
Array<{
|
|
685
|
+
id: number;
|
|
686
|
+
url: string;
|
|
687
|
+
method: string;
|
|
688
|
+
}>
|
|
689
|
+
>({
|
|
690
|
+
queryKey: ['webhook-internal-routes'],
|
|
691
|
+
queryFn: async () => {
|
|
692
|
+
const response = await request<
|
|
693
|
+
Array<{
|
|
694
|
+
id: number;
|
|
695
|
+
url: string;
|
|
696
|
+
method: string;
|
|
697
|
+
}>
|
|
698
|
+
>({
|
|
699
|
+
url: '/webhook-integration/internal-routes',
|
|
700
|
+
method: 'GET',
|
|
701
|
+
});
|
|
702
|
+
return response.data || [];
|
|
703
|
+
},
|
|
704
|
+
placeholderData: (previous) => previous ?? [],
|
|
705
|
+
});
|
|
706
|
+
|
|
521
707
|
const { data: incomingLogsResult, isFetching: isFetchingIncomingLogs } =
|
|
522
708
|
useQuery<PaginatedResponse<IncomingCallLog>>({
|
|
523
709
|
queryKey: [
|
|
@@ -765,6 +951,7 @@ export default function IntegrationsWebhooksPage() {
|
|
|
765
951
|
|
|
766
952
|
const openActionCreate = () => {
|
|
767
953
|
setActionEdit(null);
|
|
954
|
+
setGeneratedToken(null);
|
|
768
955
|
setActionForm({
|
|
769
956
|
...defaultActionForm,
|
|
770
957
|
order: incomingActions.length,
|
|
@@ -774,12 +961,13 @@ export default function IntegrationsWebhooksPage() {
|
|
|
774
961
|
|
|
775
962
|
const openActionEdit = (action: IncomingAction) => {
|
|
776
963
|
setActionEdit(action);
|
|
964
|
+
setGeneratedToken(null);
|
|
777
965
|
setActionForm({
|
|
778
966
|
type: action.type,
|
|
779
967
|
name: action.name,
|
|
780
968
|
order: Number(action.order || 0),
|
|
781
969
|
status: action.status,
|
|
782
|
-
|
|
970
|
+
integration_profile_id: action.integration_profile_id ?? null,
|
|
783
971
|
mail_id: action.mail_id ?? null,
|
|
784
972
|
email_to: action.email_to || '',
|
|
785
973
|
email_cc: action.email_cc || '',
|
|
@@ -790,6 +978,31 @@ export default function IntegrationsWebhooksPage() {
|
|
|
790
978
|
whatsapp_instance: action.whatsapp_instance || '',
|
|
791
979
|
whatsapp_base_url: action.whatsapp_base_url || '',
|
|
792
980
|
whatsapp_token: action.whatsapp_token || '',
|
|
981
|
+
http_url: action.http_url || '',
|
|
982
|
+
http_method: action.http_method || 'POST',
|
|
983
|
+
http_headers: action.http_headers
|
|
984
|
+
? JSON.stringify(action.http_headers, null, 2)
|
|
985
|
+
: '',
|
|
986
|
+
http_query: action.http_query
|
|
987
|
+
? JSON.stringify(action.http_query, null, 2)
|
|
988
|
+
: '',
|
|
989
|
+
http_body: action.http_body || '',
|
|
990
|
+
http_timeout_ms: action.http_timeout_ms ?? 30000,
|
|
991
|
+
http_retry_count: action.http_retry_count ?? 0,
|
|
992
|
+
internal_api_path: action.internal_api_path || '',
|
|
993
|
+
internal_api_method: action.internal_api_method || 'POST',
|
|
994
|
+
internal_api_query: action.internal_api_query
|
|
995
|
+
? JSON.stringify(action.internal_api_query, null, 2)
|
|
996
|
+
: '',
|
|
997
|
+
internal_api_body: action.internal_api_body
|
|
998
|
+
? JSON.stringify(action.internal_api_body, null, 2)
|
|
999
|
+
: '',
|
|
1000
|
+
internal_api_token: action.internal_api_token || '',
|
|
1001
|
+
internal_api_user_id: action.internal_api_user_id ?? null,
|
|
1002
|
+
app_command_slug: action.app_command_slug || '',
|
|
1003
|
+
app_command_params: action.app_command_params
|
|
1004
|
+
? JSON.stringify(action.app_command_params, null, 2)
|
|
1005
|
+
: '',
|
|
793
1006
|
});
|
|
794
1007
|
setActionSheetOpen(true);
|
|
795
1008
|
};
|
|
@@ -797,31 +1010,33 @@ export default function IntegrationsWebhooksPage() {
|
|
|
797
1010
|
const openMailProfileEditor = async (id: number) => {
|
|
798
1011
|
try {
|
|
799
1012
|
const response = await request<MailProfileDetail>({
|
|
800
|
-
url: `/
|
|
1013
|
+
url: `/integration-profile/${id}`,
|
|
801
1014
|
method: 'GET',
|
|
802
1015
|
});
|
|
803
1016
|
|
|
804
1017
|
const data = response.data;
|
|
1018
|
+
const config = (data.config as Record<string, unknown> | null) ?? {};
|
|
1019
|
+
const providerSlug = String(data.integration_provider?.slug ?? 'smtp');
|
|
805
1020
|
setMailProfileEditId(data.id);
|
|
806
1021
|
setMailProfileEditForm({
|
|
807
1022
|
slug: data.slug || '',
|
|
808
1023
|
name: data.name || '',
|
|
809
|
-
provider:
|
|
810
|
-
from_name:
|
|
811
|
-
from_email:
|
|
812
|
-
reply_to_name:
|
|
813
|
-
reply_to_email:
|
|
814
|
-
smtp_host:
|
|
815
|
-
smtp_port:
|
|
816
|
-
smtp_secure: Boolean(
|
|
817
|
-
smtp_username:
|
|
818
|
-
smtp_password:
|
|
819
|
-
gmail_client_id:
|
|
820
|
-
gmail_client_secret:
|
|
821
|
-
gmail_refresh_token:
|
|
822
|
-
ses_access_key_id:
|
|
823
|
-
ses_secret_access_key:
|
|
824
|
-
ses_region:
|
|
1024
|
+
provider: MAIL_PROVIDER_LABEL_BY_SLUG[providerSlug] || 'SMTP',
|
|
1025
|
+
from_name: String(config.from_name ?? ''),
|
|
1026
|
+
from_email: String(config.from_email ?? ''),
|
|
1027
|
+
reply_to_name: String(config.reply_to_name ?? ''),
|
|
1028
|
+
reply_to_email: String(config.reply_to_email ?? ''),
|
|
1029
|
+
smtp_host: String(config.host ?? ''),
|
|
1030
|
+
smtp_port: String(config.port ?? '587'),
|
|
1031
|
+
smtp_secure: Boolean(config.secure),
|
|
1032
|
+
smtp_username: String(config.username ?? ''),
|
|
1033
|
+
smtp_password: String(config.password ?? ''),
|
|
1034
|
+
gmail_client_id: String(config.client_id ?? ''),
|
|
1035
|
+
gmail_client_secret: String(config.client_secret ?? ''),
|
|
1036
|
+
gmail_refresh_token: String(config.refresh_token ?? ''),
|
|
1037
|
+
ses_access_key_id: String(config.access_key_id ?? ''),
|
|
1038
|
+
ses_secret_access_key: String(config.secret_access_key ?? ''),
|
|
1039
|
+
ses_region: String(config.region ?? ''),
|
|
825
1040
|
});
|
|
826
1041
|
setMailProfileTestedSignature(null);
|
|
827
1042
|
setMailProfileEditorOpen(true);
|
|
@@ -830,57 +1045,51 @@ export default function IntegrationsWebhooksPage() {
|
|
|
830
1045
|
}
|
|
831
1046
|
};
|
|
832
1047
|
|
|
833
|
-
const createMailProfilePayload = () =>
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
provider
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
:
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
smtp_password: mailProfileEditForm.smtp_password || undefined,
|
|
848
|
-
gmail_client_id: mailProfileEditForm.gmail_client_id || undefined,
|
|
849
|
-
gmail_client_secret: mailProfileEditForm.gmail_client_secret || undefined,
|
|
850
|
-
gmail_refresh_token: mailProfileEditForm.gmail_refresh_token || undefined,
|
|
851
|
-
ses_access_key_id: mailProfileEditForm.ses_access_key_id || undefined,
|
|
852
|
-
ses_secret_access_key:
|
|
853
|
-
mailProfileEditForm.ses_secret_access_key || undefined,
|
|
854
|
-
ses_region: mailProfileEditForm.ses_region || undefined,
|
|
855
|
-
});
|
|
1048
|
+
const createMailProfilePayload = async () => {
|
|
1049
|
+
const providerSlug =
|
|
1050
|
+
MAIL_PROVIDER_SLUG_BY_LABEL[mailProfileEditForm.provider] ?? 'smtp';
|
|
1051
|
+
const provider = await resolveEmailProviderMeta(providerSlug);
|
|
1052
|
+
|
|
1053
|
+
return {
|
|
1054
|
+
slug: trimString(mailProfileEditForm.slug),
|
|
1055
|
+
name: trimString(mailProfileEditForm.name),
|
|
1056
|
+
type_id: provider.type_id,
|
|
1057
|
+
provider_id: provider.id,
|
|
1058
|
+
config: buildMailConfigFromForm(providerSlug, mailProfileEditForm),
|
|
1059
|
+
is_active: true,
|
|
1060
|
+
};
|
|
1061
|
+
};
|
|
856
1062
|
|
|
857
|
-
const currentMailProfileSignature = JSON.stringify(
|
|
858
|
-
createMailProfilePayload()
|
|
859
|
-
);
|
|
1063
|
+
const currentMailProfileSignature = JSON.stringify(mailProfileEditForm);
|
|
860
1064
|
const canSubmitMailProfile =
|
|
861
1065
|
mailProfileTestedSignature === currentMailProfileSignature;
|
|
862
1066
|
|
|
863
1067
|
const handleTestMailProfile = async () => {
|
|
864
|
-
const payload = createMailProfilePayload();
|
|
1068
|
+
const payload = await createMailProfilePayload();
|
|
865
1069
|
|
|
866
1070
|
try {
|
|
867
1071
|
setMailProfileIsTesting(true);
|
|
868
1072
|
const { data } = await request<{ success: boolean; destination: string }>(
|
|
869
1073
|
{
|
|
870
|
-
url: '/
|
|
1074
|
+
url: '/integration-profile/test',
|
|
871
1075
|
method: 'POST',
|
|
872
1076
|
data: payload,
|
|
873
1077
|
}
|
|
874
1078
|
);
|
|
875
1079
|
|
|
876
|
-
|
|
1080
|
+
const fallbackFromEmail =
|
|
1081
|
+
payload.config && typeof payload.config === 'object'
|
|
1082
|
+
? String((payload.config as Record<string, unknown>).from_email ?? '')
|
|
1083
|
+
: '';
|
|
1084
|
+
|
|
1085
|
+
setMailProfileTestedSignature(currentMailProfileSignature);
|
|
877
1086
|
toast.success(
|
|
878
|
-
data.destination ||
|
|
879
|
-
? `Perfil testado com sucesso para ${data.destination ||
|
|
1087
|
+
data.destination || fallbackFromEmail
|
|
1088
|
+
? `Perfil testado com sucesso para ${data.destination || fallbackFromEmail}`
|
|
880
1089
|
: 'Perfil testado com sucesso.'
|
|
881
1090
|
);
|
|
882
1091
|
} catch (error) {
|
|
883
|
-
console.error('Error testing
|
|
1092
|
+
console.error('Error testing integration profile:', error);
|
|
884
1093
|
setMailProfileTestedSignature(null);
|
|
885
1094
|
toast.error('Erro ao testar o perfil de e-mail.');
|
|
886
1095
|
} finally {
|
|
@@ -890,36 +1099,13 @@ export default function IntegrationsWebhooksPage() {
|
|
|
890
1099
|
|
|
891
1100
|
const saveMailProfileEditor = async () => {
|
|
892
1101
|
if (!mailProfileEditId) return;
|
|
1102
|
+
const payload = await createMailProfilePayload();
|
|
893
1103
|
|
|
894
1104
|
try {
|
|
895
1105
|
await request({
|
|
896
|
-
url: `/
|
|
1106
|
+
url: `/integration-profile/${mailProfileEditId}`,
|
|
897
1107
|
method: 'PATCH',
|
|
898
|
-
data:
|
|
899
|
-
slug: mailProfileEditForm.slug,
|
|
900
|
-
name: mailProfileEditForm.name,
|
|
901
|
-
provider: mailProfileEditForm.provider,
|
|
902
|
-
from_name: mailProfileEditForm.from_name || undefined,
|
|
903
|
-
from_email: mailProfileEditForm.from_email,
|
|
904
|
-
reply_to_name: mailProfileEditForm.reply_to_name || undefined,
|
|
905
|
-
reply_to_email: mailProfileEditForm.reply_to_email || undefined,
|
|
906
|
-
smtp_host: mailProfileEditForm.smtp_host || undefined,
|
|
907
|
-
smtp_port: mailProfileEditForm.smtp_port
|
|
908
|
-
? Number(mailProfileEditForm.smtp_port)
|
|
909
|
-
: undefined,
|
|
910
|
-
smtp_secure: mailProfileEditForm.smtp_secure,
|
|
911
|
-
smtp_username: mailProfileEditForm.smtp_username || undefined,
|
|
912
|
-
smtp_password: mailProfileEditForm.smtp_password || undefined,
|
|
913
|
-
gmail_client_id: mailProfileEditForm.gmail_client_id || undefined,
|
|
914
|
-
gmail_client_secret:
|
|
915
|
-
mailProfileEditForm.gmail_client_secret || undefined,
|
|
916
|
-
gmail_refresh_token:
|
|
917
|
-
mailProfileEditForm.gmail_refresh_token || undefined,
|
|
918
|
-
ses_access_key_id: mailProfileEditForm.ses_access_key_id || undefined,
|
|
919
|
-
ses_secret_access_key:
|
|
920
|
-
mailProfileEditForm.ses_secret_access_key || undefined,
|
|
921
|
-
ses_region: mailProfileEditForm.ses_region || undefined,
|
|
922
|
-
},
|
|
1108
|
+
data: payload,
|
|
923
1109
|
});
|
|
924
1110
|
|
|
925
1111
|
await refetchMailProfiles();
|
|
@@ -1076,8 +1262,8 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1076
1262
|
const missingFields: string[] = [];
|
|
1077
1263
|
|
|
1078
1264
|
if (actionForm.type === 'email') {
|
|
1079
|
-
if (actionForm.
|
|
1080
|
-
missingFields.push('
|
|
1265
|
+
if (actionForm.integration_profile_id == null)
|
|
1266
|
+
missingFields.push('integration_profile_id');
|
|
1081
1267
|
if (actionForm.mail_id == null) missingFields.push('mail_id');
|
|
1082
1268
|
if (!actionForm.email_to.trim()) missingFields.push('email_to');
|
|
1083
1269
|
}
|
|
@@ -1100,6 +1286,24 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1100
1286
|
}
|
|
1101
1287
|
}
|
|
1102
1288
|
|
|
1289
|
+
if (actionForm.type === 'http_request') {
|
|
1290
|
+
if (!actionForm.http_url.trim()) missingFields.push('http_url');
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
if (actionForm.type === 'internal_api') {
|
|
1294
|
+
if (!actionForm.internal_api_path.trim())
|
|
1295
|
+
missingFields.push('internal_api_path');
|
|
1296
|
+
if (actionForm.internal_api_user_id == null)
|
|
1297
|
+
missingFields.push('internal_api_user_id');
|
|
1298
|
+
if (!actionForm.internal_api_token.trim())
|
|
1299
|
+
missingFields.push('internal_api_token');
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
if (actionForm.type === 'app_command') {
|
|
1303
|
+
if (!actionForm.app_command_slug.trim())
|
|
1304
|
+
missingFields.push('app_command_slug');
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1103
1307
|
if (missingFields.length) {
|
|
1104
1308
|
toast.error(
|
|
1105
1309
|
`Preencha os campos obrigatorios da acao: ${missingFields.join(', ')}`
|
|
@@ -1111,7 +1315,7 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1111
1315
|
const payload = {
|
|
1112
1316
|
...actionForm,
|
|
1113
1317
|
order: Number(actionForm.order || 0),
|
|
1114
|
-
|
|
1318
|
+
integration_profile_id: actionForm.integration_profile_id,
|
|
1115
1319
|
mail_id: actionForm.mail_id,
|
|
1116
1320
|
email_to: actionForm.email_to.trim(),
|
|
1117
1321
|
email_cc: actionForm.email_cc.trim(),
|
|
@@ -1121,6 +1325,61 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1121
1325
|
whatsapp_instance: actionForm.whatsapp_instance.trim(),
|
|
1122
1326
|
whatsapp_base_url: actionForm.whatsapp_base_url.trim(),
|
|
1123
1327
|
whatsapp_token: actionForm.whatsapp_token.trim(),
|
|
1328
|
+
http_url: actionForm.http_url.trim() || undefined,
|
|
1329
|
+
http_method: actionForm.http_method || 'POST',
|
|
1330
|
+
http_headers: actionForm.http_headers.trim()
|
|
1331
|
+
? (() => {
|
|
1332
|
+
try {
|
|
1333
|
+
return JSON.parse(actionForm.http_headers);
|
|
1334
|
+
} catch {
|
|
1335
|
+
return undefined;
|
|
1336
|
+
}
|
|
1337
|
+
})()
|
|
1338
|
+
: undefined,
|
|
1339
|
+
http_query: actionForm.http_query.trim()
|
|
1340
|
+
? (() => {
|
|
1341
|
+
try {
|
|
1342
|
+
return JSON.parse(actionForm.http_query);
|
|
1343
|
+
} catch {
|
|
1344
|
+
return undefined;
|
|
1345
|
+
}
|
|
1346
|
+
})()
|
|
1347
|
+
: undefined,
|
|
1348
|
+
http_body: actionForm.http_body.trim() || undefined,
|
|
1349
|
+
http_timeout_ms: actionForm.http_timeout_ms || undefined,
|
|
1350
|
+
http_retry_count: actionForm.http_retry_count ?? 0,
|
|
1351
|
+
internal_api_path: actionForm.internal_api_path.trim() || undefined,
|
|
1352
|
+
internal_api_method: actionForm.internal_api_method || 'POST',
|
|
1353
|
+
internal_api_query: actionForm.internal_api_query.trim()
|
|
1354
|
+
? (() => {
|
|
1355
|
+
try {
|
|
1356
|
+
return JSON.parse(actionForm.internal_api_query);
|
|
1357
|
+
} catch {
|
|
1358
|
+
return undefined;
|
|
1359
|
+
}
|
|
1360
|
+
})()
|
|
1361
|
+
: undefined,
|
|
1362
|
+
internal_api_body: actionForm.internal_api_body.trim()
|
|
1363
|
+
? (() => {
|
|
1364
|
+
try {
|
|
1365
|
+
return JSON.parse(actionForm.internal_api_body);
|
|
1366
|
+
} catch {
|
|
1367
|
+
return undefined;
|
|
1368
|
+
}
|
|
1369
|
+
})()
|
|
1370
|
+
: undefined,
|
|
1371
|
+
internal_api_token: actionForm.internal_api_token.trim() || undefined,
|
|
1372
|
+
internal_api_user_id: actionForm.internal_api_user_id ?? undefined,
|
|
1373
|
+
app_command_slug: actionForm.app_command_slug.trim() || undefined,
|
|
1374
|
+
app_command_params: actionForm.app_command_params.trim()
|
|
1375
|
+
? (() => {
|
|
1376
|
+
try {
|
|
1377
|
+
return JSON.parse(actionForm.app_command_params);
|
|
1378
|
+
} catch {
|
|
1379
|
+
return undefined;
|
|
1380
|
+
}
|
|
1381
|
+
})()
|
|
1382
|
+
: undefined,
|
|
1124
1383
|
};
|
|
1125
1384
|
|
|
1126
1385
|
if (actionEdit) {
|
|
@@ -1141,6 +1400,7 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1141
1400
|
|
|
1142
1401
|
setActionEdit(null);
|
|
1143
1402
|
setActionSheetOpen(false);
|
|
1403
|
+
setGeneratedToken(null);
|
|
1144
1404
|
setActionForm(defaultActionForm);
|
|
1145
1405
|
await openIncomingEdit(incomingEdit);
|
|
1146
1406
|
await incoming.refetch();
|
|
@@ -1221,6 +1481,16 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1221
1481
|
await incoming.refetch();
|
|
1222
1482
|
};
|
|
1223
1483
|
|
|
1484
|
+
const duplicateIncoming = async (item: IncomingIntegration) => {
|
|
1485
|
+
const response = await request<IncomingIntegration>({
|
|
1486
|
+
url: `/webhook-integration/${item.id}/duplicate`,
|
|
1487
|
+
method: 'POST',
|
|
1488
|
+
});
|
|
1489
|
+
toast.success(t('duplicated'));
|
|
1490
|
+
await incoming.refetch();
|
|
1491
|
+
await openIncomingEdit(response.data);
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1224
1494
|
const openEventWebhookCreate = () => {
|
|
1225
1495
|
setEventWebhookEdit(null);
|
|
1226
1496
|
setEventWebhookForm(defaultEventWebhookForm);
|
|
@@ -1255,6 +1525,16 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1255
1525
|
setEventWebhookOpen(true);
|
|
1256
1526
|
};
|
|
1257
1527
|
|
|
1528
|
+
const duplicateEventWebhook = async (item: EventWebhook) => {
|
|
1529
|
+
const response = await request<EventWebhook>({
|
|
1530
|
+
url: `/event-webhook/${item.id}/duplicate`,
|
|
1531
|
+
method: 'POST',
|
|
1532
|
+
});
|
|
1533
|
+
toast.success(t('duplicated'));
|
|
1534
|
+
await eventWebhooks.refetch();
|
|
1535
|
+
await openEventWebhookEdit(response.data);
|
|
1536
|
+
};
|
|
1537
|
+
|
|
1258
1538
|
const saveEventWebhook = async () => {
|
|
1259
1539
|
try {
|
|
1260
1540
|
const payload = {
|
|
@@ -1563,6 +1843,13 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1563
1843
|
>
|
|
1564
1844
|
<Pencil className="h-4 w-4" />
|
|
1565
1845
|
</Button>
|
|
1846
|
+
<Button
|
|
1847
|
+
variant="ghost"
|
|
1848
|
+
size="icon"
|
|
1849
|
+
onClick={() => duplicateIncoming(item)}
|
|
1850
|
+
>
|
|
1851
|
+
<Copy className="h-4 w-4" />
|
|
1852
|
+
</Button>
|
|
1566
1853
|
<Button
|
|
1567
1854
|
variant="ghost"
|
|
1568
1855
|
size="icon"
|
|
@@ -1672,6 +1959,13 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1672
1959
|
>
|
|
1673
1960
|
<Pencil className="h-4 w-4" />
|
|
1674
1961
|
</Button>
|
|
1962
|
+
<Button
|
|
1963
|
+
variant="ghost"
|
|
1964
|
+
size="icon"
|
|
1965
|
+
onClick={() => duplicateEventWebhook(item)}
|
|
1966
|
+
>
|
|
1967
|
+
<Copy className="h-4 w-4" />
|
|
1968
|
+
</Button>
|
|
1675
1969
|
<Button
|
|
1676
1970
|
variant="ghost"
|
|
1677
1971
|
size="icon"
|
|
@@ -1707,7 +2001,10 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1707
2001
|
</Tabs>
|
|
1708
2002
|
|
|
1709
2003
|
<Sheet open={catalogOpen} onOpenChange={setCatalogOpen}>
|
|
1710
|
-
<ResizableSheetContent
|
|
2004
|
+
<ResizableSheetContent
|
|
2005
|
+
sheetId="webhooks-catalog-form"
|
|
2006
|
+
defaultWidth={672}
|
|
2007
|
+
>
|
|
1711
2008
|
<SheetHeader>
|
|
1712
2009
|
<SheetTitle>
|
|
1713
2010
|
{catalogEdit ? t('editEvent') : t('newEvent')}
|
|
@@ -1782,7 +2079,10 @@ export default function IntegrationsWebhooksPage() {
|
|
|
1782
2079
|
}
|
|
1783
2080
|
}}
|
|
1784
2081
|
>
|
|
1785
|
-
<ResizableSheetContent
|
|
2082
|
+
<ResizableSheetContent
|
|
2083
|
+
sheetId="webhooks-incoming-form"
|
|
2084
|
+
defaultWidth={1024}
|
|
2085
|
+
>
|
|
1786
2086
|
<SheetHeader>
|
|
1787
2087
|
<SheetTitle>
|
|
1788
2088
|
{incomingEdit ? t('editIncoming') : t('newIncoming')}
|
|
@@ -2268,11 +2568,15 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2268
2568
|
setActionSheetOpen(open);
|
|
2269
2569
|
if (!open) {
|
|
2270
2570
|
setActionEdit(null);
|
|
2571
|
+
setGeneratedToken(null);
|
|
2271
2572
|
setActionForm(defaultActionForm);
|
|
2272
2573
|
}
|
|
2273
2574
|
}}
|
|
2274
2575
|
>
|
|
2275
|
-
<ResizableSheetContent
|
|
2576
|
+
<ResizableSheetContent
|
|
2577
|
+
sheetId="webhooks-action-form"
|
|
2578
|
+
defaultWidth={768}
|
|
2579
|
+
>
|
|
2276
2580
|
<SheetHeader>
|
|
2277
2581
|
<SheetTitle>
|
|
2278
2582
|
{actionEdit ? t('updated') : t('addAction')}
|
|
@@ -2296,6 +2600,13 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2296
2600
|
<SelectItem value="whatsapp_evolution">
|
|
2297
2601
|
{t('whatsapp')}
|
|
2298
2602
|
</SelectItem>
|
|
2603
|
+
<SelectItem value="http_request">
|
|
2604
|
+
HTTP Request
|
|
2605
|
+
</SelectItem>
|
|
2606
|
+
<SelectItem value="internal_api">
|
|
2607
|
+
Internal API
|
|
2608
|
+
</SelectItem>
|
|
2609
|
+
<SelectItem value="app_command">App Command</SelectItem>
|
|
2299
2610
|
</SelectContent>
|
|
2300
2611
|
</Select>
|
|
2301
2612
|
</Field>
|
|
@@ -2324,12 +2635,12 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2324
2635
|
</Field>
|
|
2325
2636
|
</div>
|
|
2326
2637
|
|
|
2327
|
-
{actionForm.type === 'email'
|
|
2638
|
+
{actionForm.type === 'email' && (
|
|
2328
2639
|
<div className="grid gap-3 md:grid-cols-2">
|
|
2329
2640
|
<Field label={t('mailProfile')}>
|
|
2330
2641
|
<div className="flex items-start gap-2">
|
|
2331
2642
|
<EntityPicker<SelectOption>
|
|
2332
|
-
value={actionForm.
|
|
2643
|
+
value={actionForm.integration_profile_id}
|
|
2333
2644
|
className="w-full"
|
|
2334
2645
|
valueType="number"
|
|
2335
2646
|
placeholder={t('select')}
|
|
@@ -2337,14 +2648,28 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2337
2648
|
options={mailProfiles}
|
|
2338
2649
|
loadOptions={async ({ page, pageSize, search }) => {
|
|
2339
2650
|
const response = await request<{
|
|
2340
|
-
data:
|
|
2651
|
+
data: Array<{
|
|
2652
|
+
id: number;
|
|
2653
|
+
slug: string;
|
|
2654
|
+
name: string;
|
|
2655
|
+
integration_provider?: { slug?: string | null };
|
|
2656
|
+
}>;
|
|
2341
2657
|
}>({
|
|
2342
|
-
url: `/
|
|
2658
|
+
url: `/integration-profile?page=${page}&pageSize=${pageSize}&typeSlug=email&search=${encodeURIComponent(search)}`,
|
|
2343
2659
|
method: 'GET',
|
|
2344
2660
|
});
|
|
2345
2661
|
|
|
2346
2662
|
return {
|
|
2347
|
-
items: response.data?.data || []
|
|
2663
|
+
items: (response.data?.data || []).map(
|
|
2664
|
+
(item) => ({
|
|
2665
|
+
id: item.id,
|
|
2666
|
+
slug: item.slug,
|
|
2667
|
+
name: item.name,
|
|
2668
|
+
provider: String(
|
|
2669
|
+
item.integration_provider?.slug ?? ''
|
|
2670
|
+
),
|
|
2671
|
+
})
|
|
2672
|
+
),
|
|
2348
2673
|
hasMore: false,
|
|
2349
2674
|
};
|
|
2350
2675
|
}}
|
|
@@ -2399,19 +2724,25 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2399
2724
|
createTitle="Criar perfil de e-mail"
|
|
2400
2725
|
createDescription="Crie rapidamente um perfil SMTP para usar nesta ação."
|
|
2401
2726
|
onCreate={async (values) => {
|
|
2727
|
+
const provider =
|
|
2728
|
+
await resolveEmailProviderMeta('smtp');
|
|
2402
2729
|
const response = await request<SelectOption>({
|
|
2403
|
-
url: '/
|
|
2730
|
+
url: '/integration-profile',
|
|
2404
2731
|
method: 'POST',
|
|
2405
2732
|
data: {
|
|
2406
2733
|
slug: values.slug,
|
|
2407
2734
|
name: values.name,
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2735
|
+
type_id: provider.type_id,
|
|
2736
|
+
provider_id: provider.id,
|
|
2737
|
+
config: {
|
|
2738
|
+
from_email: values.from_email,
|
|
2739
|
+
host: values.smtp_host,
|
|
2740
|
+
port: Number(values.smtp_port || 587),
|
|
2741
|
+
secure: false,
|
|
2742
|
+
username: values.smtp_username,
|
|
2743
|
+
password: values.smtp_password,
|
|
2744
|
+
},
|
|
2745
|
+
is_active: true,
|
|
2415
2746
|
},
|
|
2416
2747
|
});
|
|
2417
2748
|
|
|
@@ -2427,7 +2758,7 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2427
2758
|
onChange={(value) =>
|
|
2428
2759
|
setActionForm((current) => ({
|
|
2429
2760
|
...current,
|
|
2430
|
-
|
|
2761
|
+
integration_profile_id:
|
|
2431
2762
|
typeof value === 'number'
|
|
2432
2763
|
? value
|
|
2433
2764
|
: value != null && value !== ''
|
|
@@ -2442,13 +2773,13 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2442
2773
|
variant="outline"
|
|
2443
2774
|
size="icon"
|
|
2444
2775
|
className="h-10 w-10 shrink-0"
|
|
2445
|
-
disabled={!actionForm.
|
|
2776
|
+
disabled={!actionForm.integration_profile_id}
|
|
2446
2777
|
aria-label="Editar perfil de e-mail selecionado"
|
|
2447
2778
|
title="Editar perfil de e-mail selecionado"
|
|
2448
2779
|
onClick={() => {
|
|
2449
|
-
if (actionForm.
|
|
2780
|
+
if (actionForm.integration_profile_id) {
|
|
2450
2781
|
void openMailProfileEditor(
|
|
2451
|
-
actionForm.
|
|
2782
|
+
actionForm.integration_profile_id
|
|
2452
2783
|
);
|
|
2453
2784
|
}
|
|
2454
2785
|
}}
|
|
@@ -2568,7 +2899,9 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2568
2899
|
/>
|
|
2569
2900
|
</Field>
|
|
2570
2901
|
</div>
|
|
2571
|
-
)
|
|
2902
|
+
)}
|
|
2903
|
+
|
|
2904
|
+
{actionForm.type === 'whatsapp_evolution' && (
|
|
2572
2905
|
<div className="grid gap-3 md:grid-cols-2">
|
|
2573
2906
|
<Field label={t('whatsappTargetType')}>
|
|
2574
2907
|
<Select
|
|
@@ -2650,6 +2983,357 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2650
2983
|
</div>
|
|
2651
2984
|
)}
|
|
2652
2985
|
|
|
2986
|
+
{actionForm.type === 'http_request' && (
|
|
2987
|
+
<div className="grid gap-3 md:grid-cols-2">
|
|
2988
|
+
<Field label="Método HTTP">
|
|
2989
|
+
<Select
|
|
2990
|
+
value={actionForm.http_method}
|
|
2991
|
+
onValueChange={(value) =>
|
|
2992
|
+
setActionForm({ ...actionForm, http_method: value })
|
|
2993
|
+
}
|
|
2994
|
+
>
|
|
2995
|
+
<SelectTrigger className="w-full">
|
|
2996
|
+
<SelectValue />
|
|
2997
|
+
</SelectTrigger>
|
|
2998
|
+
<SelectContent>
|
|
2999
|
+
{['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].map(
|
|
3000
|
+
(m) => (
|
|
3001
|
+
<SelectItem key={m} value={m}>
|
|
3002
|
+
{m}
|
|
3003
|
+
</SelectItem>
|
|
3004
|
+
)
|
|
3005
|
+
)}
|
|
3006
|
+
</SelectContent>
|
|
3007
|
+
</Select>
|
|
3008
|
+
</Field>
|
|
3009
|
+
<Field label="URL *">
|
|
3010
|
+
<Input
|
|
3011
|
+
value={actionForm.http_url}
|
|
3012
|
+
onChange={(event) =>
|
|
3013
|
+
setActionForm({
|
|
3014
|
+
...actionForm,
|
|
3015
|
+
http_url: event.target.value,
|
|
3016
|
+
})
|
|
3017
|
+
}
|
|
3018
|
+
placeholder="https://example.com/api/{{endpoint}}"
|
|
3019
|
+
/>
|
|
3020
|
+
</Field>
|
|
3021
|
+
<Field label="Timeout (ms)">
|
|
3022
|
+
<Input
|
|
3023
|
+
type="number"
|
|
3024
|
+
value={actionForm.http_timeout_ms}
|
|
3025
|
+
onChange={(event) =>
|
|
3026
|
+
setActionForm({
|
|
3027
|
+
...actionForm,
|
|
3028
|
+
http_timeout_ms: Number(event.target.value),
|
|
3029
|
+
})
|
|
3030
|
+
}
|
|
3031
|
+
placeholder="30000"
|
|
3032
|
+
/>
|
|
3033
|
+
</Field>
|
|
3034
|
+
<Field label="Tentativas extras (retry)">
|
|
3035
|
+
<Input
|
|
3036
|
+
type="number"
|
|
3037
|
+
value={actionForm.http_retry_count}
|
|
3038
|
+
onChange={(event) =>
|
|
3039
|
+
setActionForm({
|
|
3040
|
+
...actionForm,
|
|
3041
|
+
http_retry_count: Number(event.target.value),
|
|
3042
|
+
})
|
|
3043
|
+
}
|
|
3044
|
+
placeholder="0"
|
|
3045
|
+
/>
|
|
3046
|
+
</Field>
|
|
3047
|
+
<Field label="Headers (JSON)">
|
|
3048
|
+
<Textarea
|
|
3049
|
+
value={actionForm.http_headers}
|
|
3050
|
+
onChange={(event) =>
|
|
3051
|
+
setActionForm({
|
|
3052
|
+
...actionForm,
|
|
3053
|
+
http_headers: event.target.value,
|
|
3054
|
+
})
|
|
3055
|
+
}
|
|
3056
|
+
className="font-mono text-xs"
|
|
3057
|
+
rows={3}
|
|
3058
|
+
placeholder='{"Authorization": "Bearer {{token}}"}'
|
|
3059
|
+
/>
|
|
3060
|
+
</Field>
|
|
3061
|
+
<Field label="Query Params (JSON)">
|
|
3062
|
+
<Textarea
|
|
3063
|
+
value={actionForm.http_query}
|
|
3064
|
+
onChange={(event) =>
|
|
3065
|
+
setActionForm({
|
|
3066
|
+
...actionForm,
|
|
3067
|
+
http_query: event.target.value,
|
|
3068
|
+
})
|
|
3069
|
+
}
|
|
3070
|
+
className="font-mono text-xs"
|
|
3071
|
+
rows={3}
|
|
3072
|
+
placeholder='{"search": "{{query}}"}'
|
|
3073
|
+
/>
|
|
3074
|
+
</Field>
|
|
3075
|
+
<div className="md:col-span-2">
|
|
3076
|
+
<Field label="Body">
|
|
3077
|
+
<Textarea
|
|
3078
|
+
value={actionForm.http_body}
|
|
3079
|
+
onChange={(event) =>
|
|
3080
|
+
setActionForm({
|
|
3081
|
+
...actionForm,
|
|
3082
|
+
http_body: event.target.value,
|
|
3083
|
+
})
|
|
3084
|
+
}
|
|
3085
|
+
className="font-mono text-xs"
|
|
3086
|
+
rows={5}
|
|
3087
|
+
placeholder='{"userId": "{{userId}}", "event": "{{type}}"}'
|
|
3088
|
+
/>
|
|
3089
|
+
</Field>
|
|
3090
|
+
</div>
|
|
3091
|
+
</div>
|
|
3092
|
+
)}
|
|
3093
|
+
|
|
3094
|
+
{actionForm.type === 'internal_api' && (
|
|
3095
|
+
<div className="grid gap-3 md:grid-cols-2">
|
|
3096
|
+
<Field label="Usuário (ID) *">
|
|
3097
|
+
<Input
|
|
3098
|
+
type="number"
|
|
3099
|
+
value={actionForm.internal_api_user_id ?? ''}
|
|
3100
|
+
onChange={(event) =>
|
|
3101
|
+
setActionForm({
|
|
3102
|
+
...actionForm,
|
|
3103
|
+
internal_api_user_id: event.target.value
|
|
3104
|
+
? Number(event.target.value)
|
|
3105
|
+
: null,
|
|
3106
|
+
})
|
|
3107
|
+
}
|
|
3108
|
+
placeholder="ID do usuário dono do token"
|
|
3109
|
+
/>
|
|
3110
|
+
</Field>
|
|
3111
|
+
<Field label="Token de autenticação *">
|
|
3112
|
+
<div className="flex items-start gap-2">
|
|
3113
|
+
<Input
|
|
3114
|
+
type="password"
|
|
3115
|
+
value={actionForm.internal_api_token}
|
|
3116
|
+
onChange={(event) =>
|
|
3117
|
+
setActionForm({
|
|
3118
|
+
...actionForm,
|
|
3119
|
+
internal_api_token: event.target.value,
|
|
3120
|
+
})
|
|
3121
|
+
}
|
|
3122
|
+
placeholder="hedhog_api_..."
|
|
3123
|
+
className="flex-1"
|
|
3124
|
+
/>
|
|
3125
|
+
<Button
|
|
3126
|
+
type="button"
|
|
3127
|
+
variant="outline"
|
|
3128
|
+
size="sm"
|
|
3129
|
+
disabled={!actionForm.internal_api_user_id}
|
|
3130
|
+
onClick={async () => {
|
|
3131
|
+
if (!actionForm.internal_api_user_id) return;
|
|
3132
|
+
try {
|
|
3133
|
+
const response = await request<{
|
|
3134
|
+
rawToken: string;
|
|
3135
|
+
}>({
|
|
3136
|
+
url: '/webhook-integration/user-tokens',
|
|
3137
|
+
method: 'POST',
|
|
3138
|
+
data: {
|
|
3139
|
+
userId: actionForm.internal_api_user_id,
|
|
3140
|
+
name: `webhook-action-${Date.now()}`,
|
|
3141
|
+
},
|
|
3142
|
+
});
|
|
3143
|
+
const raw = response.data?.rawToken;
|
|
3144
|
+
if (raw) {
|
|
3145
|
+
setActionForm({
|
|
3146
|
+
...actionForm,
|
|
3147
|
+
internal_api_token: raw,
|
|
3148
|
+
});
|
|
3149
|
+
setGeneratedToken(raw);
|
|
3150
|
+
toast.success(
|
|
3151
|
+
'Token gerado! Copie-o antes de salvar.'
|
|
3152
|
+
);
|
|
3153
|
+
}
|
|
3154
|
+
} catch {
|
|
3155
|
+
toast.error('Erro ao gerar token');
|
|
3156
|
+
}
|
|
3157
|
+
}}
|
|
3158
|
+
>
|
|
3159
|
+
Gerar
|
|
3160
|
+
</Button>
|
|
3161
|
+
</div>
|
|
3162
|
+
</Field>
|
|
3163
|
+
{generatedToken && (
|
|
3164
|
+
<div className="md:col-span-2 rounded border border-yellow-300 bg-yellow-50 p-3 text-xs text-yellow-800">
|
|
3165
|
+
<strong>Token gerado (exibido apenas uma vez):</strong>
|
|
3166
|
+
<div className="mt-1 flex items-center gap-2 font-mono break-all">
|
|
3167
|
+
<span className="flex-1">{generatedToken}</span>
|
|
3168
|
+
<Button
|
|
3169
|
+
type="button"
|
|
3170
|
+
variant="ghost"
|
|
3171
|
+
size="sm"
|
|
3172
|
+
onClick={() => {
|
|
3173
|
+
void navigator.clipboard.writeText(
|
|
3174
|
+
generatedToken
|
|
3175
|
+
);
|
|
3176
|
+
toast.success('Token copiado!');
|
|
3177
|
+
}}
|
|
3178
|
+
>
|
|
3179
|
+
Copiar
|
|
3180
|
+
</Button>
|
|
3181
|
+
</div>
|
|
3182
|
+
</div>
|
|
3183
|
+
)}
|
|
3184
|
+
<Field label="Método HTTP">
|
|
3185
|
+
<Select
|
|
3186
|
+
value={actionForm.internal_api_method}
|
|
3187
|
+
onValueChange={(value) =>
|
|
3188
|
+
setActionForm({
|
|
3189
|
+
...actionForm,
|
|
3190
|
+
internal_api_method: value,
|
|
3191
|
+
})
|
|
3192
|
+
}
|
|
3193
|
+
>
|
|
3194
|
+
<SelectTrigger className="w-full">
|
|
3195
|
+
<SelectValue />
|
|
3196
|
+
</SelectTrigger>
|
|
3197
|
+
<SelectContent>
|
|
3198
|
+
{['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].map(
|
|
3199
|
+
(m) => (
|
|
3200
|
+
<SelectItem key={m} value={m}>
|
|
3201
|
+
{m}
|
|
3202
|
+
</SelectItem>
|
|
3203
|
+
)
|
|
3204
|
+
)}
|
|
3205
|
+
</SelectContent>
|
|
3206
|
+
</Select>
|
|
3207
|
+
</Field>
|
|
3208
|
+
<Field label="Path / Endpoint *">
|
|
3209
|
+
<Select
|
|
3210
|
+
value={actionForm.internal_api_path}
|
|
3211
|
+
onValueChange={(value) => {
|
|
3212
|
+
const route = internalRoutes.find(
|
|
3213
|
+
(r) => r.url === value
|
|
3214
|
+
);
|
|
3215
|
+
setActionForm({
|
|
3216
|
+
...actionForm,
|
|
3217
|
+
internal_api_path: value,
|
|
3218
|
+
internal_api_method:
|
|
3219
|
+
route?.method || actionForm.internal_api_method,
|
|
3220
|
+
});
|
|
3221
|
+
}}
|
|
3222
|
+
>
|
|
3223
|
+
<SelectTrigger className="w-full">
|
|
3224
|
+
<SelectValue placeholder="Selecione um endpoint" />
|
|
3225
|
+
</SelectTrigger>
|
|
3226
|
+
<SelectContent>
|
|
3227
|
+
{internalRoutes.map((route) => (
|
|
3228
|
+
<SelectItem key={route.id} value={route.url}>
|
|
3229
|
+
<span className="mr-2 font-mono text-xs text-muted-foreground">
|
|
3230
|
+
{route.method}
|
|
3231
|
+
</span>
|
|
3232
|
+
{route.url}
|
|
3233
|
+
</SelectItem>
|
|
3234
|
+
))}
|
|
3235
|
+
</SelectContent>
|
|
3236
|
+
</Select>
|
|
3237
|
+
</Field>
|
|
3238
|
+
<Field label="Query Params (JSON)">
|
|
3239
|
+
<Textarea
|
|
3240
|
+
value={actionForm.internal_api_query}
|
|
3241
|
+
onChange={(event) =>
|
|
3242
|
+
setActionForm({
|
|
3243
|
+
...actionForm,
|
|
3244
|
+
internal_api_query: event.target.value,
|
|
3245
|
+
})
|
|
3246
|
+
}
|
|
3247
|
+
className="font-mono text-xs"
|
|
3248
|
+
rows={3}
|
|
3249
|
+
placeholder='{"page": "1"}'
|
|
3250
|
+
/>
|
|
3251
|
+
</Field>
|
|
3252
|
+
<Field label="Body (JSON)">
|
|
3253
|
+
<Textarea
|
|
3254
|
+
value={actionForm.internal_api_body}
|
|
3255
|
+
onChange={(event) =>
|
|
3256
|
+
setActionForm({
|
|
3257
|
+
...actionForm,
|
|
3258
|
+
internal_api_body: event.target.value,
|
|
3259
|
+
})
|
|
3260
|
+
}
|
|
3261
|
+
className="font-mono text-xs"
|
|
3262
|
+
rows={3}
|
|
3263
|
+
placeholder='{"userId": "{{userId}}"}'
|
|
3264
|
+
/>
|
|
3265
|
+
</Field>
|
|
3266
|
+
</div>
|
|
3267
|
+
)}
|
|
3268
|
+
|
|
3269
|
+
{actionForm.type === 'app_command' && (
|
|
3270
|
+
<div className="grid gap-3">
|
|
3271
|
+
<Field label="Comando *">
|
|
3272
|
+
<Select
|
|
3273
|
+
value={actionForm.app_command_slug}
|
|
3274
|
+
onValueChange={(value) =>
|
|
3275
|
+
setActionForm({
|
|
3276
|
+
...actionForm,
|
|
3277
|
+
app_command_slug: value,
|
|
3278
|
+
})
|
|
3279
|
+
}
|
|
3280
|
+
>
|
|
3281
|
+
<SelectTrigger className="w-full">
|
|
3282
|
+
<SelectValue placeholder="Selecione um comando" />
|
|
3283
|
+
</SelectTrigger>
|
|
3284
|
+
<SelectContent>
|
|
3285
|
+
{appCommands.map((cmd) => (
|
|
3286
|
+
<SelectItem key={cmd.slug} value={cmd.slug}>
|
|
3287
|
+
{cmd.name}
|
|
3288
|
+
</SelectItem>
|
|
3289
|
+
))}
|
|
3290
|
+
</SelectContent>
|
|
3291
|
+
</Select>
|
|
3292
|
+
</Field>
|
|
3293
|
+
{actionForm.app_command_slug &&
|
|
3294
|
+
(() => {
|
|
3295
|
+
const cmd = appCommands.find(
|
|
3296
|
+
(c) => c.slug === actionForm.app_command_slug
|
|
3297
|
+
);
|
|
3298
|
+
return cmd ? (
|
|
3299
|
+
<p className="text-sm text-muted-foreground">
|
|
3300
|
+
{cmd.description}
|
|
3301
|
+
</p>
|
|
3302
|
+
) : null;
|
|
3303
|
+
})()}
|
|
3304
|
+
<Field label="Parâmetros (JSON)">
|
|
3305
|
+
<Textarea
|
|
3306
|
+
value={actionForm.app_command_params}
|
|
3307
|
+
onChange={(event) =>
|
|
3308
|
+
setActionForm({
|
|
3309
|
+
...actionForm,
|
|
3310
|
+
app_command_params: event.target.value,
|
|
3311
|
+
})
|
|
3312
|
+
}
|
|
3313
|
+
className="font-mono text-xs"
|
|
3314
|
+
rows={5}
|
|
3315
|
+
placeholder="{}"
|
|
3316
|
+
/>
|
|
3317
|
+
</Field>
|
|
3318
|
+
{actionForm.app_command_slug &&
|
|
3319
|
+
(() => {
|
|
3320
|
+
const cmd = appCommands.find(
|
|
3321
|
+
(c) => c.slug === actionForm.app_command_slug
|
|
3322
|
+
);
|
|
3323
|
+
return cmd?.inputSchema ? (
|
|
3324
|
+
<div className="rounded border bg-muted/40 p-2">
|
|
3325
|
+
<p className="mb-1 text-xs font-medium text-muted-foreground">
|
|
3326
|
+
Schema esperado:
|
|
3327
|
+
</p>
|
|
3328
|
+
<pre className="whitespace-pre-wrap break-all font-mono text-xs">
|
|
3329
|
+
{JSON.stringify(cmd.inputSchema, null, 2)}
|
|
3330
|
+
</pre>
|
|
3331
|
+
</div>
|
|
3332
|
+
) : null;
|
|
3333
|
+
})()}
|
|
3334
|
+
</div>
|
|
3335
|
+
)}
|
|
3336
|
+
|
|
2653
3337
|
<SheetActions
|
|
2654
3338
|
onSave={saveAction}
|
|
2655
3339
|
onCancel={() => setActionSheetOpen(false)}
|
|
@@ -2662,7 +3346,10 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2662
3346
|
</Sheet>
|
|
2663
3347
|
|
|
2664
3348
|
<Sheet open={eventWebhookOpen} onOpenChange={setEventWebhookOpen}>
|
|
2665
|
-
<ResizableSheetContent
|
|
3349
|
+
<ResizableSheetContent
|
|
3350
|
+
sheetId="webhooks-event-webhook-form"
|
|
3351
|
+
defaultWidth={1024}
|
|
3352
|
+
>
|
|
2666
3353
|
<SheetHeader>
|
|
2667
3354
|
<SheetTitle>
|
|
2668
3355
|
{eventWebhookEdit ? t('editEventWebhook') : t('newEventWebhook')}
|
|
@@ -2856,7 +3543,10 @@ export default function IntegrationsWebhooksPage() {
|
|
|
2856
3543
|
}
|
|
2857
3544
|
}}
|
|
2858
3545
|
>
|
|
2859
|
-
<ResizableSheetContent
|
|
3546
|
+
<ResizableSheetContent
|
|
3547
|
+
sheetId="webhooks-integration-profile-editor"
|
|
3548
|
+
defaultWidth={896}
|
|
3549
|
+
>
|
|
2860
3550
|
<SheetHeader>
|
|
2861
3551
|
<SheetTitle>Editar perfil de e-mail</SheetTitle>
|
|
2862
3552
|
<SheetDescription>
|
|
@@ -3140,7 +3830,10 @@ export default function IntegrationsWebhooksPage() {
|
|
|
3140
3830
|
}
|
|
3141
3831
|
}}
|
|
3142
3832
|
>
|
|
3143
|
-
<ResizableSheetContent
|
|
3833
|
+
<ResizableSheetContent
|
|
3834
|
+
sheetId="webhooks-mail-template-editor"
|
|
3835
|
+
defaultWidth={896}
|
|
3836
|
+
>
|
|
3144
3837
|
<SheetHeader>
|
|
3145
3838
|
<SheetTitle>Editar template de e-mail</SheetTitle>
|
|
3146
3839
|
<SheetDescription>
|
|
@@ -3493,7 +4186,15 @@ function SortableIncomingActionRow({
|
|
|
3493
4186
|
<TableCell>{action.name}</TableCell>
|
|
3494
4187
|
<TableCell>
|
|
3495
4188
|
<Badge variant="secondary">
|
|
3496
|
-
{action.type === 'email'
|
|
4189
|
+
{action.type === 'email'
|
|
4190
|
+
? t('email')
|
|
4191
|
+
: action.type === 'whatsapp_evolution'
|
|
4192
|
+
? t('whatsapp')
|
|
4193
|
+
: action.type === 'http_request'
|
|
4194
|
+
? 'HTTP Request'
|
|
4195
|
+
: action.type === 'internal_api'
|
|
4196
|
+
? 'Internal API'
|
|
4197
|
+
: 'App Command'}
|
|
3497
4198
|
</Badge>
|
|
3498
4199
|
</TableCell>
|
|
3499
4200
|
<TableCell>{action.order}</TableCell>
|