@hed-hog/core 0.0.350 → 0.0.353

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/dist/access-log/access-log.controller.d.ts +16 -0
  2. package/dist/access-log/access-log.controller.d.ts.map +1 -0
  3. package/dist/access-log/access-log.controller.js +44 -0
  4. package/dist/access-log/access-log.controller.js.map +1 -0
  5. package/dist/access-log/access-log.interceptor.d.ts +9 -0
  6. package/dist/access-log/access-log.interceptor.d.ts.map +1 -0
  7. package/dist/access-log/access-log.interceptor.js +46 -0
  8. package/dist/access-log/access-log.interceptor.js.map +1 -0
  9. package/dist/access-log/access-log.module.d.ts +3 -0
  10. package/dist/access-log/access-log.module.d.ts.map +1 -0
  11. package/dist/access-log/access-log.module.js +29 -0
  12. package/dist/access-log/access-log.module.js.map +1 -0
  13. package/dist/access-log/access-log.service.d.ts +47 -0
  14. package/dist/access-log/access-log.service.d.ts.map +1 -0
  15. package/dist/access-log/access-log.service.js +113 -0
  16. package/dist/access-log/access-log.service.js.map +1 -0
  17. package/dist/access-log/dto/query-access-log.dto.d.ts +8 -0
  18. package/dist/access-log/dto/query-access-log.dto.d.ts.map +1 -0
  19. package/dist/access-log/dto/query-access-log.dto.js +42 -0
  20. package/dist/access-log/dto/query-access-log.dto.js.map +1 -0
  21. package/dist/auth/auth.controller.d.ts +9 -9
  22. package/dist/auth/auth.service.d.ts +19 -19
  23. package/dist/auth/auth.service.d.ts.map +1 -1
  24. package/dist/auth/auth.service.js +0 -4
  25. package/dist/auth/auth.service.js.map +1 -1
  26. package/dist/challenge/challenge.service.d.ts +2 -2
  27. package/dist/challenge/challenge.service.d.ts.map +1 -1
  28. package/dist/challenge/challenge.service.js +0 -1
  29. package/dist/challenge/challenge.service.js.map +1 -1
  30. package/dist/core/system.module.d.ts.map +1 -1
  31. package/dist/core/system.module.js +1 -0
  32. package/dist/core/system.module.js.map +1 -1
  33. package/dist/core.module.d.ts.map +1 -1
  34. package/dist/core.module.js +12 -0
  35. package/dist/core.module.js.map +1 -1
  36. package/dist/dashboard/dashboard-user/dashboard-user.controller.d.ts +3 -3
  37. package/dist/dashboard/dashboard-user/dashboard-user.service.d.ts +3 -3
  38. package/dist/dashboard/dashboard.module.d.ts.map +1 -1
  39. package/dist/dashboard/dashboard.module.js +4 -1
  40. package/dist/dashboard/dashboard.module.js.map +1 -1
  41. package/dist/file/file.controller.js +0 -1
  42. package/dist/file/file.controller.js.map +1 -1
  43. package/dist/file/file.service.d.ts +65 -0
  44. package/dist/file/file.service.d.ts.map +1 -1
  45. package/dist/file/file.service.js +151 -3
  46. package/dist/file/file.service.js.map +1 -1
  47. package/dist/file/provider/abstract.provider.d.ts +8 -0
  48. package/dist/file/provider/abstract.provider.d.ts.map +1 -1
  49. package/dist/file/provider/abstract.provider.js.map +1 -1
  50. package/dist/file/provider/azure.provider.d.ts +4 -0
  51. package/dist/file/provider/azure.provider.d.ts.map +1 -1
  52. package/dist/file/provider/azure.provider.js +14 -0
  53. package/dist/file/provider/azure.provider.js.map +1 -1
  54. package/dist/file/provider/gcs.provider.d.ts +4 -0
  55. package/dist/file/provider/gcs.provider.d.ts.map +1 -1
  56. package/dist/file/provider/gcs.provider.js +14 -0
  57. package/dist/file/provider/gcs.provider.js.map +1 -1
  58. package/dist/file/provider/local.provider.d.ts +4 -0
  59. package/dist/file/provider/local.provider.d.ts.map +1 -1
  60. package/dist/file/provider/local.provider.js +19 -0
  61. package/dist/file/provider/local.provider.js.map +1 -1
  62. package/dist/file/provider/provider.factory.d.ts.map +1 -1
  63. package/dist/file/provider/provider.factory.js +3 -0
  64. package/dist/file/provider/provider.factory.js.map +1 -1
  65. package/dist/file/provider/s3.provider.d.ts +4 -0
  66. package/dist/file/provider/s3.provider.d.ts.map +1 -1
  67. package/dist/file/provider/s3.provider.js +17 -0
  68. package/dist/file/provider/s3.provider.js.map +1 -1
  69. package/dist/mcp/mcp-audit.service.d.ts +3 -1
  70. package/dist/mcp/mcp-audit.service.d.ts.map +1 -1
  71. package/dist/mcp/mcp-audit.service.js +14 -2
  72. package/dist/mcp/mcp-audit.service.js.map +1 -1
  73. package/dist/mcp/mcp.controller.d.ts +3 -1
  74. package/dist/mcp/mcp.controller.d.ts.map +1 -1
  75. package/dist/mcp/mcp.controller.js +10 -2
  76. package/dist/mcp/mcp.controller.js.map +1 -1
  77. package/dist/mcp/mcp.module.d.ts.map +1 -1
  78. package/dist/mcp/mcp.module.js +72 -0
  79. package/dist/mcp/mcp.module.js.map +1 -1
  80. package/dist/mcp/tools/core-ai.mcp-tools.d.ts +45 -0
  81. package/dist/mcp/tools/core-ai.mcp-tools.d.ts.map +1 -0
  82. package/dist/mcp/tools/core-ai.mcp-tools.js +214 -0
  83. package/dist/mcp/tools/core-ai.mcp-tools.js.map +1 -0
  84. package/dist/mcp/tools/core-dashboard-items.mcp-tools.d.ts +21 -0
  85. package/dist/mcp/tools/core-dashboard-items.mcp-tools.d.ts.map +1 -0
  86. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js +89 -0
  87. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js.map +1 -0
  88. package/dist/mcp/tools/core-dashboard.mcp-tools.d.ts +29 -0
  89. package/dist/mcp/tools/core-dashboard.mcp-tools.d.ts.map +1 -0
  90. package/dist/mcp/tools/core-dashboard.mcp-tools.js +149 -0
  91. package/dist/mcp/tools/core-dashboard.mcp-tools.js.map +1 -0
  92. package/dist/mcp/tools/core-event-webhooks.mcp-tools.d.ts +30 -0
  93. package/dist/mcp/tools/core-event-webhooks.mcp-tools.d.ts.map +1 -0
  94. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js +185 -0
  95. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js.map +1 -0
  96. package/dist/mcp/tools/core-files.mcp-tools.d.ts +26 -0
  97. package/dist/mcp/tools/core-files.mcp-tools.d.ts.map +1 -0
  98. package/dist/mcp/tools/core-files.mcp-tools.js +140 -0
  99. package/dist/mcp/tools/core-files.mcp-tools.js.map +1 -0
  100. package/dist/mcp/tools/core-integration-events.mcp-tools.d.ts +26 -0
  101. package/dist/mcp/tools/core-integration-events.mcp-tools.d.ts.map +1 -0
  102. package/dist/mcp/tools/core-integration-events.mcp-tools.js +168 -0
  103. package/dist/mcp/tools/core-integration-events.mcp-tools.js.map +1 -0
  104. package/dist/mcp/tools/core-mail-profile.mcp-tools.d.ts +32 -0
  105. package/dist/mcp/tools/core-mail-profile.mcp-tools.d.ts.map +1 -0
  106. package/dist/mcp/tools/core-mail-profile.mcp-tools.js +178 -0
  107. package/dist/mcp/tools/core-mail-profile.mcp-tools.js.map +1 -0
  108. package/dist/mcp/tools/core-mail-sent.mcp-tools.d.ts +14 -0
  109. package/dist/mcp/tools/core-mail-sent.mcp-tools.d.ts.map +1 -0
  110. package/dist/mcp/tools/core-mail-sent.mcp-tools.js +106 -0
  111. package/dist/mcp/tools/core-mail-sent.mcp-tools.js.map +1 -0
  112. package/dist/mcp/tools/core-mail.mcp-tools.d.ts +36 -0
  113. package/dist/mcp/tools/core-mail.mcp-tools.d.ts.map +1 -0
  114. package/dist/mcp/tools/core-mail.mcp-tools.js +184 -0
  115. package/dist/mcp/tools/core-mail.mcp-tools.js.map +1 -0
  116. package/dist/mcp/tools/core-mcp-chat.mcp-tools.d.ts +21 -0
  117. package/dist/mcp/tools/core-mcp-chat.mcp-tools.d.ts.map +1 -0
  118. package/dist/mcp/tools/core-mcp-chat.mcp-tools.js +118 -0
  119. package/dist/mcp/tools/core-mcp-chat.mcp-tools.js.map +1 -0
  120. package/dist/mcp/tools/core-menus.mcp-tools.d.ts +40 -0
  121. package/dist/mcp/tools/core-menus.mcp-tools.d.ts.map +1 -0
  122. package/dist/mcp/tools/core-menus.mcp-tools.js +268 -0
  123. package/dist/mcp/tools/core-menus.mcp-tools.js.map +1 -0
  124. package/dist/mcp/tools/core-notifications.mcp-tools.d.ts +31 -0
  125. package/dist/mcp/tools/core-notifications.mcp-tools.d.ts.map +1 -0
  126. package/dist/mcp/tools/core-notifications.mcp-tools.js +178 -0
  127. package/dist/mcp/tools/core-notifications.mcp-tools.js.map +1 -0
  128. package/dist/mcp/tools/core-profile.mcp-tools.d.ts +20 -0
  129. package/dist/mcp/tools/core-profile.mcp-tools.d.ts.map +1 -0
  130. package/dist/mcp/tools/core-profile.mcp-tools.js +111 -0
  131. package/dist/mcp/tools/core-profile.mcp-tools.js.map +1 -0
  132. package/dist/mcp/tools/core-roles.mcp-tools.d.ts +70 -0
  133. package/dist/mcp/tools/core-roles.mcp-tools.d.ts.map +1 -0
  134. package/dist/mcp/tools/core-roles.mcp-tools.js +355 -0
  135. package/dist/mcp/tools/core-roles.mcp-tools.js.map +1 -0
  136. package/dist/mcp/tools/core-routes.mcp-tools.d.ts +52 -0
  137. package/dist/mcp/tools/core-routes.mcp-tools.d.ts.map +1 -0
  138. package/dist/mcp/tools/core-routes.mcp-tools.js +254 -0
  139. package/dist/mcp/tools/core-routes.mcp-tools.js.map +1 -0
  140. package/dist/mcp/tools/core-screens.mcp-tools.d.ts +47 -0
  141. package/dist/mcp/tools/core-screens.mcp-tools.d.ts.map +1 -0
  142. package/dist/mcp/tools/core-screens.mcp-tools.js +250 -0
  143. package/dist/mcp/tools/core-screens.mcp-tools.js.map +1 -0
  144. package/dist/mcp/tools/core-sessions.mcp-tools.d.ts +20 -0
  145. package/dist/mcp/tools/core-sessions.mcp-tools.d.ts.map +1 -0
  146. package/dist/mcp/tools/core-sessions.mcp-tools.js +128 -0
  147. package/dist/mcp/tools/core-sessions.mcp-tools.js.map +1 -0
  148. package/dist/mcp/tools/core-settings.mcp-tools.d.ts +25 -0
  149. package/dist/mcp/tools/core-settings.mcp-tools.d.ts.map +1 -1
  150. package/dist/mcp/tools/core-settings.mcp-tools.js +138 -0
  151. package/dist/mcp/tools/core-settings.mcp-tools.js.map +1 -1
  152. package/dist/mcp/tools/core-system.mcp-tools.d.ts +8 -0
  153. package/dist/mcp/tools/core-system.mcp-tools.d.ts.map +1 -0
  154. package/dist/mcp/tools/core-system.mcp-tools.js +40 -0
  155. package/dist/mcp/tools/core-system.mcp-tools.js.map +1 -0
  156. package/dist/mcp/tools/core-webhooks.mcp-tools.d.ts +46 -0
  157. package/dist/mcp/tools/core-webhooks.mcp-tools.d.ts.map +1 -0
  158. package/dist/mcp/tools/core-webhooks.mcp-tools.js +266 -0
  159. package/dist/mcp/tools/core-webhooks.mcp-tools.js.map +1 -0
  160. package/dist/mcp-chat/mcp-chat.controller.d.ts +1 -1
  161. package/dist/mcp-chat/mcp-chat.service.d.ts +25 -2
  162. package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
  163. package/dist/mcp-chat/mcp-chat.service.js +666 -36
  164. package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
  165. package/dist/notification/notification.controller.d.ts +8 -4
  166. package/dist/notification/notification.controller.d.ts.map +1 -1
  167. package/dist/notification/notification.controller.js +12 -0
  168. package/dist/notification/notification.controller.js.map +1 -1
  169. package/dist/notification/notification.service.d.ts +19 -5
  170. package/dist/notification/notification.service.d.ts.map +1 -1
  171. package/dist/notification/notification.service.js +155 -9
  172. package/dist/notification/notification.service.js.map +1 -1
  173. package/dist/pdf/pdf.service.js +1 -1
  174. package/dist/pdf/pdf.service.js.map +1 -1
  175. package/dist/profile/profile.controller.d.ts +3 -3
  176. package/dist/profile/profile.controller.js +0 -1
  177. package/dist/profile/profile.controller.js.map +1 -1
  178. package/dist/profile/profile.module.d.ts.map +1 -1
  179. package/dist/profile/profile.module.js +1 -0
  180. package/dist/profile/profile.module.js.map +1 -1
  181. package/dist/profile/profile.service.d.ts +3 -3
  182. package/dist/session/session.controller.d.ts +2 -2
  183. package/dist/session/session.service.d.ts +6 -6
  184. package/dist/setting/setting.controller.d.ts +1 -1
  185. package/dist/setting/setting.service.d.ts +1 -1
  186. package/dist/setting/setting.service.d.ts.map +1 -1
  187. package/dist/setting/setting.service.js +1 -4
  188. package/dist/setting/setting.service.js.map +1 -1
  189. package/dist/task/task.service.d.ts +1 -0
  190. package/dist/task/task.service.d.ts.map +1 -1
  191. package/dist/task/task.service.js +25 -0
  192. package/dist/task/task.service.js.map +1 -1
  193. package/dist/token/token.service.d.ts.map +1 -1
  194. package/dist/token/token.service.js +0 -1
  195. package/dist/token/token.service.js.map +1 -1
  196. package/dist/user/user.controller.d.ts +9 -9
  197. package/dist/user/user.service.d.ts +21 -21
  198. package/dist/webhook-integration/dto/webhook-action.dto.d.ts +22 -0
  199. package/dist/webhook-integration/dto/webhook-action.dto.d.ts.map +1 -0
  200. package/dist/webhook-integration/dto/webhook-action.dto.js +120 -0
  201. package/dist/webhook-integration/dto/webhook-action.dto.js.map +1 -0
  202. package/dist/webhook-integration/webhook-integration.controller.d.ts +7 -5
  203. package/dist/webhook-integration/webhook-integration.controller.d.ts.map +1 -1
  204. package/dist/webhook-integration/webhook-integration.controller.js +18 -5
  205. package/dist/webhook-integration/webhook-integration.controller.js.map +1 -1
  206. package/dist/webhook-integration/webhook-integration.service.d.ts +14 -5
  207. package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
  208. package/dist/webhook-integration/webhook-integration.service.js +174 -41
  209. package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
  210. package/hedhog/data/menu.yaml +15 -0
  211. package/hedhog/data/route.yaml +1304 -0
  212. package/hedhog/data/setting_group.yaml +67 -0
  213. package/hedhog/data/setting_subgroup.yaml +16 -0
  214. package/hedhog/frontend/app/access-log/page.tsx.ejs +772 -0
  215. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +10 -3
  216. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +33 -13
  217. package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +12 -5
  218. package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +12 -5
  219. package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +1817 -356
  220. package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +43 -5
  221. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +35 -7
  222. package/hedhog/frontend/app/menu/page.tsx.ejs +9 -3
  223. package/hedhog/frontend/app/roles/page.tsx.ejs +18 -6
  224. package/hedhog/frontend/app/routes/page.tsx.ejs +9 -3
  225. package/hedhog/frontend/app/setting-list/page.tsx.ejs +344 -171
  226. package/hedhog/frontend/app/users/user-access-sheet.tsx.ejs +310 -304
  227. package/hedhog/frontend/app/users/user-sheet.tsx.ejs +25 -7
  228. package/hedhog/frontend/messages/en.json +104 -3
  229. package/hedhog/frontend/messages/pt.json +104 -3
  230. package/hedhog/table/access_log.yaml +31 -0
  231. package/package.json +4 -3
  232. package/src/access-log/access-log.controller.ts +29 -0
  233. package/src/access-log/access-log.interceptor.ts +38 -0
  234. package/src/access-log/access-log.module.ts +16 -0
  235. package/src/access-log/access-log.service.ts +129 -0
  236. package/src/access-log/dto/query-access-log.dto.ts +23 -0
  237. package/src/auth/auth.service.ts +0 -7
  238. package/src/challenge/challenge.service.ts +0 -2
  239. package/src/core/system.module.ts +1 -0
  240. package/src/core.module.ts +12 -0
  241. package/src/dashboard/dashboard.module.ts +4 -1
  242. package/src/file/file.controller.ts +14 -14
  243. package/src/file/file.service.ts +198 -4
  244. package/src/file/provider/abstract.provider.ts +10 -0
  245. package/src/file/provider/azure.provider.ts +24 -0
  246. package/src/file/provider/gcs.provider.ts +20 -0
  247. package/src/file/provider/local.provider.ts +30 -2
  248. package/src/file/provider/provider.factory.ts +3 -0
  249. package/src/file/provider/s3.provider.ts +22 -0
  250. package/src/mcp/mcp-audit.service.ts +47 -36
  251. package/src/mcp/mcp.controller.ts +40 -30
  252. package/src/mcp/mcp.module.ts +72 -0
  253. package/src/mcp/tools/core-ai.mcp-tools.ts +156 -0
  254. package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +63 -0
  255. package/src/mcp/tools/core-dashboard.mcp-tools.ts +103 -0
  256. package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +134 -0
  257. package/src/mcp/tools/core-files.mcp-tools.ts +105 -0
  258. package/src/mcp/tools/core-integration-events.mcp-tools.ts +118 -0
  259. package/src/mcp/tools/core-mail-profile.mcp-tools.ts +128 -0
  260. package/src/mcp/tools/core-mail-sent.mcp-tools.ts +76 -0
  261. package/src/mcp/tools/core-mail.mcp-tools.ts +130 -0
  262. package/src/mcp/tools/core-mcp-chat.mcp-tools.ts +81 -0
  263. package/src/mcp/tools/core-menus.mcp-tools.ts +197 -0
  264. package/src/mcp/tools/core-notifications.mcp-tools.ts +128 -0
  265. package/src/mcp/tools/core-profile.mcp-tools.ts +74 -0
  266. package/src/mcp/tools/core-roles.mcp-tools.ts +288 -0
  267. package/src/mcp/tools/core-routes.mcp-tools.ts +196 -0
  268. package/src/mcp/tools/core-screens.mcp-tools.ts +186 -0
  269. package/src/mcp/tools/core-sessions.mcp-tools.ts +97 -0
  270. package/src/mcp/tools/core-settings.mcp-tools.ts +171 -53
  271. package/src/mcp/tools/core-system.mcp-tools.ts +19 -0
  272. package/src/mcp/tools/core-webhooks.mcp-tools.ts +199 -0
  273. package/src/mcp-chat/mcp-chat.service.ts +887 -38
  274. package/src/notification/notification.controller.ts +20 -8
  275. package/src/notification/notification.service.ts +209 -9
  276. package/src/pdf/pdf.service.ts +1 -1
  277. package/src/profile/profile.controller.ts +1 -1
  278. package/src/profile/profile.module.ts +1 -0
  279. package/src/setting/setting.service.ts +8 -11
  280. package/src/task/task.service.ts +31 -0
  281. package/src/token/token.service.ts +0 -2
  282. package/src/webhook-integration/dto/webhook-action.dto.ts +96 -0
  283. package/src/webhook-integration/webhook-integration.controller.ts +124 -103
  284. package/src/webhook-integration/webhook-integration.service.ts +267 -64
