@ikatec/digisac-api-sdk 4.14.0 → 4.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +10 -3
  2. package/dist/apis/absence/AbsenceApi.cjs +2 -2
  3. package/dist/apis/absence/AbsenceApi.cjs.map +1 -1
  4. package/dist/apis/absence/AbsenceApi.d.ts +2 -2
  5. package/dist/apis/absence/AbsenceApi.mjs +2 -2
  6. package/dist/apis/absence/AbsenceApi.mjs.map +1 -1
  7. package/dist/apis/absence/types.d.ts +1 -1
  8. package/dist/apis/answers/AnswersApi.cjs +23 -2
  9. package/dist/apis/answers/AnswersApi.cjs.map +1 -1
  10. package/dist/apis/answers/AnswersApi.d.ts +16 -2
  11. package/dist/apis/answers/AnswersApi.d.ts.map +1 -1
  12. package/dist/apis/answers/AnswersApi.mjs +23 -2
  13. package/dist/apis/answers/AnswersApi.mjs.map +1 -1
  14. package/dist/apis/answers/types.d.ts +1 -2
  15. package/dist/apis/answers/types.d.ts.map +1 -1
  16. package/dist/apis/authHistory/AuthHistoryApi.cjs +9 -2
  17. package/dist/apis/authHistory/AuthHistoryApi.cjs.map +1 -1
  18. package/dist/apis/authHistory/AuthHistoryApi.d.ts +7 -2
  19. package/dist/apis/authHistory/AuthHistoryApi.d.ts.map +1 -1
  20. package/dist/apis/authHistory/AuthHistoryApi.mjs +9 -2
  21. package/dist/apis/authHistory/AuthHistoryApi.mjs.map +1 -1
  22. package/dist/apis/authHistory/types.d.ts +6 -1
  23. package/dist/apis/authHistory/types.d.ts.map +1 -1
  24. package/dist/apis/bots/BotsApi.cjs +16 -7
  25. package/dist/apis/bots/BotsApi.cjs.map +1 -1
  26. package/dist/apis/bots/BotsApi.d.ts +13 -7
  27. package/dist/apis/bots/BotsApi.d.ts.map +1 -1
  28. package/dist/apis/bots/BotsApi.mjs +16 -7
  29. package/dist/apis/bots/BotsApi.mjs.map +1 -1
  30. package/dist/apis/bots/types.d.ts +12 -2
  31. package/dist/apis/bots/types.d.ts.map +1 -1
  32. package/dist/apis/campaigns/CampaignsApi.cjs +25 -1
  33. package/dist/apis/campaigns/CampaignsApi.cjs.map +1 -1
  34. package/dist/apis/campaigns/CampaignsApi.d.ts +16 -1
  35. package/dist/apis/campaigns/CampaignsApi.d.ts.map +1 -1
  36. package/dist/apis/campaigns/CampaignsApi.mjs +25 -1
  37. package/dist/apis/campaigns/CampaignsApi.mjs.map +1 -1
  38. package/dist/apis/campaigns/types.d.ts +98 -6
  39. package/dist/apis/campaigns/types.d.ts.map +1 -1
  40. package/dist/apis/cards/types.d.ts +5 -5
  41. package/dist/apis/categories/CategoriesApi.cjs +1 -2
  42. package/dist/apis/categories/CategoriesApi.cjs.map +1 -1
  43. package/dist/apis/categories/CategoriesApi.d.ts +1 -2
  44. package/dist/apis/categories/CategoriesApi.d.ts.map +1 -1
  45. package/dist/apis/categories/CategoriesApi.mjs +1 -2
  46. package/dist/apis/categories/CategoriesApi.mjs.map +1 -1
  47. package/dist/apis/clientFeedback/ClientFeedbackApi.cjs +2 -3
  48. package/dist/apis/clientFeedback/ClientFeedbackApi.cjs.map +1 -1
  49. package/dist/apis/clientFeedback/ClientFeedbackApi.d.ts +2 -3
  50. package/dist/apis/clientFeedback/ClientFeedbackApi.d.ts.map +1 -1
  51. package/dist/apis/clientFeedback/ClientFeedbackApi.mjs +2 -3
  52. package/dist/apis/clientFeedback/ClientFeedbackApi.mjs.map +1 -1
  53. package/dist/apis/contacts/ContactsApi.cjs +20 -6
  54. package/dist/apis/contacts/ContactsApi.cjs.map +1 -1
  55. package/dist/apis/contacts/ContactsApi.d.ts +28 -4
  56. package/dist/apis/contacts/ContactsApi.d.ts.map +1 -1
  57. package/dist/apis/contacts/ContactsApi.mjs +20 -6
  58. package/dist/apis/contacts/ContactsApi.mjs.map +1 -1
  59. package/dist/apis/contacts/types.d.ts +101 -2
  60. package/dist/apis/contacts/types.d.ts.map +1 -1
  61. package/dist/apis/customFields/types.d.ts +4 -4
  62. package/dist/apis/dashboard/DashboardApi.cjs +3 -3
  63. package/dist/apis/dashboard/DashboardApi.cjs.map +1 -1
  64. package/dist/apis/dashboard/DashboardApi.d.ts +3 -3
  65. package/dist/apis/dashboard/DashboardApi.mjs +3 -3
  66. package/dist/apis/dashboard/DashboardApi.mjs.map +1 -1
  67. package/dist/apis/dashboard/types.d.ts +11 -4
  68. package/dist/apis/dashboard/types.d.ts.map +1 -1
  69. package/dist/apis/departments/DepartmentsApi.cjs +5 -5
  70. package/dist/apis/departments/DepartmentsApi.cjs.map +1 -1
  71. package/dist/apis/departments/DepartmentsApi.d.ts +5 -5
  72. package/dist/apis/departments/DepartmentsApi.mjs +5 -5
  73. package/dist/apis/departments/DepartmentsApi.mjs.map +1 -1
  74. package/dist/apis/departments/types.d.ts +6 -0
  75. package/dist/apis/departments/types.d.ts.map +1 -1
  76. package/dist/apis/distribution/DistributionApi.cjs +3 -4
  77. package/dist/apis/distribution/DistributionApi.cjs.map +1 -1
  78. package/dist/apis/distribution/DistributionApi.d.ts +3 -4
  79. package/dist/apis/distribution/DistributionApi.d.ts.map +1 -1
  80. package/dist/apis/distribution/DistributionApi.mjs +3 -4
  81. package/dist/apis/distribution/DistributionApi.mjs.map +1 -1
  82. package/dist/apis/files/FilesApi.cjs +13 -1
  83. package/dist/apis/files/FilesApi.cjs.map +1 -1
  84. package/dist/apis/files/FilesApi.d.ts +12 -2
  85. package/dist/apis/files/FilesApi.d.ts.map +1 -1
  86. package/dist/apis/files/FilesApi.mjs +13 -1
  87. package/dist/apis/files/FilesApi.mjs.map +1 -1
  88. package/dist/apis/files/types.d.ts +19 -1
  89. package/dist/apis/files/types.d.ts.map +1 -1
  90. package/dist/apis/kanbanCards/KanbanCardsApi.cjs +32 -0
  91. package/dist/apis/kanbanCards/KanbanCardsApi.cjs.map +1 -1
  92. package/dist/apis/kanbanCards/KanbanCardsApi.d.ts +27 -1
  93. package/dist/apis/kanbanCards/KanbanCardsApi.d.ts.map +1 -1
  94. package/dist/apis/kanbanCards/KanbanCardsApi.mjs +32 -0
  95. package/dist/apis/kanbanCards/KanbanCardsApi.mjs.map +1 -1
  96. package/dist/apis/kanbanCards/types.d.ts +1 -1
  97. package/dist/apis/kanbanCards/types.d.ts.map +1 -1
  98. package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs +19 -0
  99. package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs.map +1 -1
  100. package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts +16 -1
  101. package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts.map +1 -1
  102. package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs +19 -0
  103. package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs.map +1 -1
  104. package/dist/apis/kanbanColumns/types.d.ts +4 -0
  105. package/dist/apis/kanbanColumns/types.d.ts.map +1 -1
  106. package/dist/apis/messages/MessagesApi.cjs +13 -4
  107. package/dist/apis/messages/MessagesApi.cjs.map +1 -1
  108. package/dist/apis/messages/MessagesApi.d.ts +13 -4
  109. package/dist/apis/messages/MessagesApi.d.ts.map +1 -1
  110. package/dist/apis/messages/MessagesApi.mjs +13 -4
  111. package/dist/apis/messages/MessagesApi.mjs.map +1 -1
  112. package/dist/apis/messages/types.d.ts +5 -0
  113. package/dist/apis/messages/types.d.ts.map +1 -1
  114. package/dist/apis/pipeline/types.d.ts +7 -8
  115. package/dist/apis/pipeline/types.d.ts.map +1 -1
  116. package/dist/apis/quickReplies/types.d.ts +4 -1
  117. package/dist/apis/quickReplies/types.d.ts.map +1 -1
  118. package/dist/apis/schedule/types.d.ts +41 -10
  119. package/dist/apis/schedule/types.d.ts.map +1 -1
  120. package/dist/apis/terms/TermsApi.cjs +2 -2
  121. package/dist/apis/terms/TermsApi.cjs.map +1 -1
  122. package/dist/apis/terms/TermsApi.d.ts +2 -2
  123. package/dist/apis/terms/TermsApi.mjs +2 -2
  124. package/dist/apis/terms/TermsApi.mjs.map +1 -1
  125. package/dist/apis/tickets/TicketsApi.cjs +18 -8
  126. package/dist/apis/tickets/TicketsApi.cjs.map +1 -1
  127. package/dist/apis/tickets/TicketsApi.d.ts +15 -8
  128. package/dist/apis/tickets/TicketsApi.d.ts.map +1 -1
  129. package/dist/apis/tickets/TicketsApi.mjs +18 -8
  130. package/dist/apis/tickets/TicketsApi.mjs.map +1 -1
  131. package/dist/apis/tickets/types.d.ts +4 -1
  132. package/dist/apis/tickets/types.d.ts.map +1 -1
  133. package/dist/apis/timetable/TimetableApi.cjs +6 -0
  134. package/dist/apis/timetable/TimetableApi.cjs.map +1 -1
  135. package/dist/apis/timetable/TimetableApi.d.ts +6 -0
  136. package/dist/apis/timetable/TimetableApi.d.ts.map +1 -1
  137. package/dist/apis/timetable/TimetableApi.mjs +6 -0
  138. package/dist/apis/timetable/TimetableApi.mjs.map +1 -1
  139. package/dist/apis/timetable/types.d.ts +8 -0
  140. package/dist/apis/timetable/types.d.ts.map +1 -1
  141. package/dist/apis/users/UsersApi.cjs +11 -3
  142. package/dist/apis/users/UsersApi.cjs.map +1 -1
  143. package/dist/apis/users/UsersApi.d.ts +10 -4
  144. package/dist/apis/users/UsersApi.d.ts.map +1 -1
  145. package/dist/apis/users/UsersApi.mjs +11 -3
  146. package/dist/apis/users/UsersApi.mjs.map +1 -1
  147. package/dist/apis/users/types.d.ts +26 -0
  148. package/dist/apis/users/types.d.ts.map +1 -1
  149. package/dist/apis/webhooks/types.d.ts +51 -6
  150. package/dist/apis/webhooks/types.d.ts.map +1 -1
  151. package/dist/core/BaseReadApi.cjs +2 -2
  152. package/dist/core/BaseReadApi.cjs.map +1 -1
  153. package/dist/core/BaseReadApi.d.ts +2 -2
  154. package/dist/core/BaseReadApi.mjs +2 -2
  155. package/dist/core/BaseReadApi.mjs.map +1 -1
  156. package/dist/core/errors.cjs +4 -1
  157. package/dist/core/errors.cjs.map +1 -1
  158. package/dist/core/errors.d.ts +4 -1
  159. package/dist/core/errors.d.ts.map +1 -1
  160. package/dist/core/errors.mjs +4 -1
  161. package/dist/core/errors.mjs.map +1 -1
  162. package/package.json +1 -1
  163. package/src/apis/absence/AbsenceApi.ts +2 -2
  164. package/src/apis/absence/types.ts +1 -1
  165. package/src/apis/answers/AnswersApi.test.ts +32 -0
  166. package/src/apis/answers/AnswersApi.ts +38 -2
  167. package/src/apis/answers/types.ts +1 -2
  168. package/src/apis/authHistory/AuthHistoryApi.test.ts +16 -0
  169. package/src/apis/authHistory/AuthHistoryApi.ts +10 -2
  170. package/src/apis/authHistory/types.ts +6 -1
  171. package/src/apis/bots/BotsApi.test.ts +16 -0
  172. package/src/apis/bots/BotsApi.ts +25 -7
  173. package/src/apis/bots/types.ts +12 -2
  174. package/src/apis/campaigns/CampaignsApi.test.ts +48 -0
  175. package/src/apis/campaigns/CampaignsApi.ts +31 -2
  176. package/src/apis/campaigns/types.ts +101 -3
  177. package/src/apis/cards/types.ts +5 -5
  178. package/src/apis/categories/CategoriesApi.ts +1 -2
  179. package/src/apis/clientFeedback/ClientFeedbackApi.ts +2 -3
  180. package/src/apis/contacts/ContactsApi.test.ts +49 -2
  181. package/src/apis/contacts/ContactsApi.ts +64 -4
  182. package/src/apis/contacts/types.ts +111 -1
  183. package/src/apis/creditMovements/CreditMovementsApi.test.ts +1 -1
  184. package/src/apis/customFields/types.ts +4 -4
  185. package/src/apis/dashboard/DashboardApi.test-d.ts +9 -0
  186. package/src/apis/dashboard/DashboardApi.ts +3 -3
  187. package/src/apis/dashboard/types.ts +11 -4
  188. package/src/apis/departments/DepartmentsApi.ts +5 -5
  189. package/src/apis/departments/types.ts +13 -0
  190. package/src/apis/distribution/DistributionApi.ts +3 -4
  191. package/src/apis/files/FilesApi.test.ts +21 -0
  192. package/src/apis/files/FilesApi.ts +19 -1
  193. package/src/apis/files/types.ts +20 -1
  194. package/src/apis/kanbanCards/KanbanCardsApi.test.ts +21 -0
  195. package/src/apis/kanbanCards/KanbanCardsApi.ts +47 -1
  196. package/src/apis/kanbanCards/types.ts +1 -1
  197. package/src/apis/kanbanColumns/KanbanColumnsApi.test.ts +26 -0
  198. package/src/apis/kanbanColumns/KanbanColumnsApi.ts +31 -0
  199. package/src/apis/kanbanColumns/types.ts +5 -0
  200. package/src/apis/messages/MessagesApi.ts +13 -4
  201. package/src/apis/messages/types.ts +5 -0
  202. package/src/apis/payloads.test-d.ts +245 -5
  203. package/src/apis/pipeline/types.ts +7 -8
  204. package/src/apis/queryFormat.test.ts +13 -0
  205. package/src/apis/quickReplies/types.ts +4 -1
  206. package/src/apis/schedule/types.ts +42 -10
  207. package/src/apis/terms/TermsApi.ts +2 -2
  208. package/src/apis/tickets/TicketsApi.ts +28 -8
  209. package/src/apis/tickets/types.ts +4 -1
  210. package/src/apis/timetable/TimetableApi.ts +6 -0
  211. package/src/apis/timetable/types.ts +9 -0
  212. package/src/apis/users/UsersApi.test.ts +17 -0
  213. package/src/apis/users/UsersApi.ts +21 -3
  214. package/src/apis/users/types.ts +28 -0
  215. package/src/apis/webhooks/types.ts +53 -6
  216. package/src/core/BaseReadApi.ts +2 -2
  217. package/src/core/errors.ts +4 -1
