@workbuddy/piece-workbuddy-vnext 1.0.4 → 1.0.6

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 (208) hide show
  1. package/package.json +1 -1
  2. package/src/index.d.ts.map +1 -1
  3. package/src/index.js +89 -83
  4. package/src/index.js.map +1 -1
  5. package/src/index.ts +29 -17
  6. package/src/lib/actions/agents.d.ts.map +1 -1
  7. package/src/lib/actions/agents.js +6 -4
  8. package/src/lib/actions/agents.js.map +1 -1
  9. package/src/lib/actions/agents.ts +8 -4
  10. package/src/lib/actions/attachments.d.ts.map +1 -1
  11. package/src/lib/actions/attachments.js +2 -1
  12. package/src/lib/actions/attachments.js.map +1 -1
  13. package/src/lib/actions/attachments.ts +3 -1
  14. package/src/lib/actions/{crm->-companies.d.ts → crm-companies.d.ts} +1 -1
  15. package/src/lib/actions/crm-companies.d.ts.map +1 -0
  16. package/src/lib/actions/{crm->-companies.js → crm-companies.js} +1 -1
  17. package/src/lib/actions/{crm->-invites.js.map → crm-companies.js.map} +1 -1
  18. package/src/lib/actions/{crm->-contacts.d.ts → crm-contacts.d.ts} +1 -1
  19. package/src/lib/actions/crm-contacts.d.ts.map +1 -0
  20. package/src/lib/actions/{crm->-contacts.js → crm-contacts.js} +1 -1
  21. package/src/lib/actions/crm-contacts.js.map +1 -0
  22. package/src/lib/actions/{crm->-contractors.d.ts → crm-contractors.d.ts} +1 -1
  23. package/src/lib/actions/crm-contractors.d.ts.map +1 -0
  24. package/src/lib/actions/{crm->-contractors.js → crm-contractors.js} +1 -1
  25. package/src/lib/actions/{crm->-employees.js.map → crm-contractors.js.map} +1 -1
  26. package/src/lib/actions/{crm->-customers.d.ts → crm-customers.d.ts} +1 -1
  27. package/src/lib/actions/crm-customers.d.ts.map +1 -0
  28. package/src/lib/actions/{crm->-customers.js → crm-customers.js} +1 -1
  29. package/src/lib/actions/crm-customers.js.map +1 -0
  30. package/src/lib/actions/{crm->-employees.d.ts → crm-employees.d.ts} +1 -1
  31. package/src/lib/actions/crm-employees.d.ts.map +1 -0
  32. package/src/lib/actions/{crm->-employees.js → crm-employees.js} +1 -1
  33. package/src/lib/actions/crm-employees.js.map +1 -0
  34. package/src/lib/actions/{crm->-external-users.d.ts → crm-external-users.d.ts} +1 -1
  35. package/src/lib/actions/crm-external-users.d.ts.map +1 -0
  36. package/src/lib/actions/{crm->-external-users.js → crm-external-users.js} +1 -1
  37. package/src/lib/actions/crm-external-users.js.map +1 -0
  38. package/src/lib/actions/{crm->-invites.d.ts → crm-invites.d.ts} +1 -1
  39. package/src/lib/actions/crm-invites.d.ts.map +1 -0
  40. package/src/lib/actions/{crm->-invites.js → crm-invites.js} +1 -1
  41. package/src/lib/actions/crm-invites.js.map +1 -0
  42. package/src/lib/actions/{crm->-sites.d.ts → crm-sites.d.ts} +1 -1
  43. package/src/lib/actions/crm-sites.d.ts.map +1 -0
  44. package/src/lib/actions/{crm->-sites.js → crm-sites.js} +1 -1
  45. package/src/lib/actions/crm-sites.js.map +1 -0
  46. package/src/lib/actions/{crm->-suppliers.d.ts → crm-suppliers.d.ts} +1 -1
  47. package/src/lib/actions/crm-suppliers.d.ts.map +1 -0
  48. package/src/lib/actions/{crm->-suppliers.js → crm-suppliers.js} +1 -1
  49. package/src/lib/actions/crm-suppliers.js.map +1 -0
  50. package/src/lib/actions/flags.d.ts +34 -0
  51. package/src/lib/actions/flags.d.ts.map +1 -0
  52. package/src/lib/actions/flags.js +185 -0
  53. package/src/lib/actions/flags.js.map +1 -0
  54. package/src/lib/actions/flags.ts +201 -0
  55. package/src/lib/actions/index.d.ts +18 -17
  56. package/src/lib/actions/index.d.ts.map +1 -1
  57. package/src/lib/actions/index.js +18 -17
  58. package/src/lib/actions/index.js.map +1 -1
  59. package/src/lib/actions/index.ts +18 -17
  60. package/src/lib/actions/{jobs->-activities.d.ts → jobs-activities.d.ts} +15 -5
  61. package/src/lib/actions/jobs-activities.d.ts.map +1 -0
  62. package/src/lib/actions/{jobs->-activities.js → jobs-activities.js} +110 -59
  63. package/src/lib/actions/jobs-activities.js.map +1 -0
  64. package/src/lib/actions/{jobs->-activities.ts → jobs-activities.ts} +118 -57
  65. package/src/lib/actions/{jobs->-contacts.d.ts → jobs-contacts.d.ts} +1 -1
  66. package/src/lib/actions/jobs-contacts.d.ts.map +1 -0
  67. package/src/lib/actions/{jobs->-contacts.js → jobs-contacts.js} +5 -5
  68. package/src/lib/actions/jobs-contacts.js.map +1 -0
  69. package/src/lib/actions/{jobs->-contacts.ts → jobs-contacts.ts} +4 -4
  70. package/src/lib/actions/{jobs->-files.d.ts → jobs-files.d.ts} +1 -1
  71. package/src/lib/actions/jobs-files.d.ts.map +1 -0
  72. package/src/lib/actions/{jobs->-files.js → jobs-files.js} +9 -9
  73. package/src/lib/actions/jobs-files.js.map +1 -0
  74. package/src/lib/actions/{jobs->-files.ts → jobs-files.ts} +8 -8
  75. package/src/lib/actions/{jobs->-tasks.d.ts → jobs-tasks.d.ts} +4 -2
  76. package/src/lib/actions/jobs-tasks.d.ts.map +1 -0
  77. package/src/lib/actions/{jobs->-tasks.js → jobs-tasks.js} +61 -37
  78. package/src/lib/actions/jobs-tasks.js.map +1 -0
  79. package/src/lib/actions/{jobs->-tasks.ts → jobs-tasks.ts} +64 -36
  80. package/src/lib/actions/jobs.d.ts +4 -3
  81. package/src/lib/actions/jobs.d.ts.map +1 -1
  82. package/src/lib/actions/jobs.js +90 -72
  83. package/src/lib/actions/jobs.js.map +1 -1
  84. package/src/lib/actions/jobs.ts +94 -72
  85. package/src/lib/actions/mcp.d.ts +1 -1
  86. package/src/lib/actions/mcp.d.ts.map +1 -1
  87. package/src/lib/actions/mcp.js +7 -6
  88. package/src/lib/actions/mcp.js.map +1 -1
  89. package/src/lib/actions/mcp.ts +8 -6
  90. package/src/lib/actions/settings.js +1 -1
  91. package/src/lib/actions/settings.js.map +1 -1
  92. package/src/lib/actions/settings.ts +1 -1
  93. package/src/lib/actions/{stages->-activities.d.ts → stages-activities.d.ts} +24 -5
  94. package/src/lib/actions/stages-activities.d.ts.map +1 -0
  95. package/src/lib/actions/{stages->-activities.js → stages-activities.js} +164 -68
  96. package/src/lib/actions/stages-activities.js.map +1 -0
  97. package/src/lib/actions/{stages->-activities.ts → stages-activities.ts} +172 -66
  98. package/src/lib/actions/{stages->-files.d.ts → stages-files.d.ts} +5 -1
  99. package/src/lib/actions/stages-files.d.ts.map +1 -0
  100. package/src/lib/actions/{stages->-files.js → stages-files.js} +35 -15
  101. package/src/lib/actions/stages-files.js.map +1 -0
  102. package/src/lib/actions/{stages->-files.ts → stages-files.ts} +34 -14
  103. package/src/lib/actions/{stages->-resources.d.ts → stages-resources.d.ts} +1 -1
  104. package/src/lib/actions/stages-resources.d.ts.map +1 -0
  105. package/src/lib/actions/{stages->-resources.js → stages-resources.js} +7 -5
  106. package/src/lib/actions/stages-resources.js.map +1 -0
  107. package/src/lib/actions/{stages->-resources.ts → stages-resources.ts} +8 -4
  108. package/src/lib/actions/{stages->-tasks.d.ts → stages-tasks.d.ts} +8 -2
  109. package/src/lib/actions/stages-tasks.d.ts.map +1 -0
  110. package/src/lib/actions/{stages->-tasks.js → stages-tasks.js} +91 -47
  111. package/src/lib/actions/stages-tasks.js.map +1 -0
  112. package/src/lib/actions/{stages->-tasks.ts → stages-tasks.ts} +94 -46
  113. package/src/lib/actions/stages.d.ts +6 -2
  114. package/src/lib/actions/stages.d.ts.map +1 -1
  115. package/src/lib/actions/stages.js +77 -27
  116. package/src/lib/actions/stages.js.map +1 -1
  117. package/src/lib/actions/stages.ts +88 -27
  118. package/src/lib/actions/webhooks-v2.js +15 -15
  119. package/src/lib/actions/webhooks-v2.js.map +1 -1
  120. package/src/lib/actions/webhooks-v2.ts +15 -15
  121. package/src/lib/auth.js +2 -2
  122. package/src/lib/auth.js.map +1 -1
  123. package/src/lib/auth.ts +2 -2
  124. package/src/lib/triggers/activity.d.ts.map +1 -1
  125. package/src/lib/triggers/activity.js +54 -42
  126. package/src/lib/triggers/activity.js.map +1 -1
  127. package/src/lib/triggers/activity.ts +54 -42
  128. package/src/lib/triggers/bill.d.ts +240 -48
  129. package/src/lib/triggers/bill.d.ts.map +1 -1
  130. package/src/lib/triggers/bill.js +368 -88
  131. package/src/lib/triggers/bill.js.map +1 -1
  132. package/src/lib/triggers/bill.ts +368 -88
  133. package/src/lib/triggers/invoice.d.ts +240 -48
  134. package/src/lib/triggers/invoice.d.ts.map +1 -1
  135. package/src/lib/triggers/invoice.js +368 -88
  136. package/src/lib/triggers/invoice.js.map +1 -1
  137. package/src/lib/triggers/invoice.ts +368 -88
  138. package/src/lib/triggers/job.d.ts +640 -128
  139. package/src/lib/triggers/job.d.ts.map +1 -1
  140. package/src/lib/triggers/job.js +928 -208
  141. package/src/lib/triggers/job.js.map +1 -1
  142. package/src/lib/triggers/job.ts +928 -208
  143. package/src/lib/triggers/lead.d.ts +400 -80
  144. package/src/lib/triggers/lead.d.ts.map +1 -1
  145. package/src/lib/triggers/lead.js +552 -96
  146. package/src/lib/triggers/lead.js.map +1 -1
  147. package/src/lib/triggers/lead.ts +552 -96
  148. package/src/lib/triggers/opportunity.d.ts +320 -64
  149. package/src/lib/triggers/opportunity.d.ts.map +1 -1
  150. package/src/lib/triggers/opportunity.js +456 -88
  151. package/src/lib/triggers/opportunity.js.map +1 -1
  152. package/src/lib/triggers/opportunity.ts +456 -88
  153. package/src/lib/triggers/quote.d.ts +240 -48
  154. package/src/lib/triggers/quote.d.ts.map +1 -1
  155. package/src/lib/triggers/quote.js +368 -88
  156. package/src/lib/triggers/quote.js.map +1 -1
  157. package/src/lib/triggers/quote.ts +368 -88
  158. package/src/lib/triggers/stage.d.ts +480 -96
  159. package/src/lib/triggers/stage.d.ts.map +1 -1
  160. package/src/lib/triggers/stage.js +764 -220
  161. package/src/lib/triggers/stage.js.map +1 -1
  162. package/src/lib/triggers/stage.ts +764 -220
  163. package/src/lib/triggers/task.d.ts +80 -16
  164. package/src/lib/triggers/task.d.ts.map +1 -1
  165. package/src/lib/triggers/task.js +172 -68
  166. package/src/lib/triggers/task.js.map +1 -1
  167. package/src/lib/triggers/task.ts +172 -68
  168. package/src/lib/actions/crm->-companies.d.ts.map +0 -1
  169. package/src/lib/actions/crm->-companies.js.map +0 -1
  170. package/src/lib/actions/crm->-contacts.d.ts.map +0 -1
  171. package/src/lib/actions/crm->-contacts.js.map +0 -1
  172. package/src/lib/actions/crm->-contractors.d.ts.map +0 -1
  173. package/src/lib/actions/crm->-contractors.js.map +0 -1
  174. package/src/lib/actions/crm->-customers.d.ts.map +0 -1
  175. package/src/lib/actions/crm->-customers.js.map +0 -1
  176. package/src/lib/actions/crm->-employees.d.ts.map +0 -1
  177. package/src/lib/actions/crm->-external-users.d.ts.map +0 -1
  178. package/src/lib/actions/crm->-external-users.js.map +0 -1
  179. package/src/lib/actions/crm->-invites.d.ts.map +0 -1
  180. package/src/lib/actions/crm->-sites.d.ts.map +0 -1
  181. package/src/lib/actions/crm->-sites.js.map +0 -1
  182. package/src/lib/actions/crm->-suppliers.d.ts.map +0 -1
  183. package/src/lib/actions/crm->-suppliers.js.map +0 -1
  184. package/src/lib/actions/jobs->-activities.d.ts.map +0 -1
  185. package/src/lib/actions/jobs->-activities.js.map +0 -1
  186. package/src/lib/actions/jobs->-contacts.d.ts.map +0 -1
  187. package/src/lib/actions/jobs->-contacts.js.map +0 -1
  188. package/src/lib/actions/jobs->-files.d.ts.map +0 -1
  189. package/src/lib/actions/jobs->-files.js.map +0 -1
  190. package/src/lib/actions/jobs->-tasks.d.ts.map +0 -1
  191. package/src/lib/actions/jobs->-tasks.js.map +0 -1
  192. package/src/lib/actions/stages->-activities.d.ts.map +0 -1
  193. package/src/lib/actions/stages->-activities.js.map +0 -1
  194. package/src/lib/actions/stages->-files.d.ts.map +0 -1
  195. package/src/lib/actions/stages->-files.js.map +0 -1
  196. package/src/lib/actions/stages->-resources.d.ts.map +0 -1
  197. package/src/lib/actions/stages->-resources.js.map +0 -1
  198. package/src/lib/actions/stages->-tasks.d.ts.map +0 -1
  199. package/src/lib/actions/stages->-tasks.js.map +0 -1
  200. /package/src/lib/actions/{crm->-companies.ts → crm-companies.ts} +0 -0
  201. /package/src/lib/actions/{crm->-contacts.ts → crm-contacts.ts} +0 -0
  202. /package/src/lib/actions/{crm->-contractors.ts → crm-contractors.ts} +0 -0
  203. /package/src/lib/actions/{crm->-customers.ts → crm-customers.ts} +0 -0
  204. /package/src/lib/actions/{crm->-employees.ts → crm-employees.ts} +0 -0
  205. /package/src/lib/actions/{crm->-external-users.ts → crm-external-users.ts} +0 -0
  206. /package/src/lib/actions/{crm->-invites.ts → crm-invites.ts} +0 -0
  207. /package/src/lib/actions/{crm->-sites.ts → crm-sites.ts} +0 -0
  208. /package/src/lib/actions/{crm->-suppliers.ts → crm-suppliers.ts} +0 -0