@@ -1,103 +1,124 @@
1
- import { DeleteDTO, Public, Role } from '@hed-hog/api';
2
- import { Pagination } from '@hed-hog/api-pagination';
3
- import {
4
- Body,
5
- Controller,
6
- Delete,
7
- Get,
8
- Headers,
9
- Param,
10
- ParseIntPipe,
11
- Patch,
12
- Post,
13
- Req,
14
- } from '@nestjs/common';
15
- import { Request } from 'express';
16
- import { WebhookIntegrationService } from './webhook-integration.service';
17
-
18
- @Role()
19
- @Controller('webhook-integration')
20
- export class WebhookIntegrationController {
21
- constructor(private readonly service: WebhookIntegrationService) {}
22
-
23
- @Get()
24
- list(@Pagination() paginationParams) {
25
- return this.service.list(paginationParams);
26
- }
27
-
28
- @Get(':id')
29
- get(@Param('id', ParseIntPipe) id: number) {
30
- return this.service.get(id);
31
- }
32
-
33
- @Post()
34
- create(@Body() data: any) {
35
- return this.service.create(data);
36
- }
37
-
38
- @Patch(':id')
39
- update(@Param('id', ParseIntPipe) id: number, @Body() data: any) {
40
- return this.service.update(id, data);
41
- }
42
-
43
- @Delete()
44
- delete(@Body() data: DeleteDTO) {
45
- return this.service.delete(data);
46
- }
47
-
48
- @Post(':id/regenerate-uuid')
49
- regenerateUuid(@Param('id', ParseIntPipe) id: number) {
50
- return this.service.regenerateUuid(id);
51
- }
52
-
53
- @Post(':id/regenerate-token')
54
- regenerateToken(@Param('id', ParseIntPipe) id: number) {
55
- return this.service.regenerateToken(id);
56
- }
57
-
58
- @Get(':id/action')
59
- listActions(@Param('id', ParseIntPipe) id: number) {
60
- return this.service.listActions(id);
61
- }
62
-
63
- @Post(':id/action')
64
- createAction(@Param('id', ParseIntPipe) id: number, @Body() data: any) {
65
- return this.service.createAction(id, data);
66
- }
67
-
68
- @Patch(':id/action/:actionId')
69
- updateAction(
70
- @Param('id', ParseIntPipe) id: number,
71
- @Param('actionId', ParseIntPipe) actionId: number,
72
- @Body() data: any,
73
- ) {
74
- return this.service.updateAction(id, actionId, data);
75
- }
76
-
77
- @Delete(':id/action')
78
- deleteActions(@Param('id', ParseIntPipe) id: number, @Body() data: DeleteDTO) {
79
- return this.service.deleteActions(id, data);
80
- }
81
-
82
- @Get(':id/log')
83
- listLogs(@Param('id', ParseIntPipe) id: number, @Pagination() paginationParams) {
84
- return this.service.listLogs(id, paginationParams);
85
- }
86
- }
87
-
88
- @Public()
89
- @Controller('webhook')
90
- export class PublicWebhookController {
91
- constructor(private readonly service: WebhookIntegrationService) {}
92
-
93
- @Post(':uuid')
94
- execute(
95
- @Param('uuid') uuid: string,
96
- @Body() body: any,
97
- @Headers() headers: any,
98
- @Req() req: Request,
99
- ) {
100
- return this.service.executePublic(uuid, body, headers, req);
101
- }
102
- }
103
-
1
+ import { DeleteDTO, Public, Role } from '@hed-hog/api';
2
+ import { Pagination } from '@hed-hog/api-pagination';
3
+ import {
4
+ Body,
5
+ Controller,
6
+ Delete,
7
+ Get,
8
+ Headers,
9
+ Param,
10
+ ParseIntPipe,
11
+ Patch,
12
+ Post,
13
+ Query,
14
+ Req,
15
+ Res,
16
+ } from '@nestjs/common';
17
+ import { Request, Response } from 'express';
18
+ import { WebhookIntegrationService } from './webhook-integration.service';
19
+ import {
20
+ CreateWebhookActionDTO,
21
+ UpdateWebhookActionDTO,
22
+ } from './dto/webhook-action.dto';
23
+
24
+ @Role()
25
+ @Controller('webhook-integration')
26
+ export class WebhookIntegrationController {
27
+ constructor(private readonly service: WebhookIntegrationService) {}
28
+
29
+ @Get()
30
+ list(@Pagination() paginationParams) {
31
+ return this.service.list(paginationParams);
32
+ }
33
+
34
+ @Get(':id')
35
+ get(@Param('id', ParseIntPipe) id: number) {
36
+ return this.service.get(id);
37
+ }
38
+
39
+ @Post()
40
+ create(@Body() data: any) {
41
+ return this.service.create(data);
42
+ }
43
+
44
+ @Patch(':id')
45
+ update(@Param('id', ParseIntPipe) id: number, @Body() data: any) {
46
+ return this.service.update(id, data);
47
+ }
48
+
49
+ @Delete()
50
+ delete(@Body() data: DeleteDTO) {
51
+ return this.service.delete(data);
52
+ }
53
+
54
+ @Post(':id/regenerate-uuid')
55
+ regenerateUuid(@Param('id', ParseIntPipe) id: number) {
56
+ return this.service.regenerateUuid(id);
57
+ }
58
+
59
+ @Post(':id/regenerate-token')
60
+ regenerateToken(@Param('id', ParseIntPipe) id: number) {
61
+ return this.service.regenerateToken(id);
62
+ }
63
+
64
+ @Get(':id/action')
65
+ listActions(@Param('id', ParseIntPipe) id: number) {
66
+ return this.service.listActions(id);
67
+ }
68
+
69
+ @Post(':id/action')
70
+ createAction(
71
+ @Param('id', ParseIntPipe) id: number,
72
+ @Body() data: CreateWebhookActionDTO,
73
+ ) {
74
+ return this.service.createAction(id, data);
75
+ }
76
+
77
+ @Patch(':id/action/:actionId')
78
+ updateAction(
79
+ @Param('id', ParseIntPipe) id: number,
80
+ @Param('actionId', ParseIntPipe) actionId: number,
81
+ @Body() data: UpdateWebhookActionDTO,
82
+ ) {
83
+ return this.service.updateAction(id, actionId, data);
84
+ }
85
+
86
+ @Delete(':id/action')
87
+ deleteActions(@Param('id', ParseIntPipe) id: number, @Body() data: DeleteDTO) {
88
+ return this.service.deleteActions(id, data);
89
+ }
90
+
91
+ @Get(':id/log')
92
+ listLogs(
93
+ @Param('id', ParseIntPipe) id: number,
94
+ @Pagination() paginationParams,
95
+ @Query('sort') sort?: 'asc' | 'desc',
96
+ ) {
97
+ return this.service.listLogs(id, paginationParams, sort);
98
+ }
99
+
100
+ @Get(':id/log/stream')
101
+ streamLogs(
102
+ @Param('id', ParseIntPipe) id: number,
103
+ @Res() res: Response,
104
+ ) {
105
+ return this.service.streamLogs(id, res);
106
+ }
107
+ }
108
+
109
+ @Public()
110
+ @Controller('webhook')
111
+ export class PublicWebhookController {
112
+ constructor(private readonly service: WebhookIntegrationService) {}
113
+
114
+ @Post(':uuid')
115
+ execute(
116
+ @Param('uuid') uuid: string,
117
+ @Body() body: any,
118
+ @Headers() headers: any,
119
+ @Req() req: Request,
120
+ ) {
121
+ return this.service.executePublic(uuid, body, headers, req);
122
+ }
123
+ }
124
+
@@ -4,23 +4,28 @@ import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
4
4
  import { PrismaService } from '@hed-hog/api-prisma';