@@ -129,8 +129,7 @@ export type CreatePipelineStagePayload = {
129
129
 
130
130
  export type UpdatePipelineStagePayload = CreatePipelineStagePayload & {
131
131
  /**
132
- * The stage id. Send it: the duplicate-name check compares against the `id` of the body,
133
- * so without it keeping the current name answers `'STAGE_ALREADY_EXIST'`.
132
+ * The stage id. Send it: without it, keeping the current name answers `'STAGE_ALREADY_EXIST'`.
134
133
  */
135
134
  id?: string
136
135
  }
@@ -145,10 +144,10 @@ export type DeletePipelineStagePayload = {
145
144
  typeAction?: 'move'
146
145
  idNewStage?: string
147
146
  /**
148
- * Author of the card movements written by `'move'` — the backend reads it from the body, not
149
- * from the token (the UI sends the logged user). Without it, moving a stage that has cards
150
- * fails with 500 (`CardMovement.userId cannot be null`) after the cards were already moved,
151
- * and the stage is kept.
147
+ * The user that moves the cards with `'move'`: send the logged user (`{ id }` of
148
+ * `MeApi.getMe`). Without it, moving a stage that has cards fails with 500
149
+ * (`CardMovement.userId cannot be null`) after the cards were already moved, and the stage is
150
+ * kept.
152
151
  */
153
152
  user?: { id: string }
154
153
  }
@@ -163,7 +162,7 @@ export type PipelineStageStatusWithCount = PipelineStageStatus & { cardsCount: n
163
162
 
164
163
  /**
165
164
  * What happens to the cards of a deleted status: `'keep-without-status'` clears their status,
166
- * `'move-to-another'` sets `newStatusId` (not validated by the backend).
165
+ * `'move-to-another'` moves them to the status `newStatusId`.
167
166
  */
168
167
  export type DeletePipelineStatusPayload =
169
168
  | { action: 'keep-without-status' }
@@ -192,7 +191,7 @@ export type PipelineAutomation = {
192
191
 
193
192
  export type CreatePipelineAutomationPayload = {
194
193
  pipelineId: string
195
- /** The backend does not validate it (any string is stored); `'notification'` is the only one used. */
194
+ /** `'notification'` is the only one used. */
196
195
  type: PipelineAutomationType
197
196
  config?: PipelineAutomationConfig
198
197
  isArchived?: boolean
@@ -65,6 +65,19 @@ const cases: Case[] = [
65
65
  return (f ? api.withQueryFormat(f) : api).getMany(campaignsQuery)
66
66
  },
67
67
  },
68
+ {
69
+ name: 'CampaignsApi.getOne (one page of one campaign)',
70
+ path: '/campaigns',
71
+ query: { ...campaignsQuery, page: 1, perPage: 1 },
72
+ call: (client, f) => {
73
+ const api = new CampaignsApi(client)
74
+ return (f ? api.withQueryFormat(f) : api).getOne({
75
+ ...campaignsQuery,
76
+ paginate: false,
77
+ limit: 5,
78
+ })
79
+ },
80
+ },
68
81
  {
69
82
  name: 'CampaignsApi.getContacts',
70
83
  path: '/campaigns/c1/contacts',
@@ -49,7 +49,10 @@ export type UpdateQuickReplyPayload = {
49
49
  files: QuickReplyFilePayload[]
50
50
  }
51
51
 
52
- /** The query of `loadOnDemand`, passed to the database as is. */
52
+ /**
53
+ * The query of `loadOnDemand`: the `where`, `include`, `order`, `attributes`, `limit` and `offset`
54
+ * of a list query.
55
+ */
53
56
  export type QuickRepliesLoadOnDemandQuery = Pick<
54
57
  ListQuery<QuickReply>,
55
58
  'where' | 'include' | 'order' | 'attributes' | 'limit' | 'offset'
@@ -1,29 +1,52 @@
1
+ import type { CampaignTemplateParameter } from '../campaigns/types'
1
2
  import type { Contact } from '../contacts/types'
2
3
  import type { Department } from '../departments/types'
3
4
  import type { File } from '../files/types'
4
5
  import type { User } from '../users/types'
5
6
 
6
- /** `scheduled` until the worker runs it; `error` and `not_sent` come with the `reason`. */
7
+ /**
8
+ * - `scheduled`: waiting for the worker.
9
+ * - `done`: sent, or skipped with `reason: null` (contact blocked, connection off, open ticket
10
+ * without `sendWithOpenTicket`, user without access to the connection). It is stored
11
+ * before the message is sent, so a template schedule can still turn `error` afterwards.
12
+ * Archiving the connection also sets its `scheduled` schedules as `done`, and archiving the
13
+ * department every schedule of it (keeping the `reason` of the ones that had failed).
14
+ * - `not_sent`: only for a template schedule (`hsmId`), with `HSM_IS_BLOCKED` or
15
+ * `SERVICE_IS_BLOCKED`.
16
+ * - `error`: `DDD_BLOCKED` for any schedule; the other reasons only for a template schedule sent
17
+ * with `extraOptions` (a plain schedule is `done` instead).
18
+ */
7
19
  export type ScheduleStatus = 'scheduled' | 'done' | 'error' | 'not_sent'
8
20
 
21
+ /** The template parameters of a WhatsApp Business schedule (`hsmId`), sent with the message. */
22
+ export type ScheduleExtraOptions = {
23
+ /** The parameters of the header, body and buttons of the template, as a campaign takes them. */
24
+ parameters?: CampaignTemplateParameter[]
25
+ [key: string]: unknown
26
+ }
27
+
9
28
  export type Schedule = {
10
29
  id: string
11
30
  status: ScheduleStatus
12
31
  /**
13
- * Why it was not sent: `ALREADY_TICKET_OPENED`, `DDD_BLOCKED`, `SERVICE_IS_NOT_ENABLED`,
14
- * `CONTACT_IS_BLOCKED`, `CONTACT_NOT_EXISTS`, `HSM_LIMIT_EXCEEDED`, `HSM_IS_BLOCKED`,
15
- * `SERVICE_IS_BLOCKED`, `INVALID_PAYLOAD`, a WhatsApp Business error code or
16
- * `SCHEDULE_UNKNOWN_REASON`.
32
+ * Why an `error` or `not_sent` schedule was not sent (see {@link ScheduleStatus}):
33
+ * `ALREADY_TICKET_OPENED`, `DDD_BLOCKED`, `SERVICE_IS_NOT_ENABLED`, `CONTACT_IS_BLOCKED`,
34
+ * `CONTACT_NOT_EXISTS`, `HSM_LIMIT_EXCEEDED`, `HSM_IS_BLOCKED`, `SERVICE_IS_BLOCKED`,
35
+ * `INVALID_PAYLOAD`, a WhatsApp Business error code or `SCHEDULE_UNKNOWN_REASON`. Usually `null`
36
+ * for a `done` schedule (see the archiving of the department in {@link ScheduleStatus}).
17
37
  */
18
38
  reason: string | null
19
- /** For a WhatsApp Business template (`hsmId`), the message the server built from it. */
39
+ /**
40
+ * For a WhatsApp Business template (`hsmId`) sent with `extraOptions`, the message the server
41
+ * built from it; otherwise the `message` sent.
42
+ */
20
43
  message: string | null
21
44
  notes: string
22
45
  openTicket: boolean | null
23
46
  notificateUser: boolean | null
24
47
  /** Sends the message even when the contact already has an open ticket. */
25
48
  sendWithOpenTicket: boolean | null
26
- extraOptions: Record<string, unknown> | null
49
+ extraOptions: ScheduleExtraOptions | null
27
50
  hsmId: string | null
28
51
  hsmFileId: string | null
29
52
  scheduledAt: string
@@ -73,7 +96,11 @@ export type CreateSchedulePayload = {
73
96
  scheduledAt: string
74
97
  contactId: string
75
98
  departmentId: string
76
- /** Up to 1024 characters. Optional for a WhatsApp Business template, built from `hsmId`. */
99
+ /**
100
+ * Up to 1024 characters. Optional for a WhatsApp Business template sent with `extraOptions` (the
101
+ * server builds it from the template); without both, the schedule turns `done` and no message is
102
+ * sent.
103
+ */
77
104
  message?: string
78
105
  /**
79
106
  * Up to 1024 characters. Required by the route only with `openTicket: true`, but the column is
@@ -85,8 +112,13 @@ export type CreateSchedulePayload = {
85
112
  sendWithOpenTicket?: boolean
86
113
  userId?: string
87
114
  hsmId?: string
115
+ /** The header file of the template (`hsmId`), uploaded with `attachedType: 'hsm.file'`. */
88
116
  hsmFileId?: string
89
- extraOptions?: Record<string, unknown>
117
+ /**
118
+ * Send it with `hsmId` (`{}` is enough for a template without parameters): without it the
119
+ * schedule sends `message` as plain text, not the template.
120
+ */
121
+ extraOptions?: ScheduleExtraOptions
90
122
  /** New attachments only: the create drops `{ id }` items. */
91
123
  files?: ScheduleNewFilePayload[]
92
124
  }
@@ -107,7 +139,7 @@ export type UpdateSchedulePayload = {
107
139
  sendWithOpenTicket?: boolean
108
140
  hsmId?: string | null
109
141
  hsmFileId?: string | null
110
- extraOptions?: Record<string, unknown> | null
142
+ extraOptions?: ScheduleExtraOptions | null
111
143
  /** Replaces the attachments: `{ id }` keeps one, `{ base64, ... }` adds one; omitted or `[]` removes all. */
112
144
  files?: ScheduleFilePayload[]
113
145
  }
@@ -6,8 +6,8 @@ import type { Term } from './types'
6
6
  * Platform terms of use. Terms are published by Agnus (billing) and accepted by the account users,
7
7
  * so the `/terms` route has no create/list/update/delete — only the routes below.
8
8
  *
9
- * `GET /terms/:id/export-pdf` is not exposed: it answers a binary PDF, and `ApiClient` only
10
- * handles JSON/text bodies.
9
+ * `GET /terms/:id/export-pdf` (a binary PDF) has no method: read it with `client.requestRaw` (see
10
+ * "Raw responses" in the README).
11
11
  */
12
12
  export class TermsApi extends BaseApi implements HasGetById<Term> {
13
13
  public readonly basePath = '/terms'
@@ -1,5 +1,6 @@
1
1
  import type { ApiClient } from '../../core/ApiClient'
2
2
  import { BaseCrudApi } from '../../core/BaseCrudApi'
3
+ import type { GetByIdQuery } from '../../core/types'
3
4
  import type {
4
5
  Ticket,
5
6
  CreateTicketPayload,
@@ -15,23 +16,42 @@ import type {
15
16
  /**
16
17
  * Tickets. The backend only serves them for reading (`getMany`, `getOne`, `getById`, the counts,
17
18
  * the first waiting time and the exports) plus `closeMany`: a ticket is opened and transferred by
18
- * `ContactsApi.transferTicket`. The reads check no permission (any authenticated user): the
19
- * `@permissions` of the inherited `getMany`, `getOne` and `getById` do not apply here. `getById`
20
- * of an unknown id resolves `null`. For a user who is not an admin, `getMany` leaves out the
21
- * tickets of the contacts of the connections restricted to that user; the counts and `getById`
22
- * do not.
19
+ * `ContactsApi.transferTicket`, and the ticket of one contact is closed by
20
+ * `ContactsApi.closeTicket`. `getById` of an unknown id resolves `null`. For a user who is not an
21
+ * admin, `getMany` leaves out the tickets of the contacts of the connections restricted to that
22
+ * user.
23
23
  */
24
24
  export class TicketsApi extends BaseCrudApi<Ticket, CreateTicketPayload, UpdateTicketPayload> {
25
25
  constructor(client: ApiClient) {
26
26
  super(client, '/tickets')
27
27
  }
28
28
 
29
+ /** Returns the first ticket matching the query, or `null` when none match. */
30
+ override getOne(
31
+ query?: TicketsListQuery,
32
+ headers?: Record<string, string>,
33
+ ): Promise<Ticket | null> {
34
+ return super.getOne(query, headers)
35
+ }
36
+
37
+ /** Returns a ticket by ID; an unknown id resolves `null`. */
38
+ override getById(
39
+ id: string,
40
+ query?: GetByIdQuery<Ticket>,
41
+ headers?: Record<string, string>,
42
+ ): Promise<Ticket> {
43
+ return super.getById(id, query, headers)
44
+ }
45
+
29
46
  /** @deprecated Not served: `POST /tickets` answers 404 `Route not found.`. Open a ticket through `ContactsApi.transferTicket`. */
30
47
  override create(body: CreateTicketPayload, headers?: Record<string, string>): Promise<Ticket> {
31
48
  return super.create(body, headers)
32
49
  }
33
50
 
34
- /** @deprecated Not served: `PUT /tickets/{id}` answers 404 `Route not found.`. Transfer through `ContactsApi.transferTicket`, close through `closeMany`. */
51
+ /**
52
+ * @deprecated Not served: `PUT /tickets/{id}` answers 404 `Route not found.`. Transfer through
53
+ * `ContactsApi.transferTicket`, close through `ContactsApi.closeTicket` or `closeMany`.
54
+ */
35
55
  override updateById(
36
56
  id: string,
37
57
  body: UpdateTicketPayload,
@@ -46,8 +66,8 @@ export class TicketsApi extends BaseCrudApi<Ticket, CreateTicketPayload, UpdateT
46
66
  }
47
67
 
48
68
  /**
49
- * Closes multiple tickets in a single request. This is the only ticket-close
50
- * endpoint exposed by the API — there is no per-ticket close/update route.
69
+ * Closes multiple tickets in a single request. `ContactsApi.closeTicket` closes the ticket of one
70
+ * contact by the contact id, and also takes the rating of the AI summary.
51
71
  *
52
72
  * Pass `{ ids }` to close specific tickets, or `{ allContactsSelected: true, query }`
53
73
  * to close every OPEN ticket matching `query` (the backend forces `isOpen: true`): an empty
@@ -142,7 +142,10 @@ export type CreateTicketPayload = {
142
142
  origin?: TicketOrigin
143
143
  }
144
144
 
145
- /** @deprecated Not served: the backend has no `PUT /tickets/{id}`. Transfer through `ContactsApi.transferTicket`, close through `TicketsApi.closeMany`. */
145
+ /**
146
+ * @deprecated Not served: the backend has no `PUT /tickets/{id}`. Transfer through
147
+ * `ContactsApi.transferTicket`, close through `ContactsApi.closeTicket` or `TicketsApi.closeMany`.
148
+ */
146
149
  export type UpdateTicketPayload = {
147
150
  departmentId?: string
148
151
  userId?: string | null
@@ -3,6 +3,12 @@ import type { ListQuery } from '../../core/types'
3
3
  import { BaseCrudApi } from '../../core/BaseCrudApi'
4
4
  import type { Timetable, CreateTimetablePayload, UpdateTimetablePayload } from './types'
5
5
 
6
+ /**
7
+ * Timetables (work hours) of the users. Out of the timetable of the user, most authenticated routes
8
+ * answer 403 `Is out of office hours`, with the `workPlan` of the timetable in the `extra` of the
9
+ * error body (see `OutOfOfficeHoursErrorExtra`). Logging in (`POST /oauth/token`) and setting
10
+ * the status to `offline` still work.
11
+ */
6
12
  export class TimetableApi extends BaseCrudApi<
7
13
  Timetable,
8
14
  CreateTimetablePayload,
@@ -32,3 +32,12 @@ export type CreateTimetablePayload = {
32
32
 
33
33
  /** The backend requires the three fields on every update (400 `required` otherwise). */
34
34
  export type UpdateTimetablePayload = CreateTimetablePayload
35
+
36
+ /**
37
+ * The `extra` of the 403 `Is out of office hours` error body: the timetable of the user. The error
38
+ * is a `PermissionDeniedError` with that `message`; read it as
39
+ * `(error.body as { extra?: OutOfOfficeHoursErrorExtra }).extra?.workPlan`.
40
+ */
41
+ export type OutOfOfficeHoursErrorExtra = {
42
+ workPlan: TimetableWorkSlot[]
43
+ }
@@ -3,6 +3,7 @@ import { UsersApi } from './UsersApi'
3
3
  import type { ApiClient } from '../../core/ApiClient'
4
4
  import type {
5
5
  BulkUsersStatusPreview,
6
+ BulkUpdateUsersLinksResult,
6
7
  BulkUsersStatusResult,
7
8
  ImportUsersResult,
8
9
  User,
@@ -109,6 +110,22 @@ describe('UsersApi', () => {
109
110
  })
110
111
  })
111
112
 
113
+ describe('bulkUpdateLinks', () => {
114
+ it('calls client.put with /users/v2/bulk-update and body', async () => {
115
+ const response: BulkUpdateUsersLinksResult = {
116
+ changed: 1,
117
+ failed: 0,
118
+ changedIds: ['usr-1'],
119
+ missingIds: ['usr-2'],
120
+ }
121
+ vi.mocked(client.put).mockResolvedValue(response)
122
+ const body = { ids: ['usr-1', 'usr-2'], timetableId: null, departmentIds: ['dep-1'] }
123
+ const result = await api.bulkUpdateLinks(body, headers)
124
+ expect(client.put).toHaveBeenCalledWith('/users/v2/bulk-update', body, headers)
125
+ expect(result).toEqual(response)
126
+ })
127
+ })
128
+
112
129
  describe('bulkStatus', () => {
113
130
  it('calls client.post with /users/bulk-status and body', async () => {
114
131
  const response: BulkUsersStatusResult = {
@@ -7,6 +7,8 @@ import type {
7
7
  BulkUsersStatusPayload,
8
8
  BulkUsersStatusPreview,
9
9
  BulkUsersStatusResult,
10
+ BulkUpdateUsersLinksPayload,
11
+ BulkUpdateUsersLinksResult,
10
12
  CreateUserPayload,
11
13
  EnableUserAccessResult,
12
14
  ExportUsersPayload,
@@ -41,9 +43,8 @@ export class UsersApi extends ArchivableCrudApi<
41
43
  }
42
44
 
43
45
  /**
44
- * Archives or restores a user through the dedicated route used by the UI, which also
45
- * sets the user offline and ends its sessions. The route enforces the business rules that
46
- * {@link archive}/{@link unarchive} (a plain `PUT { archivedAt }`) skip:
46
+ * Archives or restores a user through the route used by the UI, which also sets the user
47
+ * offline and ends its sessions:
47
48
  * - archiving refuses (403) a user referenced by a bot or with open tickets;
48
49
  * - restoring refuses (402) when the plan has no free user slot.
49
50
  * @permissions users.view OR users.archive
@@ -75,6 +76,23 @@ export class UsersApi extends ArchivableCrudApi<
75
76
  )
76
77
  }
77
78
 
79
+ /**
80
+ * Links up to 100 users at once to a timetable, departments or roles (see
81
+ * {@link BulkUpdateUsersLinksPayload}). The timetable is written for the whole batch at once; the
82
+ * departments and roles user by user, so the result may be partial (`failed`).
83
+ * @permissions users.update
84
+ */
85
+ bulkUpdateLinks(
86
+ body: BulkUpdateUsersLinksPayload,
87
+ headers?: Record<string, string>,
88
+ ): Promise<BulkUpdateUsersLinksResult> {
89
+ return this.client.put<BulkUpdateUsersLinksResult, BulkUpdateUsersLinksPayload>(
90
+ `${this.basePath}/v2/bulk-update`,
91
+ body,
92
+ headers,
93
+ )
94
+ }
95
+
78
96
  /**
79
97
  * Archives or unarchives up to 100 users at once.
80
98
  * @permissions users.archive
@@ -145,6 +145,34 @@ export type BulkUsersStatusResult = {
145
145
  missingIds: string[]
146
146
  }
147
147
 
148
+ /**
149
+ * Body for `PUT /users/v2/bulk-update` (1 to 100 user IDs). Send at least one of `timetableId`,
150
+ * `departmentIds` and `roleIds` (400 otherwise). A link id of another account, or unknown, refuses
151
+ * the whole batch with 400 (`<field> contains ids that do not belong to the account.`).
152
+ */
153
+ export type BulkUpdateUsersLinksPayload = {
154
+ ids: string[]
155
+ /** Sets the timetable of every user; `null` removes it. */
156
+ timetableId?: string | null
157
+ /** Adds the departments to every user (the current ones are kept). At least one id. */
158
+ departmentIds?: string[]
159
+ /** Adds the roles to every user (the current ones are kept). At least one id. */
160
+ roleIds?: string[]
161
+ }
162
+
163
+ export type BulkUpdateUsersLinksResult = {
164
+ /**
165
+ * Users of the batch written by at least one of the steps (with `timetableId`, `null` included,
166
+ * every user found; with `departmentIds`/`roleIds`, also those that already had them).
167
+ */
168
+ changed: number
169
+ /** Failures of the per-user writes (departments and roles), one per user and field. */
170
+ failed: number
171
+ changedIds: string[]
172
+ /** IDs of the batch that are not users of the account (they are skipped). */
173
+ missingIds: string[]
174
+ }
175
+
148
176
  /** Body for `POST /users/export`. */
149
177
  export type ExportUsersPayload = {
150
178
  filter: 'all' | 'active' | 'archived'
@@ -1,14 +1,46 @@
1
1
  import type { Service } from '../services/types'
2
2
 
3
+ /**
4
+ * `by_service` and `whatsapp_low_level` only get the events of the connections in `services`.
5
+ * Events not tied to a connection (users, departments, tags...) reach `by_service` too. A webhook
6
+ * with `services`, whatever its type, only gets the events of those connections (events not tied
7
+ * to a connection reach it too); a `general` webhook is meant to have none.
8
+ */
9
+ export type WebhookType = 'general' | 'by_service' | 'whatsapp_low_level'
10
+
11
+ /**
12
+ * The categories of message the `message.created` event delivers. Only `false` leaves a category
13
+ * out (an absent key keeps it); `null`, or no filter, delivers every message. The other events are
14
+ * not filtered. A key outside these answers 400.
15
+ */
16
+ export type WebhookMessageFilters = {
17
+ /** Messages of the contact (not their reactions). */
18
+ received?: boolean
19
+ /** Messages sent through the connection, except the bot's (and the reactions). */
20
+ sent?: boolean
21
+ /** Messages sent by the bot. */
22
+ bot?: boolean
23
+ /**
24
+ * Internal comments, ticket events, reactions, summaries, schedules, AI evaluations, the notices
25
+ * of the message block rule and the message types the platform does not know.
26
+ */
27
+ system?: boolean
28
+ }
29
+
3
30
  export type Webhook = {
4
31
  id: string
5
32
  name: string
6
33
  url: string
7
- type: string
34
+ /** A webhook created before the type was validated may hold another value. */
35
+ type: WebhookType
8
36
  active: boolean
9
37
  events: string[]
38
+ /** `null` when `events` has no `message.created` (the backend clears it on every write). */
39
+ messageFilters?: WebhookMessageFilters | null
10
40
  errorAt: string | null
11
41
  errorNotifiedAt: string | null
42
+ /** The average delivery latency, in ms (shown in the list of webhooks); `null` until measured. */
43
+ avgLatencyMs?: number | null
12
44
  userId: string
13
45
  accountId: string
14
46
  createdAt: string
@@ -23,15 +55,30 @@ export type WebhookRelationships = 'services'
23
55
  export type CreateWebhookPayload = {
24
56
  name: string
25
57
  url: string
26
- type: string
58
+ type: WebhookType
27
59
  events: string[]
28
60
  active?: boolean
61
+ /** The connections of a `by_service` or `whatsapp_low_level` webhook (none for `general`). */
62
+ services?: string[]
63
+ /** Only kept with the `message.created` event. */
64
+ messageFilters?: WebhookMessageFilters | null
29
65
  }
30
66
 
67
+ /**
68
+ * `updateById` sends a `PUT`: `name`, `url`, `type` and `events` are required (400 without them),
69
+ * as in the create.
70
+ */
31
71
  export type UpdateWebhookPayload = {
32
- name?: string
33
- url?: string
34
- type?: string
35
- events?: string[]
72
+ name: string
73
+ url: string
74
+ type: WebhookType
75
+ events: string[]
36
76
  active?: boolean
77
+ /**
78
+ * Replaces the connections of the webhook; omitted keeps them. Send `[]` when the type becomes
79
+ * `general`: the connections kept also filter a `general` webhook.
80
+ */
81
+ services?: string[]
82
+ /** Only kept with the `message.created` event. */
83
+ messageFilters?: WebhookMessageFilters | null
37
84
  }
@@ -4,8 +4,8 @@ import type { GetByIdQuery, HasGetById, HasGetMany, ListQuery, Paginated } from
4
4
 
5
5
  /**
6
6
  * Generic read-only resource: `getMany`, `getOne` and `getById` under `basePath`. Base of
7
- * `BaseCrudApi`, and of the resources the backend only serves for reading (e.g. permissions,
8
- * auth history).
7
+ * `BaseCrudApi`, and of the resources the backend serves for reading, plus their own actions (e.g.
8
+ * permissions, auth history).
9
9
  */
10
10
  export class BaseReadApi<TResponse, TQuery extends ListQuery<TResponse> = ListQuery<TResponse>>
11
11
  extends BaseApi
@@ -181,7 +181,10 @@ export class PaymentRequiredError extends ApiError {
181
181
  override name = 'PaymentRequiredError'
182
182
  }
183
183
 
184
- /** 403 — the user lacks the permission for this action. */
184
+ /**
185
+ * 403 — the user lacks the permission for this action, or the action is refused (e.g. out of
186
+ * office hours, see `OutOfOfficeHoursErrorExtra`).
187
+ */
185
188
  export class PermissionDeniedError extends ApiError {
186
189
  override name = 'PermissionDeniedError'
187
190
  }