@@ -8,20 +8,86 @@ export const quote_created_trigger = createTrigger({
8
8
  displayName: 'Quote Created',
9
9
  description: 'Triggered when a new quote is created',
10
10
  props: {
11
- customer: Property.Array({
11
+ customer: Property.MultiSelectDropdown({
12
12
  displayName: 'Filter by Customer',
13
- description: 'Only trigger for specific customer IDs',
13
+ description: 'Only trigger for specific customer',
14
14
  required: false,
15
+ auth: workbuddyAuth,
16
+ refreshers: [],
17
+ options: async ({ auth }) => {
18
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
19
+ const token = await getAccessToken(authValue);
20
+ const baseUrl = authValue.props.baseUrl;
21
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
22
+ method: HttpMethod.GET,
23
+ url: `${baseUrl}/api/v2/public/customers`,
24
+ headers: {
25
+ Authorization: `Bearer ${token}`,
26
+ 'X-WorkBuddy-Version': '2026-01',
27
+ },
28
+ });
29
+ const items = response.body?.items || [];
30
+ return {
31
+ options: items.map((item) => ({
32
+ label: item.name,
33
+ value: item.id,
34
+ })),
35
+ };
36
+ },
15
37
  }),
16
- billingCompany: Property.Array({
38
+ billingCompany: Property.MultiSelectDropdown({
17
39
  displayName: 'Filter by Billing Company',
18
- description: 'Only trigger for specific billing company IDs',
40
+ description: 'Only trigger for specific billing company',
19
41
  required: false,
42
+ auth: workbuddyAuth,
43
+ refreshers: [],
44
+ options: async ({ auth }) => {
45
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
46
+ const token = await getAccessToken(authValue);
47
+ const baseUrl = authValue.props.baseUrl;
48
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
49
+ method: HttpMethod.GET,
50
+ url: `${baseUrl}/api/v2/public/companies`,
51
+ headers: {
52
+ Authorization: `Bearer ${token}`,
53
+ 'X-WorkBuddy-Version': '2026-01',
54
+ },
55
+ });
56
+ const items = response.body?.items || [];
57
+ return {
58
+ options: items.map((item) => ({
59
+ label: item.name,
60
+ value: item.id,
61
+ })),
62
+ };
63
+ },
20
64
  }),
21
- tag: Property.Array({
65
+ tag: Property.MultiSelectDropdown({
22
66
  displayName: 'Filter by Tags',
23
- description: 'Only trigger for specific tags IDs',
67
+ description: 'Only trigger for specific tags',
24
68
  required: false,
69
+ auth: workbuddyAuth,
70
+ refreshers: [],
71
+ options: async ({ auth }) => {
72
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
73
+ const token = await getAccessToken(authValue);
74
+ const baseUrl = authValue.props.baseUrl;
75
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
76
+ method: HttpMethod.GET,
77
+ url: `${baseUrl}/api/v2/public/settings/tags`,
78
+ headers: {
79
+ Authorization: `Bearer ${token}`,
80
+ 'X-WorkBuddy-Version': '2026-01',
81
+ },
82
+ });
83
+ const items = response.body?.items || [];
84
+ return {
85
+ options: items.map((item) => ({
86
+ label: item.name,
87
+ value: item.id,
88
+ })),
89
+ };
90
+ },
25
91
  }),
26
92
  status: Property.StaticMultiSelectDropdown({
27
93
  displayName: 'Filter by Status',
@@ -39,16 +105,23 @@ export const quote_created_trigger = createTrigger({
39
105
  }),
40
106
  },
41
107
  sampleData: {
42
- quote: {
43
- id: '507f1f77bcf86cd799439011',
44
- quoteNumber: 'Q-1001',
45
- status: 'Draft',
46
- total: 2500.0,
47
- tax: 250.0,
48
- createdAt: '2026-03-05T10:00:00.000Z',
49
- validUntil: '2026-04-05T10:00:00.000Z',
50
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
51
- job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
108
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
109
+ event: 'Quote Created',
110
+ action: 'create',
111
+ createdAt: '2026-03-14T05:21:47.307Z',
112
+ webhookTimestamp: 1773465707307,
113
+ data: {
114
+ quote: {
115
+ id: '507f1f77bcf86cd799439011',
116
+ quoteNumber: 'Q-1001',
117
+ status: 'Draft',
118
+ total: 2500.0,
119
+ tax: 250.0,
120
+ createdAt: '2026-03-05T10:00:00.000Z',
121
+ validUntil: '2026-04-05T10:00:00.000Z',
122
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
123
+ job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
124
+ },
52
125
  },
53
126
  },
54
127
  type: TriggerStrategy.WEBHOOK,
@@ -63,7 +136,7 @@ export const quote_created_trigger = createTrigger({
63
136
  if (context.propsValue.billingCompany?.length) filters.billingCompany = context.propsValue.billingCompany;
64
137
  if (context.propsValue.tag?.length) filters.tag = context.propsValue.tag;
65
138
  if (context.propsValue.status?.length) filters.status = context.propsValue.status.map((v: string) => JSON.parse(v));
66
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
139
+ // Register webhook with WorkBuddy v2 API
67
140
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
68
141
  method: HttpMethod.POST,
69
142
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -95,18 +168,15 @@ export const quote_created_trigger = createTrigger({
95
168
  const webhookId = await context.store.get<string>('webhookId');
96
169
 
97
170
  if (webhookId) {
98
- // Pause webhook (server keeps it for potential reactivation)
171
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
99
172
  await httpClient.sendRequest({
100
- method: HttpMethod.PATCH,
173
+ method: HttpMethod.DELETE,
101
174
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
102
175
  headers: {
103
176
  Authorization: `Bearer ${token}`,
104
177
  'Content-Type': 'application/json',
105
178
  'X-WorkBuddy-Version': '2026-01',
106
179
  },
107
- body: {
108
- status: 'paused',
109
- },
110
180
  });
111
181
  }
112
182
  },
@@ -122,20 +192,86 @@ export const quote_updated_trigger = createTrigger({
122
192
  displayName: 'Quote Updated',
123
193
  description: 'Triggered when a quote is updated',
124
194
  props: {
125
- customer: Property.Array({
195
+ customer: Property.MultiSelectDropdown({
126
196
  displayName: 'Filter by Customer',
127
- description: 'Only trigger for specific customer IDs',
197
+ description: 'Only trigger for specific customer',
128
198
  required: false,
199
+ auth: workbuddyAuth,
200
+ refreshers: [],
201
+ options: async ({ auth }) => {
202
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
203
+ const token = await getAccessToken(authValue);
204
+ const baseUrl = authValue.props.baseUrl;
205
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
206
+ method: HttpMethod.GET,
207
+ url: `${baseUrl}/api/v2/public/customers`,
208
+ headers: {
209
+ Authorization: `Bearer ${token}`,
210
+ 'X-WorkBuddy-Version': '2026-01',
211
+ },
212
+ });
213
+ const items = response.body?.items || [];
214
+ return {
215
+ options: items.map((item) => ({
216
+ label: item.name,
217
+ value: item.id,
218
+ })),
219
+ };
220
+ },
129
221
  }),
130
- billingCompany: Property.Array({
222
+ billingCompany: Property.MultiSelectDropdown({
131
223
  displayName: 'Filter by Billing Company',
132
- description: 'Only trigger for specific billing company IDs',
224
+ description: 'Only trigger for specific billing company',
133
225
  required: false,
226
+ auth: workbuddyAuth,
227
+ refreshers: [],
228
+ options: async ({ auth }) => {
229
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
230
+ const token = await getAccessToken(authValue);
231
+ const baseUrl = authValue.props.baseUrl;
232
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
233
+ method: HttpMethod.GET,
234
+ url: `${baseUrl}/api/v2/public/companies`,
235
+ headers: {
236
+ Authorization: `Bearer ${token}`,
237
+ 'X-WorkBuddy-Version': '2026-01',
238
+ },
239
+ });
240
+ const items = response.body?.items || [];
241
+ return {
242
+ options: items.map((item) => ({
243
+ label: item.name,
244
+ value: item.id,
245
+ })),
246
+ };
247
+ },
134
248
  }),
135
- tag: Property.Array({
249
+ tag: Property.MultiSelectDropdown({
136
250
  displayName: 'Filter by Tags',
137
- description: 'Only trigger for specific tags IDs',
251
+ description: 'Only trigger for specific tags',
138
252
  required: false,
253
+ auth: workbuddyAuth,
254
+ refreshers: [],
255
+ options: async ({ auth }) => {
256
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
257
+ const token = await getAccessToken(authValue);
258
+ const baseUrl = authValue.props.baseUrl;
259
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
260
+ method: HttpMethod.GET,
261
+ url: `${baseUrl}/api/v2/public/settings/tags`,
262
+ headers: {
263
+ Authorization: `Bearer ${token}`,
264
+ 'X-WorkBuddy-Version': '2026-01',
265
+ },
266
+ });
267
+ const items = response.body?.items || [];
268
+ return {
269
+ options: items.map((item) => ({
270
+ label: item.name,
271
+ value: item.id,
272
+ })),
273
+ };
274
+ },
139
275
  }),
140
276
  status: Property.StaticMultiSelectDropdown({
141
277
  displayName: 'Filter by Status',
@@ -153,16 +289,23 @@ export const quote_updated_trigger = createTrigger({
153
289
  }),
154
290
  },
155
291
  sampleData: {
156
- quote: {
157
- id: '507f1f77bcf86cd799439011',
158
- quoteNumber: 'Q-1001',
159
- status: 'Draft',
160
- total: 2500.0,
161
- tax: 250.0,
162
- createdAt: '2026-03-05T10:00:00.000Z',
163
- validUntil: '2026-04-05T10:00:00.000Z',
164
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
165
- job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
292
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
293
+ event: 'Quote Updated',
294
+ action: 'update',
295
+ createdAt: '2026-03-14T05:21:47.307Z',
296
+ webhookTimestamp: 1773465707307,
297
+ data: {
298
+ quote: {
299
+ id: '507f1f77bcf86cd799439011',
300
+ quoteNumber: 'Q-1001',
301
+ status: 'Draft',
302
+ total: 2500.0,
303
+ tax: 250.0,
304
+ createdAt: '2026-03-05T10:00:00.000Z',
305
+ validUntil: '2026-04-05T10:00:00.000Z',
306
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
307
+ job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
308
+ },
166
309
  },
167
310
  },
168
311
  type: TriggerStrategy.WEBHOOK,
@@ -177,7 +320,7 @@ export const quote_updated_trigger = createTrigger({
177
320
  if (context.propsValue.billingCompany?.length) filters.billingCompany = context.propsValue.billingCompany;
178
321
  if (context.propsValue.tag?.length) filters.tag = context.propsValue.tag;
179
322
  if (context.propsValue.status?.length) filters.status = context.propsValue.status.map((v: string) => JSON.parse(v));
180
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
323
+ // Register webhook with WorkBuddy v2 API
181
324
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
182
325
  method: HttpMethod.POST,
183
326
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -209,18 +352,15 @@ export const quote_updated_trigger = createTrigger({
209
352
  const webhookId = await context.store.get<string>('webhookId');
210
353
 
211
354
  if (webhookId) {
212
- // Pause webhook (server keeps it for potential reactivation)
355
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
213
356
  await httpClient.sendRequest({
214
- method: HttpMethod.PATCH,
357
+ method: HttpMethod.DELETE,
215
358
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
216
359
  headers: {
217
360
  Authorization: `Bearer ${token}`,
218
361
  'Content-Type': 'application/json',
219
362
  'X-WorkBuddy-Version': '2026-01',
220
363
  },
221
- body: {
222
- status: 'paused',
223
- },
224
364
  });
225
365
  }
226
366
  },
@@ -236,20 +376,86 @@ export const quote_status_changed_trigger = createTrigger({
236
376
  displayName: 'Quote Status Changed',
237
377
  description: 'Triggered when a quote status changes',
238
378
  props: {
239
- customer: Property.Array({
379
+ customer: Property.MultiSelectDropdown({
240
380
  displayName: 'Filter by Customer',
241
- description: 'Only trigger for specific customer IDs',
381
+ description: 'Only trigger for specific customer',
242
382
  required: false,
383
+ auth: workbuddyAuth,
384
+ refreshers: [],
385
+ options: async ({ auth }) => {
386
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
387
+ const token = await getAccessToken(authValue);
388
+ const baseUrl = authValue.props.baseUrl;
389
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
390
+ method: HttpMethod.GET,
391
+ url: `${baseUrl}/api/v2/public/customers`,
392
+ headers: {
393
+ Authorization: `Bearer ${token}`,
394
+ 'X-WorkBuddy-Version': '2026-01',
395
+ },
396
+ });
397
+ const items = response.body?.items || [];
398
+ return {
399
+ options: items.map((item) => ({
400
+ label: item.name,
401
+ value: item.id,
402
+ })),
403
+ };
404
+ },
243
405
  }),
244
- billingCompany: Property.Array({
406
+ billingCompany: Property.MultiSelectDropdown({
245
407
  displayName: 'Filter by Billing Company',
246
- description: 'Only trigger for specific billing company IDs',
408
+ description: 'Only trigger for specific billing company',
247
409
  required: false,
410
+ auth: workbuddyAuth,
411
+ refreshers: [],
412
+ options: async ({ auth }) => {
413
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
414
+ const token = await getAccessToken(authValue);
415
+ const baseUrl = authValue.props.baseUrl;
416
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
417
+ method: HttpMethod.GET,
418
+ url: `${baseUrl}/api/v2/public/companies`,
419
+ headers: {
420
+ Authorization: `Bearer ${token}`,
421
+ 'X-WorkBuddy-Version': '2026-01',
422
+ },
423
+ });
424
+ const items = response.body?.items || [];
425
+ return {
426
+ options: items.map((item) => ({
427
+ label: item.name,
428
+ value: item.id,
429
+ })),
430
+ };
431
+ },
248
432
  }),
249
- tag: Property.Array({
433
+ tag: Property.MultiSelectDropdown({
250
434
  displayName: 'Filter by Tags',
251
- description: 'Only trigger for specific tags IDs',
435
+ description: 'Only trigger for specific tags',
252
436
  required: false,
437
+ auth: workbuddyAuth,
438
+ refreshers: [],
439
+ options: async ({ auth }) => {
440
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
441
+ const token = await getAccessToken(authValue);
442
+ const baseUrl = authValue.props.baseUrl;
443
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
444
+ method: HttpMethod.GET,
445
+ url: `${baseUrl}/api/v2/public/settings/tags`,
446
+ headers: {
447
+ Authorization: `Bearer ${token}`,
448
+ 'X-WorkBuddy-Version': '2026-01',
449
+ },
450
+ });
451
+ const items = response.body?.items || [];
452
+ return {
453
+ options: items.map((item) => ({
454
+ label: item.name,
455
+ value: item.id,
456
+ })),
457
+ };
458
+ },
253
459
  }),
254
460
  status: Property.StaticMultiSelectDropdown({
255
461
  displayName: 'Filter by Status',
@@ -267,16 +473,23 @@ export const quote_status_changed_trigger = createTrigger({
267
473
  }),
268
474
  },
269
475
  sampleData: {
270
- quote: {
271
- id: '507f1f77bcf86cd799439011',
272
- quoteNumber: 'Q-1001',
273
- status: 'Draft',
274
- total: 2500.0,
275
- tax: 250.0,
276
- createdAt: '2026-03-05T10:00:00.000Z',
277
- validUntil: '2026-04-05T10:00:00.000Z',
278
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
279
- job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
476
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
477
+ event: 'Quote Status Changed',
478
+ action: 'update',
479
+ createdAt: '2026-03-14T05:21:47.307Z',
480
+ webhookTimestamp: 1773465707307,
481
+ data: {
482
+ quote: {
483
+ id: '507f1f77bcf86cd799439011',
484
+ quoteNumber: 'Q-1001',
485
+ status: 'Draft',
486
+ total: 2500.0,
487
+ tax: 250.0,
488
+ createdAt: '2026-03-05T10:00:00.000Z',
489
+ validUntil: '2026-04-05T10:00:00.000Z',
490
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
491
+ job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
492
+ },
280
493
  },
281
494
  },
282
495
  type: TriggerStrategy.WEBHOOK,
@@ -291,7 +504,7 @@ export const quote_status_changed_trigger = createTrigger({
291
504
  if (context.propsValue.billingCompany?.length) filters.billingCompany = context.propsValue.billingCompany;
292
505
  if (context.propsValue.tag?.length) filters.tag = context.propsValue.tag;
293
506
  if (context.propsValue.status?.length) filters.status = context.propsValue.status.map((v: string) => JSON.parse(v));
294
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
507
+ // Register webhook with WorkBuddy v2 API
295
508
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
296
509
  method: HttpMethod.POST,
297
510
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -323,18 +536,15 @@ export const quote_status_changed_trigger = createTrigger({
323
536
  const webhookId = await context.store.get<string>('webhookId');
324
537
 
325
538
  if (webhookId) {
326
- // Pause webhook (server keeps it for potential reactivation)
539
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
327
540
  await httpClient.sendRequest({
328
- method: HttpMethod.PATCH,
541
+ method: HttpMethod.DELETE,
329
542
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
330
543
  headers: {
331
544
  Authorization: `Bearer ${token}`,
332
545
  'Content-Type': 'application/json',
333
546
  'X-WorkBuddy-Version': '2026-01',
334
547
  },
335
- body: {
336
- status: 'paused',
337
- },
338
548
  });
339
549
  }
340
550
  },
@@ -350,20 +560,86 @@ export const quote_deleted_trigger = createTrigger({
350
560
  displayName: 'Quote Deleted',
351
561
  description: 'Triggered when a quote is deleted',
352
562
  props: {
353
- customer: Property.Array({
563
+ customer: Property.MultiSelectDropdown({
354
564
  displayName: 'Filter by Customer',
355
- description: 'Only trigger for specific customer IDs',
565
+ description: 'Only trigger for specific customer',
356
566
  required: false,
567
+ auth: workbuddyAuth,
568
+ refreshers: [],
569
+ options: async ({ auth }) => {
570
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
571
+ const token = await getAccessToken(authValue);
572
+ const baseUrl = authValue.props.baseUrl;
573
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
574
+ method: HttpMethod.GET,
575
+ url: `${baseUrl}/api/v2/public/customers`,
576
+ headers: {
577
+ Authorization: `Bearer ${token}`,
578
+ 'X-WorkBuddy-Version': '2026-01',
579
+ },
580
+ });
581
+ const items = response.body?.items || [];
582
+ return {
583
+ options: items.map((item) => ({
584
+ label: item.name,
585
+ value: item.id,
586
+ })),
587
+ };
588
+ },
357
589
  }),
358
- billingCompany: Property.Array({
590
+ billingCompany: Property.MultiSelectDropdown({
359
591
  displayName: 'Filter by Billing Company',
360
- description: 'Only trigger for specific billing company IDs',
592
+ description: 'Only trigger for specific billing company',
361
593
  required: false,
594
+ auth: workbuddyAuth,
595
+ refreshers: [],
596
+ options: async ({ auth }) => {
597
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
598
+ const token = await getAccessToken(authValue);
599
+ const baseUrl = authValue.props.baseUrl;
600
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
601
+ method: HttpMethod.GET,
602
+ url: `${baseUrl}/api/v2/public/companies`,
603
+ headers: {
604
+ Authorization: `Bearer ${token}`,
605
+ 'X-WorkBuddy-Version': '2026-01',
606
+ },
607
+ });
608
+ const items = response.body?.items || [];
609
+ return {
610
+ options: items.map((item) => ({
611
+ label: item.name,
612
+ value: item.id,
613
+ })),
614
+ };
615
+ },
362
616
  }),
363
- tag: Property.Array({
617
+ tag: Property.MultiSelectDropdown({
364
618
  displayName: 'Filter by Tags',
365
- description: 'Only trigger for specific tags IDs',
619
+ description: 'Only trigger for specific tags',
366
620
  required: false,
621
+ auth: workbuddyAuth,
622
+ refreshers: [],
623
+ options: async ({ auth }) => {
624
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
625
+ const token = await getAccessToken(authValue);
626
+ const baseUrl = authValue.props.baseUrl;
627
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
628
+ method: HttpMethod.GET,
629
+ url: `${baseUrl}/api/v2/public/settings/tags`,
630
+ headers: {
631
+ Authorization: `Bearer ${token}`,
632
+ 'X-WorkBuddy-Version': '2026-01',
633
+ },
634
+ });
635
+ const items = response.body?.items || [];
636
+ return {
637
+ options: items.map((item) => ({
638
+ label: item.name,
639
+ value: item.id,
640
+ })),
641
+ };
642
+ },
367
643
  }),
368
644
  status: Property.StaticMultiSelectDropdown({
369
645
  displayName: 'Filter by Status',
@@ -381,16 +657,23 @@ export const quote_deleted_trigger = createTrigger({
381
657
  }),
382
658
  },
383
659
  sampleData: {
384
- quote: {
385
- id: '507f1f77bcf86cd799439011',
386
- quoteNumber: 'Q-1001',
387
- status: 'Draft',
388
- total: 2500.0,
389
- tax: 250.0,
390
- createdAt: '2026-03-05T10:00:00.000Z',
391
- validUntil: '2026-04-05T10:00:00.000Z',
392
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
393
- job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
660
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
661
+ event: 'Quote Deleted',
662
+ action: 'remove',
663
+ createdAt: '2026-03-14T05:21:47.307Z',
664
+ webhookTimestamp: 1773465707307,
665
+ data: {
666
+ quote: {
667
+ id: '507f1f77bcf86cd799439011',
668
+ quoteNumber: 'Q-1001',
669
+ status: 'Draft',
670
+ total: 2500.0,
671
+ tax: 250.0,
672
+ createdAt: '2026-03-05T10:00:00.000Z',
673
+ validUntil: '2026-04-05T10:00:00.000Z',
674
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
675
+ job: { id: '507f1f77bcf86cd799439011', name: 'J10001' },
676
+ },
394
677
  },
395
678
  },
396
679
  type: TriggerStrategy.WEBHOOK,
@@ -405,7 +688,7 @@ export const quote_deleted_trigger = createTrigger({
405
688
  if (context.propsValue.billingCompany?.length) filters.billingCompany = context.propsValue.billingCompany;
406
689
  if (context.propsValue.tag?.length) filters.tag = context.propsValue.tag;
407
690
  if (context.propsValue.status?.length) filters.status = context.propsValue.status.map((v: string) => JSON.parse(v));
408
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
691
+ // Register webhook with WorkBuddy v2 API
409
692
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
410
693
  method: HttpMethod.POST,
411
694
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -437,18 +720,15 @@ export const quote_deleted_trigger = createTrigger({
437
720
  const webhookId = await context.store.get<string>('webhookId');
438
721
 
439
722
  if (webhookId) {
440
- // Pause webhook (server keeps it for potential reactivation)
723
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
441
724
  await httpClient.sendRequest({
442
- method: HttpMethod.PATCH,
725
+ method: HttpMethod.DELETE,
443
726
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
444
727
  headers: {
445
728
  Authorization: `Bearer ${token}`,
446
729
  'Content-Type': 'application/json',
447
730
  'X-WorkBuddy-Version': '2026-01',
448
731
  },
449
- body: {
450
- status: 'paused',
451
- },
452
732
  });
453
733
  }
454
734
  },