5
5
  import { HttpService } from '@nestjs/axios';
6
6
  import {
7
- BadRequestException,
8
- HttpException,
9
- Injectable,
10
- NotFoundException,
7
+ BadRequestException,
8
+ HttpException,
9
+ Injectable,
10
+ NotFoundException,
11
11
  } from '@nestjs/common';
12
- import { Request } from 'express';
12
+ import { EventEmitter } from 'events';
13
+ import { Request, Response } from 'express';
13
14
  import { firstValueFrom } from 'rxjs';
14
15
  import { MailService } from '../mail/mail.service';
15
16
  import { SettingService } from '../setting/setting.service';
16
17
  import {
17
- createPlainToken,
18
- createPublicUuid,
19
- hashToken,
20
- normalizeJsonObject,
21
- renderTemplate,
22
- sanitizeSensitiveData,
23
- summarizePayload,
18
+ CreateWebhookActionDTO,
19
+ UpdateWebhookActionDTO,
20
+ } from './dto/webhook-action.dto';
21
+ import {
22
+ createPlainToken,
23
+ createPublicUuid,
24
+ hashToken,
25
+ normalizeJsonObject,
26
+ renderTemplate,
27
+ sanitizeSensitiveData,
28
+ summarizePayload,
24
29
  } from './webhook-utils';
