@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 lead_created_trigger = createTrigger({
8
8
  displayName: 'Lead Created',
9
9
  description: 'Triggered when a new lead 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
  leadStage: Property.Array({
27
93
  displayName: 'Filter by Stage',
@@ -33,26 +99,77 @@ export const lead_created_trigger = createTrigger({
33
99
  description: 'Only trigger for specific source IDs',
34
100
  required: false,
35
101
  }),
36
- owner: Property.Array({
102
+ owner: Property.MultiSelectDropdown({
37
103
  displayName: 'Filter by Owner',
38
- description: 'Only trigger for specific owner IDs',
104
+ description: 'Only trigger for specific owner',
39
105
  required: false,
106
+ auth: workbuddyAuth,
107
+ refreshers: [],
108
+ options: async ({ auth }) => {
109
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
110
+ const token = await getAccessToken(authValue);
111
+ const baseUrl = authValue.props.baseUrl;
112
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
113
+ method: HttpMethod.GET,
114
+ url: `${baseUrl}/api/v2/public/employees`,
115
+ headers: {
116
+ Authorization: `Bearer ${token}`,
117
+ 'X-WorkBuddy-Version': '2026-01',
118
+ },
119
+ });
120
+ const items = response.body?.items || [];
121
+ return {
122
+ options: items.map((item) => ({
123
+ label: item.name,
124
+ value: item.id,
125
+ })),
126
+ };
127
+ },
40
128
  }),
41
- type: Property.Array({
129
+ type: Property.MultiSelectDropdown({
42
130
  displayName: 'Filter by Job Type',
43
- description: 'Only trigger for specific job type IDs',
131
+ description: 'Only trigger for specific job type',
44
132
  required: false,
133
+ auth: workbuddyAuth,
134
+ refreshers: [],
135
+ options: async ({ auth }) => {
136
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
137
+ const token = await getAccessToken(authValue);
138
+ const baseUrl = authValue.props.baseUrl;
139
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
140
+ method: HttpMethod.GET,
141
+ url: `${baseUrl}/api/v2/public/settings/job-types`,
142
+ headers: {
143
+ Authorization: `Bearer ${token}`,
144
+ 'X-WorkBuddy-Version': '2026-01',
145
+ },
146
+ });
147
+ const items = response.body?.items || [];
148
+ return {
149
+ options: items.map((item) => ({
150
+ label: item.name,
151
+ value: item.id,
152
+ })),
153
+ };
154
+ },
45
155
  }),
46
156
  },
47
157
  sampleData: {
48
- lead: {
49
- id: '507f1f77bcf86cd799439011',
50
- name: 'New Lead',
51
- status: 'New',
52
- source: 'website',
53
- createdAt: '2026-03-05T10:00:00.000Z',
54
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
55
- owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
158
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
159
+ event: 'Lead Created',
160
+ action: 'create',
161
+ createdAt: '2026-03-14T05:21:47.307Z',
162
+ webhookTimestamp: 1773465707307,
163
+ data: {
164
+ lead: {
165
+ id: '507f1f77bcf86cd799439011',
166
+ name: 'New Lead',
167
+ status: 'New',
168
+ source: 'website',
169
+ createdAt: '2026-03-05T10:00:00.000Z',
170
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
171
+ owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
172
+ },
56
173
  },
57
174
  },
58
175
  type: TriggerStrategy.WEBHOOK,
@@ -70,7 +187,7 @@ export const lead_created_trigger = createTrigger({
70
187
  if (context.propsValue.leadSource?.length) filters.leadSource = context.propsValue.leadSource;
71
188
  if (context.propsValue.owner?.length) filters.owner = context.propsValue.owner;
72
189
  if (context.propsValue.type?.length) filters.type = context.propsValue.type;
73
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
190
+ // Register webhook with WorkBuddy v2 API
74
191
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
75
192
  method: HttpMethod.POST,
76
193
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -102,18 +219,15 @@ export const lead_created_trigger = createTrigger({
102
219
  const webhookId = await context.store.get<string>('webhookId');
103
220
 
104
221
  if (webhookId) {
105
- // Pause webhook (server keeps it for potential reactivation)
222
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
106
223
  await httpClient.sendRequest({
107
- method: HttpMethod.PATCH,
224
+ method: HttpMethod.DELETE,
108
225
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
109
226
  headers: {
110
227
  Authorization: `Bearer ${token}`,
111
228
  'Content-Type': 'application/json',
112
229
  'X-WorkBuddy-Version': '2026-01',
113
230
  },
114
- body: {
115
- status: 'paused',
116
- },
117
231
  });
118
232
  }
119
233
  },
@@ -129,20 +243,86 @@ export const lead_updated_trigger = createTrigger({
129
243
  displayName: 'Lead Updated',
130
244
  description: 'Triggered when a lead is updated',
131
245
  props: {
132
- customer: Property.Array({
246
+ customer: Property.MultiSelectDropdown({
133
247
  displayName: 'Filter by Customer',
134
- description: 'Only trigger for specific customer IDs',
248
+ description: 'Only trigger for specific customer',
135
249
  required: false,
250
+ auth: workbuddyAuth,
251
+ refreshers: [],
252
+ options: async ({ auth }) => {
253
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
254
+ const token = await getAccessToken(authValue);
255
+ const baseUrl = authValue.props.baseUrl;
256
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
257
+ method: HttpMethod.GET,
258
+ url: `${baseUrl}/api/v2/public/customers`,
259
+ headers: {
260
+ Authorization: `Bearer ${token}`,
261
+ 'X-WorkBuddy-Version': '2026-01',
262
+ },
263
+ });
264
+ const items = response.body?.items || [];
265
+ return {
266
+ options: items.map((item) => ({
267
+ label: item.name,
268
+ value: item.id,
269
+ })),
270
+ };
271
+ },
136
272
  }),
137
- billingCompany: Property.Array({
273
+ billingCompany: Property.MultiSelectDropdown({
138
274
  displayName: 'Filter by Billing Company',
139
- description: 'Only trigger for specific billing company IDs',
275
+ description: 'Only trigger for specific billing company',
140
276
  required: false,
277
+ auth: workbuddyAuth,
278
+ refreshers: [],
279
+ options: async ({ auth }) => {
280
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
281
+ const token = await getAccessToken(authValue);
282
+ const baseUrl = authValue.props.baseUrl;
283
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
284
+ method: HttpMethod.GET,
285
+ url: `${baseUrl}/api/v2/public/companies`,
286
+ headers: {
287
+ Authorization: `Bearer ${token}`,
288
+ 'X-WorkBuddy-Version': '2026-01',
289
+ },
290
+ });
291
+ const items = response.body?.items || [];
292
+ return {
293
+ options: items.map((item) => ({
294
+ label: item.name,
295
+ value: item.id,
296
+ })),
297
+ };
298
+ },
141
299
  }),
142
- tag: Property.Array({
300
+ tag: Property.MultiSelectDropdown({
143
301
  displayName: 'Filter by Tags',
144
- description: 'Only trigger for specific tags IDs',
302
+ description: 'Only trigger for specific tags',
145
303
  required: false,
304
+ auth: workbuddyAuth,
305
+ refreshers: [],
306
+ options: async ({ auth }) => {
307
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
308
+ const token = await getAccessToken(authValue);
309
+ const baseUrl = authValue.props.baseUrl;
310
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
311
+ method: HttpMethod.GET,
312
+ url: `${baseUrl}/api/v2/public/settings/tags`,
313
+ headers: {
314
+ Authorization: `Bearer ${token}`,
315
+ 'X-WorkBuddy-Version': '2026-01',
316
+ },
317
+ });
318
+ const items = response.body?.items || [];
319
+ return {
320
+ options: items.map((item) => ({
321
+ label: item.name,
322
+ value: item.id,
323
+ })),
324
+ };
325
+ },
146
326
  }),
147
327
  leadStage: Property.Array({
148
328
  displayName: 'Filter by Stage',
@@ -154,26 +334,77 @@ export const lead_updated_trigger = createTrigger({
154
334
  description: 'Only trigger for specific source IDs',
155
335
  required: false,
156
336
  }),
157
- owner: Property.Array({
337
+ owner: Property.MultiSelectDropdown({
158
338
  displayName: 'Filter by Owner',
159
- description: 'Only trigger for specific owner IDs',
339
+ description: 'Only trigger for specific owner',
160
340
  required: false,
341
+ auth: workbuddyAuth,
342
+ refreshers: [],
343
+ options: async ({ auth }) => {
344
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
345
+ const token = await getAccessToken(authValue);
346
+ const baseUrl = authValue.props.baseUrl;
347
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
348
+ method: HttpMethod.GET,
349
+ url: `${baseUrl}/api/v2/public/employees`,
350
+ headers: {
351
+ Authorization: `Bearer ${token}`,
352
+ 'X-WorkBuddy-Version': '2026-01',
353
+ },
354
+ });
355
+ const items = response.body?.items || [];
356
+ return {
357
+ options: items.map((item) => ({
358
+ label: item.name,
359
+ value: item.id,
360
+ })),
361
+ };
362
+ },
161
363
  }),
162
- type: Property.Array({
364
+ type: Property.MultiSelectDropdown({
163
365
  displayName: 'Filter by Job Type',
164
- description: 'Only trigger for specific job type IDs',
366
+ description: 'Only trigger for specific job type',
165
367
  required: false,
368
+ auth: workbuddyAuth,
369
+ refreshers: [],
370
+ options: async ({ auth }) => {
371
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
372
+ const token = await getAccessToken(authValue);
373
+ const baseUrl = authValue.props.baseUrl;
374
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
375
+ method: HttpMethod.GET,
376
+ url: `${baseUrl}/api/v2/public/settings/job-types`,
377
+ headers: {
378
+ Authorization: `Bearer ${token}`,
379
+ 'X-WorkBuddy-Version': '2026-01',
380
+ },
381
+ });
382
+ const items = response.body?.items || [];
383
+ return {
384
+ options: items.map((item) => ({
385
+ label: item.name,
386
+ value: item.id,
387
+ })),
388
+ };
389
+ },
166
390
  }),
167
391
  },
168
392
  sampleData: {
169
- lead: {
170
- id: '507f1f77bcf86cd799439011',
171
- name: 'New Lead',
172
- status: 'New',
173
- source: 'website',
174
- createdAt: '2026-03-05T10:00:00.000Z',
175
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
176
- owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
393
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
394
+ event: 'Lead Updated',
395
+ action: 'update',
396
+ createdAt: '2026-03-14T05:21:47.307Z',
397
+ webhookTimestamp: 1773465707307,
398
+ data: {
399
+ lead: {
400
+ id: '507f1f77bcf86cd799439011',
401
+ name: 'New Lead',
402
+ status: 'New',
403
+ source: 'website',
404
+ createdAt: '2026-03-05T10:00:00.000Z',
405
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
406
+ owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
407
+ },
177
408
  },
178
409
  },
179
410
  type: TriggerStrategy.WEBHOOK,
@@ -191,7 +422,7 @@ export const lead_updated_trigger = createTrigger({
191
422
  if (context.propsValue.leadSource?.length) filters.leadSource = context.propsValue.leadSource;
192
423
  if (context.propsValue.owner?.length) filters.owner = context.propsValue.owner;
193
424
  if (context.propsValue.type?.length) filters.type = context.propsValue.type;
194
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
425
+ // Register webhook with WorkBuddy v2 API
195
426
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
196
427
  method: HttpMethod.POST,
197
428
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -223,18 +454,15 @@ export const lead_updated_trigger = createTrigger({
223
454
  const webhookId = await context.store.get<string>('webhookId');
224
455
 
225
456
  if (webhookId) {
226
- // Pause webhook (server keeps it for potential reactivation)
457
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
227
458
  await httpClient.sendRequest({
228
- method: HttpMethod.PATCH,
459
+ method: HttpMethod.DELETE,
229
460
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
230
461
  headers: {
231
462
  Authorization: `Bearer ${token}`,
232
463
  'Content-Type': 'application/json',
233
464
  'X-WorkBuddy-Version': '2026-01',
234
465
  },
235
- body: {
236
- status: 'paused',
237
- },
238
466
  });
239
467
  }
240
468
  },
@@ -250,20 +478,86 @@ export const lead_status_changed_trigger = createTrigger({
250
478
  displayName: 'Lead Status Changed',
251
479
  description: 'Triggered when a lead status changes',
252
480
  props: {
253
- customer: Property.Array({
481
+ customer: Property.MultiSelectDropdown({
254
482
  displayName: 'Filter by Customer',
255
- description: 'Only trigger for specific customer IDs',
483
+ description: 'Only trigger for specific customer',
256
484
  required: false,
485
+ auth: workbuddyAuth,
486
+ refreshers: [],
487
+ options: async ({ auth }) => {
488
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
489
+ const token = await getAccessToken(authValue);
490
+ const baseUrl = authValue.props.baseUrl;
491
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
492
+ method: HttpMethod.GET,
493
+ url: `${baseUrl}/api/v2/public/customers`,
494
+ headers: {
495
+ Authorization: `Bearer ${token}`,
496
+ 'X-WorkBuddy-Version': '2026-01',
497
+ },
498
+ });
499
+ const items = response.body?.items || [];
500
+ return {
501
+ options: items.map((item) => ({
502
+ label: item.name,
503
+ value: item.id,
504
+ })),
505
+ };
506
+ },
257
507
  }),
258
- billingCompany: Property.Array({
508
+ billingCompany: Property.MultiSelectDropdown({
259
509
  displayName: 'Filter by Billing Company',
260
- description: 'Only trigger for specific billing company IDs',
510
+ description: 'Only trigger for specific billing company',
261
511
  required: false,
512
+ auth: workbuddyAuth,
513
+ refreshers: [],
514
+ options: async ({ auth }) => {
515
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
516
+ const token = await getAccessToken(authValue);
517
+ const baseUrl = authValue.props.baseUrl;
518
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
519
+ method: HttpMethod.GET,
520
+ url: `${baseUrl}/api/v2/public/companies`,
521
+ headers: {
522
+ Authorization: `Bearer ${token}`,
523
+ 'X-WorkBuddy-Version': '2026-01',
524
+ },
525
+ });
526
+ const items = response.body?.items || [];
527
+ return {
528
+ options: items.map((item) => ({
529
+ label: item.name,
530
+ value: item.id,
531
+ })),
532
+ };
533
+ },
262
534
  }),
263
- tag: Property.Array({
535
+ tag: Property.MultiSelectDropdown({
264
536
  displayName: 'Filter by Tags',
265
- description: 'Only trigger for specific tags IDs',
537
+ description: 'Only trigger for specific tags',
266
538
  required: false,
539
+ auth: workbuddyAuth,
540
+ refreshers: [],
541
+ options: async ({ auth }) => {
542
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
543
+ const token = await getAccessToken(authValue);
544
+ const baseUrl = authValue.props.baseUrl;
545
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
546
+ method: HttpMethod.GET,
547
+ url: `${baseUrl}/api/v2/public/settings/tags`,
548
+ headers: {
549
+ Authorization: `Bearer ${token}`,
550
+ 'X-WorkBuddy-Version': '2026-01',
551
+ },
552
+ });
553
+ const items = response.body?.items || [];
554
+ return {
555
+ options: items.map((item) => ({
556
+ label: item.name,
557
+ value: item.id,
558
+ })),
559
+ };
560
+ },
267
561
  }),
268
562
  leadStage: Property.Array({
269
563
  displayName: 'Filter by Stage',
@@ -275,26 +569,77 @@ export const lead_status_changed_trigger = createTrigger({
275
569
  description: 'Only trigger for specific source IDs',
276
570
  required: false,
277
571
  }),
278
- owner: Property.Array({
572
+ owner: Property.MultiSelectDropdown({
279
573
  displayName: 'Filter by Owner',
280
- description: 'Only trigger for specific owner IDs',
574
+ description: 'Only trigger for specific owner',
281
575
  required: false,
576
+ auth: workbuddyAuth,
577
+ refreshers: [],
578
+ options: async ({ auth }) => {
579
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
580
+ const token = await getAccessToken(authValue);
581
+ const baseUrl = authValue.props.baseUrl;
582
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
583
+ method: HttpMethod.GET,
584
+ url: `${baseUrl}/api/v2/public/employees`,
585
+ headers: {
586
+ Authorization: `Bearer ${token}`,
587
+ 'X-WorkBuddy-Version': '2026-01',
588
+ },
589
+ });
590
+ const items = response.body?.items || [];
591
+ return {
592
+ options: items.map((item) => ({
593
+ label: item.name,
594
+ value: item.id,
595
+ })),
596
+ };
597
+ },
282
598
  }),
283
- type: Property.Array({
599
+ type: Property.MultiSelectDropdown({
284
600
  displayName: 'Filter by Job Type',
285
- description: 'Only trigger for specific job type IDs',
601
+ description: 'Only trigger for specific job type',
286
602
  required: false,
603
+ auth: workbuddyAuth,
604
+ refreshers: [],
605
+ options: async ({ auth }) => {
606
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
607
+ const token = await getAccessToken(authValue);
608
+ const baseUrl = authValue.props.baseUrl;
609
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
610
+ method: HttpMethod.GET,
611
+ url: `${baseUrl}/api/v2/public/settings/job-types`,
612
+ headers: {
613
+ Authorization: `Bearer ${token}`,
614
+ 'X-WorkBuddy-Version': '2026-01',
615
+ },
616
+ });
617
+ const items = response.body?.items || [];
618
+ return {
619
+ options: items.map((item) => ({
620
+ label: item.name,
621
+ value: item.id,
622
+ })),
623
+ };
624
+ },
287
625
  }),
288
626
  },
289
627
  sampleData: {
290
- lead: {
291
- id: '507f1f77bcf86cd799439011',
292
- name: 'New Lead',
293
- status: 'New',
294
- source: 'website',
295
- createdAt: '2026-03-05T10:00:00.000Z',
296
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
297
- owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
628
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
629
+ event: 'Lead Status Changed',
630
+ action: 'update',
631
+ createdAt: '2026-03-14T05:21:47.307Z',
632
+ webhookTimestamp: 1773465707307,
633
+ data: {
634
+ lead: {
635
+ id: '507f1f77bcf86cd799439011',
636
+ name: 'New Lead',
637
+ status: 'New',
638
+ source: 'website',
639
+ createdAt: '2026-03-05T10:00:00.000Z',
640
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
641
+ owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
642
+ },
298
643
  },
299
644
  },
300
645
  type: TriggerStrategy.WEBHOOK,
@@ -312,7 +657,7 @@ export const lead_status_changed_trigger = createTrigger({
312
657
  if (context.propsValue.leadSource?.length) filters.leadSource = context.propsValue.leadSource;
313
658
  if (context.propsValue.owner?.length) filters.owner = context.propsValue.owner;
314
659
  if (context.propsValue.type?.length) filters.type = context.propsValue.type;
315
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
660
+ // Register webhook with WorkBuddy v2 API
316
661
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
317
662
  method: HttpMethod.POST,
318
663
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -344,18 +689,15 @@ export const lead_status_changed_trigger = createTrigger({
344
689
  const webhookId = await context.store.get<string>('webhookId');
345
690
 
346
691
  if (webhookId) {
347
- // Pause webhook (server keeps it for potential reactivation)
692
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
348
693
  await httpClient.sendRequest({
349
- method: HttpMethod.PATCH,
694
+ method: HttpMethod.DELETE,
350
695
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
351
696
  headers: {
352
697
  Authorization: `Bearer ${token}`,
353
698
  'Content-Type': 'application/json',
354
699
  'X-WorkBuddy-Version': '2026-01',
355
700
  },
356
- body: {
357
- status: 'paused',
358
- },
359
701
  });
360
702
  }
361
703
  },
@@ -371,20 +713,86 @@ export const lead_deleted_trigger = createTrigger({
371
713
  displayName: 'Lead Deleted',
372
714
  description: 'Triggered when a lead is deleted',
373
715
  props: {
374
- customer: Property.Array({
716
+ customer: Property.MultiSelectDropdown({
375
717
  displayName: 'Filter by Customer',
376
- description: 'Only trigger for specific customer IDs',
718
+ description: 'Only trigger for specific customer',
377
719
  required: false,
720
+ auth: workbuddyAuth,
721
+ refreshers: [],
722
+ options: async ({ auth }) => {
723
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
724
+ const token = await getAccessToken(authValue);
725
+ const baseUrl = authValue.props.baseUrl;
726
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
727
+ method: HttpMethod.GET,
728
+ url: `${baseUrl}/api/v2/public/customers`,
729
+ headers: {
730
+ Authorization: `Bearer ${token}`,
731
+ 'X-WorkBuddy-Version': '2026-01',
732
+ },
733
+ });
734
+ const items = response.body?.items || [];
735
+ return {
736
+ options: items.map((item) => ({
737
+ label: item.name,
738
+ value: item.id,
739
+ })),
740
+ };
741
+ },
378
742
  }),
379
- billingCompany: Property.Array({
743
+ billingCompany: Property.MultiSelectDropdown({
380
744
  displayName: 'Filter by Billing Company',
381
- description: 'Only trigger for specific billing company IDs',
745
+ description: 'Only trigger for specific billing company',
382
746
  required: false,
747
+ auth: workbuddyAuth,
748
+ refreshers: [],
749
+ options: async ({ auth }) => {
750
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
751
+ const token = await getAccessToken(authValue);
752
+ const baseUrl = authValue.props.baseUrl;
753
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
754
+ method: HttpMethod.GET,
755
+ url: `${baseUrl}/api/v2/public/companies`,
756
+ headers: {
757
+ Authorization: `Bearer ${token}`,
758
+ 'X-WorkBuddy-Version': '2026-01',
759
+ },
760
+ });
761
+ const items = response.body?.items || [];
762
+ return {
763
+ options: items.map((item) => ({
764
+ label: item.name,
765
+ value: item.id,
766
+ })),
767
+ };
768
+ },
383
769
  }),
384
- tag: Property.Array({
770
+ tag: Property.MultiSelectDropdown({
385
771
  displayName: 'Filter by Tags',
386
- description: 'Only trigger for specific tags IDs',
772
+ description: 'Only trigger for specific tags',
387
773
  required: false,
774
+ auth: workbuddyAuth,
775
+ refreshers: [],
776
+ options: async ({ auth }) => {
777
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
778
+ const token = await getAccessToken(authValue);
779
+ const baseUrl = authValue.props.baseUrl;
780
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
781
+ method: HttpMethod.GET,
782
+ url: `${baseUrl}/api/v2/public/settings/tags`,
783
+ headers: {
784
+ Authorization: `Bearer ${token}`,
785
+ 'X-WorkBuddy-Version': '2026-01',
786
+ },
787
+ });
788
+ const items = response.body?.items || [];
789
+ return {
790
+ options: items.map((item) => ({
791
+ label: item.name,
792
+ value: item.id,
793
+ })),
794
+ };
795
+ },
388
796
  }),
389
797
  leadStage: Property.Array({
390
798
  displayName: 'Filter by Stage',
@@ -396,26 +804,77 @@ export const lead_deleted_trigger = createTrigger({
396
804
  description: 'Only trigger for specific source IDs',
397
805
  required: false,
398
806
  }),
399
- owner: Property.Array({
807
+ owner: Property.MultiSelectDropdown({
400
808
  displayName: 'Filter by Owner',
401
- description: 'Only trigger for specific owner IDs',
809
+ description: 'Only trigger for specific owner',
402
810
  required: false,
811
+ auth: workbuddyAuth,
812
+ refreshers: [],
813
+ options: async ({ auth }) => {
814
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
815
+ const token = await getAccessToken(authValue);
816
+ const baseUrl = authValue.props.baseUrl;
817
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
818
+ method: HttpMethod.GET,
819
+ url: `${baseUrl}/api/v2/public/employees`,
820
+ headers: {
821
+ Authorization: `Bearer ${token}`,
822
+ 'X-WorkBuddy-Version': '2026-01',
823
+ },
824
+ });
825
+ const items = response.body?.items || [];
826
+ return {
827
+ options: items.map((item) => ({
828
+ label: item.name,
829
+ value: item.id,
830
+ })),
831
+ };
832
+ },
403
833
  }),
404
- type: Property.Array({
834
+ type: Property.MultiSelectDropdown({
405
835
  displayName: 'Filter by Job Type',
406
- description: 'Only trigger for specific job type IDs',
836
+ description: 'Only trigger for specific job type',
407
837
  required: false,
838
+ auth: workbuddyAuth,
839
+ refreshers: [],
840
+ options: async ({ auth }) => {
841
+ const authValue = auth as unknown as { props: { baseUrl: string; clientId: string; clientSecret: string } };
842
+ const token = await getAccessToken(authValue);
843
+ const baseUrl = authValue.props.baseUrl;
844
+ const response = await httpClient.sendRequest<{ items: Array<{ id: string; name: string }> }>({
845
+ method: HttpMethod.GET,
846
+ url: `${baseUrl}/api/v2/public/settings/job-types`,
847
+ headers: {
848
+ Authorization: `Bearer ${token}`,
849
+ 'X-WorkBuddy-Version': '2026-01',
850
+ },
851
+ });
852
+ const items = response.body?.items || [];
853
+ return {
854
+ options: items.map((item) => ({
855
+ label: item.name,
856
+ value: item.id,
857
+ })),
858
+ };
859
+ },
408
860
  }),
409
861
  },
410
862
  sampleData: {
411
- lead: {
412
- id: '507f1f77bcf86cd799439011',
413
- name: 'New Lead',
414
- status: 'New',
415
- source: 'website',
416
- createdAt: '2026-03-05T10:00:00.000Z',
417
- customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
418
- owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
863
+ id: 'whd_019ceacb-232b-764f-8dfd-748e1a226de2',
864
+ event: 'Lead Deleted',
865
+ action: 'remove',
866
+ createdAt: '2026-03-14T05:21:47.307Z',
867
+ webhookTimestamp: 1773465707307,
868
+ data: {
869
+ lead: {
870
+ id: '507f1f77bcf86cd799439011',
871
+ name: 'New Lead',
872
+ status: 'New',
873
+ source: 'website',
874
+ createdAt: '2026-03-05T10:00:00.000Z',
875
+ customer: { id: '507f1f77bcf86cd799439011', name: 'Acme Corp' },
876
+ owner: { id: '507f1f77bcf86cd799439011', name: 'John Smith' },
877
+ },
419
878
  },
420
879
  },
421
880
  type: TriggerStrategy.WEBHOOK,
@@ -433,7 +892,7 @@ export const lead_deleted_trigger = createTrigger({
433
892
  if (context.propsValue.leadSource?.length) filters.leadSource = context.propsValue.leadSource;
434
893
  if (context.propsValue.owner?.length) filters.owner = context.propsValue.owner;
435
894
  if (context.propsValue.type?.length) filters.type = context.propsValue.type;
436
- // Register webhook with WorkBuddy v2 API (server handles upsert - reactivates if exists)
895
+ // Register webhook with WorkBuddy v2 API
437
896
  const response = await httpClient.sendRequest<{ data: { id: string } }>({
438
897
  method: HttpMethod.POST,
439
898
  url: `${baseUrl}/api/v2/public/webhooks`,
@@ -465,18 +924,15 @@ export const lead_deleted_trigger = createTrigger({
465
924
  const webhookId = await context.store.get<string>('webhookId');
466
925
 
467
926
  if (webhookId) {
468
- // Pause webhook (server keeps it for potential reactivation)
927
+ // Delete webhook to avoid stale subscriptions causing duplicate trigger deliveries
469
928
  await httpClient.sendRequest({
470
- method: HttpMethod.PATCH,
929
+ method: HttpMethod.DELETE,
471
930
  url: `${baseUrl}/api/v2/public/webhooks/${webhookId}`,
472
931
  headers: {
473
932
  Authorization: `Bearer ${token}`,
474
933
  'Content-Type': 'application/json',
475
934
  'X-WorkBuddy-Version': '2026-01',
476
935
  },
477
- body: {
478
- status: 'paused',
479
- },
480
936
  });
481
937
  }
482
938
  },