25
30
 
26
31
  type ActionExecutionLog = {
@@ -34,8 +39,15 @@ type ActionExecutionLog = {
34
39
  errorMessage?: string | null;
35
40
  };
36
41
 
42
+ type WebhookActionPayload =
43
+ | CreateWebhookActionDTO
44
+ | UpdateWebhookActionDTO
45
+ | Record<string, unknown>;
46
+
37
47
  @Injectable()
38
48
  export class WebhookIntegrationService {
49
+ private readonly logEmitter = new EventEmitter();
50
+
39
51
  constructor(
40
52
  private readonly prisma: PrismaService,
41
53
  private readonly pagination: PaginationService,
@@ -192,8 +204,11 @@ export class WebhookIntegrationService {
192
204
  }
193
205
 
194
206
  private async getApplicationBaseUrl() {
195
- const settings = await this.settingService.getSettingValues('url');
196
- const value = settings?.url;
207
+ const settings = await this.settingService.getSettingValues([
208
+ 'api-url',
209
+ 'url',
210
+ ]);
211
+ const value = settings?.['api-url'] || settings?.url;
197
212
  return typeof value === 'string' ? value.replace(/\/+$/, '') : '';
198
213
  }
199
214
 
@@ -231,21 +246,34 @@ export class WebhookIntegrationService {
231
246
  });
232
247
  }
233
248
 
234
- async createAction(integrationId: number, data: any) {
249
+ async createAction(integrationId: number, data: WebhookActionPayload) {
235
250
  await this.get(integrationId);
251
+ const normalized = this.normalizeAction(data);
252
+ this.validateActionConfiguration(normalized);
253
+
236
254
  return this.actions.create({
237
255
  data: {
238
- ...this.normalizeAction(data),
256
+ ...normalized,
239
257
  webhook_integration_id: integrationId,
240
258
  },
241
259
  });
242
260
  }
243
261
 
244
- async updateAction(integrationId: number, actionId: number, data: any) {
245
- await this.ensureAction(integrationId, actionId);
262
+ async updateAction(
263
+ integrationId: number,
264
+ actionId: number,
265
+ data: WebhookActionPayload,
266
+ ) {
267
+ const existing = await this.ensureAction(integrationId, actionId);
268
+ const normalized = this.normalizeAction(data, true);
269
+ this.validateActionConfiguration({
270
+ ...existing,
271
+ ...normalized,
272
+ });
273
+
246
274
  return this.actions.update({
247
275
  where: { id: actionId },
248
- data: this.normalizeAction(data, true),
276
+ data: normalized,
249
277
  });
250
278
  }
251
279
 
@@ -265,12 +293,40 @@ export class WebhookIntegrationService {
265
293
  });
266
294
  }
267
295
 
268
- async listLogs(integrationId: number, paginationParams: PaginationDTO) {
296
+ async listLogs(
297
+ integrationId: number,
298
+ paginationParams: PaginationDTO,
299
+ sort: 'asc' | 'desc' = 'desc',
300
+ ) {
269
301
  await this.get(integrationId);
270
- const result = await this.pagination.paginate(this.logs, paginationParams, {
271
- where: { webhook_integration_id: integrationId },
272
- orderBy: [{ created_at: 'desc' }, { id: 'desc' }],
273
- });
302
+
303
+ const page = Math.max(Number(paginationParams.page || 1), 1);
304
+ const pageSize = Math.max(Number(paginationParams.pageSize || 10), 1);
305
+ const skip = (page - 1) * pageSize;
306
+ const normalizedSort = sort === 'asc' ? 'asc' : 'desc';
307
+
308
+ const where = { webhook_integration_id: integrationId };
309
+
310
+ const [data, total] = await Promise.all([
311
+ this.logs.findMany({
312
+ where,
313
+ orderBy: [{ created_at: normalizedSort }, { id: normalizedSort }],
314
+ skip,
315
+ take: pageSize,
316
+ }),
317
+ this.logs.count({ where }),
318
+ ]);
319
+
320
+ const lastPage = Math.max(1, Math.ceil(total / pageSize));
321
+ const result = {
322
+ total,
323
+ lastPage,
324
+ page,
325
+ pageSize,
326
+ prev: page > 1 ? page - 1 : null,
327
+ next: page < lastPage ? page + 1 : null,
328
+ data,
329
+ };
274
330
 
275
331
  const logIds = (result.data || [])
276
332
  .map((item: any) => item.id)
@@ -303,6 +359,27 @@ export class WebhookIntegrationService {
303
359
  };
304
360
  }
305
361
 
362
+ streamLogs(integrationId: number, res: Response) {
363
+ res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
364
+ res.setHeader('Cache-Control', 'no-cache, no-transform');
365
+ res.setHeader('Connection', 'keep-alive');
366
+ res.setHeader('X-Accel-Buffering', 'no');
367
+ res.flushHeaders();
368
+
369
+ res.write(`data: ${JSON.stringify({ type: 'connected' })}\n\n`);
370
+
371
+ const handler = (payload: unknown) => {
372
+ res.write(`data: ${JSON.stringify({ type: 'log', payload })}\n\n`);
373
+ };
374
+
375
+ const eventKey = `log:${integrationId}`;
376
+ this.logEmitter.on(eventKey, handler);
377
+
378
+ res.on('close', () => {
379
+ this.logEmitter.off(eventKey, handler);
380
+ });
381
+ }
382
+
306
383
  async executePublic(uuid: string, body: any, headers: any, req: Request) {
307
384
  const startedAt = Date.now();
308
385
  const remoteIp = this.getRemoteIp(req);
@@ -372,6 +449,7 @@ export class WebhookIntegrationService {
372
449
  actionType: action.type,
373
450
  status: 'failed',
374
451
  durationMs,
452
+ requestPayload: this.extractErrorRequestPayload(error),
375
453
  errorMessage,
376
454
  responsePayload: this.extractErrorResponse(error),
377
455
  });
@@ -397,6 +475,10 @@ export class WebhookIntegrationService {
397
475
 
398
476
  await this.createActionLogs(callLog?.id, actionLogs);
399
477
 
478
+ if (integration?.id && callLog?.id) {
479
+ this.logEmitter.emit(`log:${integration.id}`, { id: callLog.id });
480
+ }
481
+
400
482
  return response;
401
483
  } catch (error) {
402
484
  const callLog = await this.createCallLog({
@@ -421,6 +503,10 @@ export class WebhookIntegrationService {
421
503
 
422
504
  await this.createActionLogs(callLog?.id, actionLogs).catch(() => undefined);
423
505
 
506
+ if (integration?.id && callLog?.id) {
507
+ this.logEmitter.emit(`log:${integration.id}`, { id: callLog.id });
508
+ }
509
+
424
510
  if (error instanceof HttpException) {
425
511
  throw error;
426
512
  }
@@ -451,11 +537,7 @@ export class WebhookIntegrationService {
451
537
  }
452
538
 
453
539
  private async executeEmailAction(action: any, body: any) {
454
- if (!action.mail_profile_id || !action.mail_id || !action.email_to) {
455
- throw new BadRequestException(
456
- 'Email action is missing required configuration.',
457
- );
458
- }
540
+ this.validateActionConfiguration(action);
459
541
 
460
542
  const profile = await (this.prisma as any).mail_profile.findUnique({
461
543
  where: { id: Number(action.mail_profile_id) },
@@ -486,14 +568,24 @@ export class WebhookIntegrationService {
486
568
  : profile.reply_to_email
487
569
  : undefined;
488
570
 
571
+ const renderedTo = String(renderTemplate(action.email_to, body) ?? '').trim();
572
+ const renderedCc = action.email_cc
573
+ ? String(renderTemplate(action.email_cc, body) ?? '').trim()
574
+ : '';
575
+ const renderedBcc = action.email_bcc
576
+ ? String(renderTemplate(action.email_bcc, body) ?? '').trim()
577
+ : '';
578
+
579
+ if (!renderedTo) {
580
+ throw new BadRequestException(
581
+ 'Email action rendered an empty recipient for email_to.',
582
+ );
583
+ }
584
+
489
585
  const requestPayload = {
490
- to: renderTemplate(action.email_to, body) as string,
491
- cc: action.email_cc
492
- ? (renderTemplate(action.email_cc, body) as string)
493
- : undefined,
494
- bcc: action.email_bcc
495
- ? (renderTemplate(action.email_bcc, body) as string)
496
- : undefined,
586
+ to: renderedTo,
587
+ cc: renderedCc || undefined,
588
+ bcc: renderedBcc || undefined,
497
589
  from: sender,
498
590
  replyTo,
499
591
  subject: renderTemplate(template.subject, body) as string,
@@ -537,32 +629,55 @@ export class WebhookIntegrationService {
537
629
  const baseUrl = String(action.whatsapp_base_url).replace(/\/+$/, '');
538
630
  const instance = encodeURIComponent(action.whatsapp_instance);
539
631
  const url = `${baseUrl}/message/sendText/${instance}`;
540
- const message = renderTemplate(action.whatsapp_template, body);
541
- const target = renderTemplate(action.whatsapp_target, body);
542
-
543
- const response = await firstValueFrom(
544
- this.http.post(
545
- url,
546
- {
547
- number: target,
548
- text: message,
549
- },
550
- {
551
- headers: {
552
- apikey: action.whatsapp_token,
553
- Authorization: `Bearer ${action.whatsapp_token}`,
632
+ const targetType =
633
+ action.whatsapp_target_type === 'group' ? 'group' : 'phone';
634
+ const renderedMessage = String(
635
+ renderTemplate(action.whatsapp_template, body) ?? '',
636
+ ).trim();
637
+ const renderedTarget = String(
638
+ renderTemplate(action.whatsapp_target, body) ?? '',
639
+ ).trim();
640
+
641
+ if (!renderedMessage) {
642
+ throw new BadRequestException(
643
+ 'WhatsApp action template rendered an empty message.',
644
+ );
645
+ }
646
+
647
+ const target = this.normalizeWhatsappTarget(renderedTarget, targetType);
648
+ const requestPayload = {
649
+ provider: 'evolution',
650
+ url,
651
+ instance: action.whatsapp_instance,
652
+ targetType,
653
+ number: target,
654
+ text: renderedMessage,
655
+ };
656
+
657
+ let response: any;
658
+ try {
659
+ response = await firstValueFrom(
660
+ this.http.post(
661
+ url,
662
+ {
663
+ number: target,
664
+ text: renderedMessage,
554
665
  },
555
- timeout: 15000,
556
- },
557
- ),
558
- );
666
+ {
667
+ headers: {
668
+ apikey: action.whatsapp_token,
669
+ },
670
+ timeout: 15000,
671
+ },
672
+ ),
673
+ );
674
+ } catch (error) {
675
+ this.attachErrorRequestPayload(error, requestPayload);
676
+ throw error;
677
+ }
559
678
 
560
679
  return {
561
- requestPayload: {
562
- url,
563
- number: target,
564
- text: message,
565
- },
680
+ requestPayload,
566
681
  responsePayload: {
567
682
  status: response?.status || null,
568
683
  statusText: response?.statusText || null,
@@ -600,6 +715,48 @@ export class WebhookIntegrationService {
600
715
  }
601
716
  }
602
717
 
718
+ private validateActionConfiguration(action: any) {
719
+ if (action?.type === 'email') {
720
+ const missing: string[] = [];
721
+
722
+ if (!this.nullableNumber(action.mail_profile_id)) {
723
+ missing.push('mail_profile_id');
724
+ }
725
+
726
+ if (!this.nullableNumber(action.mail_id)) {
727
+ missing.push('mail_id');
728
+ }
729
+
730
+ if (!this.nullableString(action.email_to, true)) {
731
+ missing.push('email_to');
732
+ }
733
+
734
+ if (missing.length) {
735
+ throw new BadRequestException(
736
+ `Email action is missing required configuration: ${missing.join(', ')}.`,
737
+ );
738
+ }
739
+ }
740
+
741
+ if (action?.type === 'whatsapp_evolution') {
742
+ const missing = [
743
+ ['whatsapp_target', action.whatsapp_target],
744
+ ['whatsapp_template', action.whatsapp_template],
745
+ ['whatsapp_instance', action.whatsapp_instance],
746
+ ['whatsapp_base_url', action.whatsapp_base_url],
747
+ ['whatsapp_token', action.whatsapp_token],
748
+ ]
749
+ .filter(([, value]) => !String(value || '').trim())
750
+ .map(([key]) => key);
751
+
752
+ if (missing.length) {
753
+ throw new BadRequestException(
754
+ `WhatsApp action is missing required configuration: ${missing.join(', ')}.`,
755
+ );
756
+ }
757
+ }
758
+ }
759
+
603
760
  private validateBodySchema(integration: any, body: any) {
604
761
  if (!integration.body_schema) {
605
762
  return;
@@ -777,6 +934,48 @@ export class WebhookIntegrationService {
777
934
  };
778
935
  }
779
936
 
937
+ private extractErrorRequestPayload(error: unknown) {
938
+ if (!error || typeof error !== 'object') {
939
+ return null;
940
+ }
941
+
942
+ const maybePayload = (error as any).__webhookRequestPayload;
943
+ return maybePayload || null;
944
+ }
945
+
946
+ private attachErrorRequestPayload(error: unknown, requestPayload: unknown) {
947
+ if (!error || typeof error !== 'object') {
948
+ return;
949
+ }
950
+
951
+ (error as any).__webhookRequestPayload = requestPayload;
952
+ }
953
+
954
+ private normalizeWhatsappTarget(
955
+ renderedTarget: string,
956
+ targetType: 'phone' | 'group',
957
+ ) {
958
+ const rawTarget = String(renderedTarget || '').trim();
959
+ if (!rawTarget) {
960
+ throw new BadRequestException(
961
+ 'WhatsApp action target template rendered an empty value.',
962
+ );
963
+ }
964
+
965
+ if (targetType === 'group') {
966
+ return rawTarget;
967
+ }
968
+
969
+ const normalized = rawTarget.replace(/\D+/g, '');
970
+ if (!normalized) {
971
+ throw new BadRequestException(
972
+ 'WhatsApp action target must contain at least one digit for phone targets.',
973
+ );
974
+ }
975
+
976
+ return normalized;
977
+ }
978
+
780
979
  private getRemoteIp(req: Request) {
781
980
  const forwardedFor = req.headers['x-forwarded-for'];
782
981
  const forwardedIp = Array.isArray(forwardedFor)
@@ -835,7 +1034,7 @@ export class WebhookIntegrationService {
835
1034
  return normalized;
836
1035
  }
837
1036
 
838
- private normalizeAction(data: any, partial = false) {
1037
+ private normalizeAction(data: WebhookActionPayload, partial = false) {
839
1038
  const normalized: Record<string, any> = {};
840
1039
  const assign = (key: string, value: any) => {
841
1040
  if (!partial || value !== undefined) {
@@ -847,8 +1046,8 @@ export class WebhookIntegrationService {
847
1046
  assign('name', String(data.name ?? '').trim());
848
1047
  assign('order', Number(data.order ?? 0));
849
1048
  assign('status', data.status === 'inactive' ? 'inactive' : 'active');
850
- assign('mail_profile_id', this.nullableNumber(data.mail_profile_id));
851
- assign('mail_id', this.nullableNumber(data.mail_id));
1049
+ assign('mail_profile_id', this.nullableNumber(data.mail_profile_id, partial));
1050
+ assign('mail_id', this.nullableNumber(data.mail_id, partial));
852
1051
  assign('email_to', this.nullableString(data.email_to, partial));
853
1052
  assign('email_cc', this.nullableString(data.email_cc, partial));
854
1053
  assign('email_bcc', this.nullableString(data.email_bcc, partial));
@@ -887,8 +1086,12 @@ export class WebhookIntegrationService {
887
1086
  return normalized || null;
888
1087
  }
889
1088
 
890
- private nullableNumber(value: any) {
891
- if (value === undefined || value === null || value === '') {
1089
+ private nullableNumber(value: any, partial = false) {
1090
+ if (value === undefined) {
1091
+ return partial ? undefined : null;
1092
+ }
1093
+
1094
+ if (value === null || value === '') {
892
1095
  return null;
893
1096
  }
894
1097