@agnocon/piece-bigin-by-zoho 0.1.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 (157) hide show
  1. package/LICENSE.MIT-AP +24 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +72 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/actions/create-call.d.ts +16 -0
  7. package/dist/lib/actions/create-call.d.ts.map +1 -0
  8. package/dist/lib/actions/create-call.js +162 -0
  9. package/dist/lib/actions/create-call.js.map +1 -0
  10. package/dist/lib/actions/create-company.d.ts +14 -0
  11. package/dist/lib/actions/create-company.d.ts.map +1 -0
  12. package/dist/lib/actions/create-company.js +108 -0
  13. package/dist/lib/actions/create-company.js.map +1 -0
  14. package/dist/lib/actions/create-contact.d.ts +18 -0
  15. package/dist/lib/actions/create-contact.d.ts.map +1 -0
  16. package/dist/lib/actions/create-contact.js +130 -0
  17. package/dist/lib/actions/create-contact.js.map +1 -0
  18. package/dist/lib/actions/create-event.d.ts +18 -0
  19. package/dist/lib/actions/create-event.d.ts.map +1 -0
  20. package/dist/lib/actions/create-event.js +360 -0
  21. package/dist/lib/actions/create-event.js.map +1 -0
  22. package/dist/lib/actions/create-pipeline-record.d.ts +16 -0
  23. package/dist/lib/actions/create-pipeline-record.d.ts.map +1 -0
  24. package/dist/lib/actions/create-pipeline-record.js +219 -0
  25. package/dist/lib/actions/create-pipeline-record.js.map +1 -0
  26. package/dist/lib/actions/create-task.d.ts +16 -0
  27. package/dist/lib/actions/create-task.d.ts.map +1 -0
  28. package/dist/lib/actions/create-task.js +380 -0
  29. package/dist/lib/actions/create-task.js.map +1 -0
  30. package/dist/lib/actions/search-company-record.d.ts +5 -0
  31. package/dist/lib/actions/search-company-record.d.ts.map +1 -0
  32. package/dist/lib/actions/search-company-record.js +58 -0
  33. package/dist/lib/actions/search-company-record.js.map +1 -0
  34. package/dist/lib/actions/search-contact-record.d.ts +5 -0
  35. package/dist/lib/actions/search-contact-record.d.ts.map +1 -0
  36. package/dist/lib/actions/search-contact-record.js +82 -0
  37. package/dist/lib/actions/search-contact-record.js.map +1 -0
  38. package/dist/lib/actions/search-pipeline-records.d.ts +5 -0
  39. package/dist/lib/actions/search-pipeline-records.d.ts.map +1 -0
  40. package/dist/lib/actions/search-pipeline-records.js +53 -0
  41. package/dist/lib/actions/search-pipeline-records.js.map +1 -0
  42. package/dist/lib/actions/search-product.d.ts +5 -0
  43. package/dist/lib/actions/search-product.d.ts.map +1 -0
  44. package/dist/lib/actions/search-product.js +60 -0
  45. package/dist/lib/actions/search-product.js.map +1 -0
  46. package/dist/lib/actions/search-user.d.ts +7 -0
  47. package/dist/lib/actions/search-user.d.ts.map +1 -0
  48. package/dist/lib/actions/search-user.js +75 -0
  49. package/dist/lib/actions/search-user.js.map +1 -0
  50. package/dist/lib/actions/update-company.d.ts +7 -0
  51. package/dist/lib/actions/update-company.d.ts.map +1 -0
  52. package/dist/lib/actions/update-company.js +224 -0
  53. package/dist/lib/actions/update-company.js.map +1 -0
  54. package/dist/lib/actions/update-contact.d.ts +7 -0
  55. package/dist/lib/actions/update-contact.d.ts.map +1 -0
  56. package/dist/lib/actions/update-contact.js +248 -0
  57. package/dist/lib/actions/update-contact.js.map +1 -0
  58. package/dist/lib/actions/update-event.d.ts +13 -0
  59. package/dist/lib/actions/update-event.d.ts.map +1 -0
  60. package/dist/lib/actions/update-event.js +466 -0
  61. package/dist/lib/actions/update-event.js.map +1 -0
  62. package/dist/lib/actions/update-pipeline-record.d.ts +14 -0
  63. package/dist/lib/actions/update-pipeline-record.d.ts.map +1 -0
  64. package/dist/lib/actions/update-pipeline-record.js +205 -0
  65. package/dist/lib/actions/update-pipeline-record.js.map +1 -0
  66. package/dist/lib/actions/update-task.d.ts +13 -0
  67. package/dist/lib/actions/update-task.d.ts.map +1 -0
  68. package/dist/lib/actions/update-task.js +449 -0
  69. package/dist/lib/actions/update-task.js.map +1 -0
  70. package/dist/lib/auth.d.ts +2 -0
  71. package/dist/lib/auth.d.ts.map +1 -0
  72. package/dist/lib/auth.js +59 -0
  73. package/dist/lib/auth.js.map +1 -0
  74. package/dist/lib/common/constants.d.ts +23 -0
  75. package/dist/lib/common/constants.d.ts.map +1 -0
  76. package/dist/lib/common/constants.js +72 -0
  77. package/dist/lib/common/constants.js.map +1 -0
  78. package/dist/lib/common/helpers.d.ts +11 -0
  79. package/dist/lib/common/helpers.d.ts.map +1 -0
  80. package/dist/lib/common/helpers.js +40 -0
  81. package/dist/lib/common/helpers.js.map +1 -0
  82. package/dist/lib/common/props.d.ts +10 -0
  83. package/dist/lib/common/props.d.ts.map +1 -0
  84. package/dist/lib/common/props.js +217 -0
  85. package/dist/lib/common/props.js.map +1 -0
  86. package/dist/lib/common/request.d.ts +35 -0
  87. package/dist/lib/common/request.d.ts.map +1 -0
  88. package/dist/lib/common/request.js +226 -0
  89. package/dist/lib/common/request.js.map +1 -0
  90. package/dist/lib/triggers/company-updated.d.ts +3 -0
  91. package/dist/lib/triggers/company-updated.d.ts.map +1 -0
  92. package/dist/lib/triggers/company-updated.js +66 -0
  93. package/dist/lib/triggers/company-updated.js.map +1 -0
  94. package/dist/lib/triggers/contact-updated.d.ts +3 -0
  95. package/dist/lib/triggers/contact-updated.d.ts.map +1 -0
  96. package/dist/lib/triggers/contact-updated.js +66 -0
  97. package/dist/lib/triggers/contact-updated.js.map +1 -0
  98. package/dist/lib/triggers/new-call-created.d.ts +3 -0
  99. package/dist/lib/triggers/new-call-created.d.ts.map +1 -0
  100. package/dist/lib/triggers/new-call-created.js +66 -0
  101. package/dist/lib/triggers/new-call-created.js.map +1 -0
  102. package/dist/lib/triggers/new-company-created.d.ts +3 -0
  103. package/dist/lib/triggers/new-company-created.d.ts.map +1 -0
  104. package/dist/lib/triggers/new-company-created.js +66 -0
  105. package/dist/lib/triggers/new-company-created.js.map +1 -0
  106. package/dist/lib/triggers/new-contact-created.d.ts +3 -0
  107. package/dist/lib/triggers/new-contact-created.d.ts.map +1 -0
  108. package/dist/lib/triggers/new-contact-created.js +75 -0
  109. package/dist/lib/triggers/new-contact-created.js.map +1 -0
  110. package/dist/lib/triggers/new-event-created.d.ts +3 -0
  111. package/dist/lib/triggers/new-event-created.d.ts.map +1 -0
  112. package/dist/lib/triggers/new-event-created.js +66 -0
  113. package/dist/lib/triggers/new-event-created.js.map +1 -0
  114. package/dist/lib/triggers/new-pipeline-record.d.ts +3 -0
  115. package/dist/lib/triggers/new-pipeline-record.d.ts.map +1 -0
  116. package/dist/lib/triggers/new-pipeline-record.js +66 -0
  117. package/dist/lib/triggers/new-pipeline-record.js.map +1 -0
  118. package/dist/lib/triggers/new-task-created.d.ts +3 -0
  119. package/dist/lib/triggers/new-task-created.d.ts.map +1 -0
  120. package/dist/lib/triggers/new-task-created.js +66 -0
  121. package/dist/lib/triggers/new-task-created.js.map +1 -0
  122. package/dist/lib/triggers/pipeline-record-updated.d.ts +3 -0
  123. package/dist/lib/triggers/pipeline-record-updated.d.ts.map +1 -0
  124. package/dist/lib/triggers/pipeline-record-updated.js +66 -0
  125. package/dist/lib/triggers/pipeline-record-updated.js.map +1 -0
  126. package/package.json +46 -0
  127. package/src/index.ts +72 -0
  128. package/src/lib/actions/create-call.ts +168 -0
  129. package/src/lib/actions/create-company.ts +124 -0
  130. package/src/lib/actions/create-contact.ts +151 -0
  131. package/src/lib/actions/create-event.ts +399 -0
  132. package/src/lib/actions/create-pipeline-record.ts +255 -0
  133. package/src/lib/actions/create-task.ts +426 -0
  134. package/src/lib/actions/search-company-record.ts +57 -0
  135. package/src/lib/actions/search-contact-record.ts +79 -0
  136. package/src/lib/actions/search-pipeline-records.ts +52 -0
  137. package/src/lib/actions/search-product.ts +60 -0
  138. package/src/lib/actions/search-user.ts +70 -0
  139. package/src/lib/actions/update-company.ts +235 -0
  140. package/src/lib/actions/update-contact.ts +261 -0
  141. package/src/lib/actions/update-event.ts +528 -0
  142. package/src/lib/actions/update-pipeline-record.ts +235 -0
  143. package/src/lib/actions/update-task.ts +499 -0
  144. package/src/lib/auth.ts +57 -0
  145. package/src/lib/common/constants.ts +68 -0
  146. package/src/lib/common/helpers.ts +46 -0
  147. package/src/lib/common/props.ts +270 -0
  148. package/src/lib/common/request.ts +285 -0
  149. package/src/lib/triggers/company-updated.ts +69 -0
  150. package/src/lib/triggers/contact-updated.ts +65 -0
  151. package/src/lib/triggers/new-call-created.ts +69 -0
  152. package/src/lib/triggers/new-company-created.ts +69 -0
  153. package/src/lib/triggers/new-contact-created.ts +75 -0
  154. package/src/lib/triggers/new-event-created.ts +69 -0
  155. package/src/lib/triggers/new-pipeline-record.ts +69 -0
  156. package/src/lib/triggers/new-task-created.ts +69 -0
  157. package/src/lib/triggers/pipeline-record-updated.ts +69 -0
@@ -0,0 +1,151 @@
1
+ import { biginAuth } from '../auth';
2
+ import { createAction, Property } from '@agnocon/pieces-framework';
3
+ import { companyDropdown, tagsDropdown, usersDropdown } from '../common/props';
4
+ import { biginApiService } from '../common/request';
5
+ import { handleDropdownError } from '../common/helpers';
6
+
7
+ export const createContact = createAction({
8
+ auth: biginAuth,
9
+ name: 'createContact',
10
+ displayName: 'Create Contact',
11
+ description: 'Creates a Contact Record',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Creates a new contact (person) record in Bigin CRM. Last name is required; optionally set email, mobile, title, owner, associated company, tags, mailing address, and description. Use to add a person to the CRM. Not idempotent: each call creates a new contact even with identical details, so search first to avoid duplicates.', idempotent: false },
14
+ props: {
15
+ firstName: Property.ShortText({
16
+ displayName: 'First Name',
17
+ description: 'First name of the contact',
18
+ required: false,
19
+ }),
20
+ lastName: Property.ShortText({
21
+ displayName: 'Last Name',
22
+ description: 'Last name of the contact',
23
+ required: true,
24
+ }),
25
+ title: Property.ShortText({
26
+ displayName: 'Title',
27
+ description: 'Job title of the contact',
28
+ required: false,
29
+ }),
30
+ email: Property.ShortText({
31
+ displayName: 'Email',
32
+ description: 'Email address of the contact',
33
+ required: false,
34
+ }),
35
+ mobile: Property.ShortText({
36
+ displayName: 'Mobile',
37
+ description: 'Mobile phone number',
38
+ required: false,
39
+ }),
40
+ emailOptOut: Property.Checkbox({
41
+ displayName: 'Email Opt Out',
42
+ description: 'Whether the contact has opted out of emails',
43
+ required: false,
44
+ defaultValue: false,
45
+ }),
46
+ owner: usersDropdown,
47
+ accountName: companyDropdown,
48
+ tag: tagsDropdown('Contacts'),
49
+ description: Property.LongText({
50
+ displayName: 'Description',
51
+ description: 'Provide additional descriptions or notes related to the contact',
52
+ required: false,
53
+ }),
54
+ mailingStreet: Property.ShortText({
55
+ displayName: 'Mailing Street',
56
+ description: 'Street address for mailing',
57
+ required: false,
58
+ }),
59
+ mailingCity: Property.ShortText({
60
+ displayName: 'Mailing City',
61
+ description: 'City for mailing address',
62
+ required: false,
63
+ }),
64
+ mailingState: Property.ShortText({
65
+ displayName: 'Mailing State',
66
+ description: 'State for mailing address',
67
+ required: false,
68
+ }),
69
+ mailingCountry: Property.ShortText({
70
+ displayName: 'Mailing Country',
71
+ description: 'Country for mailing address',
72
+ required: false,
73
+ }),
74
+ mailingZip: Property.ShortText({
75
+ displayName: 'Mailing Zip',
76
+ description: 'ZIP/postal code',
77
+ required: false,
78
+ }),
79
+ },
80
+ async run(context) {
81
+ try {
82
+ const {
83
+ firstName,
84
+ lastName,
85
+ title,
86
+ email,
87
+ mobile,
88
+ emailOptOut,
89
+ owner,
90
+ accountName,
91
+ tag,
92
+ description,
93
+ mailingStreet,
94
+ mailingCity,
95
+ mailingState,
96
+ mailingCountry,
97
+ mailingZip,
98
+ } = context.propsValue;
99
+
100
+ const record: Record<string, any> = {
101
+ First_Name: firstName,
102
+ Last_Name: lastName,
103
+ Title: title,
104
+ Email: email,
105
+ Mobile: mobile,
106
+ Email_Opt_Out: emailOptOut,
107
+ Owner: owner ? { id: owner } : undefined,
108
+ Account_Name: accountName ? { id: accountName } : undefined,
109
+ Tag: tag?.length ? tag.map((t: any) => ({ name: t })) : undefined,
110
+ Description: description,
111
+ Mailing_Street: mailingStreet,
112
+ Mailing_City: mailingCity,
113
+ Mailing_State: mailingState,
114
+ Mailing_Country: mailingCountry,
115
+ Mailing_Zip: mailingZip,
116
+ };
117
+
118
+ Object.keys(record).forEach((k) => {
119
+ const v = record[k];
120
+ if (
121
+ v === undefined ||
122
+ v === null ||
123
+ (typeof v === 'string' && v.trim() === '') ||
124
+ (Array.isArray(v) && v.length === 0)
125
+ ) {
126
+ delete record[k];
127
+ }
128
+ });
129
+
130
+ const payload = { data: [record] };
131
+
132
+ const response = await biginApiService.createContact(
133
+ context.auth.access_token,
134
+ context.auth.data['api_domain'],
135
+ payload
136
+ );
137
+
138
+ return {
139
+ message: 'Contact created successfully',
140
+ data: response.data[0],
141
+ };
142
+ } catch (error: any) {
143
+ console.error('Error creating contact:', error);
144
+ throw new Error(
145
+ error instanceof Error
146
+ ? `Failed to create contact: ${error.message}`
147
+ : 'Failed to create contact due to an unknown error'
148
+ );
149
+ }
150
+ },
151
+ });
@@ -0,0 +1,399 @@
1
+ import { biginAuth } from '../auth';
2
+ import { createAction, Property } from '@agnocon/pieces-framework';
3
+ import { tagsDropdown, usersDropdown } from '../common/props';
4
+ import { API_ENDPOINTS } from '../common/constants';
5
+ import { biginApiService } from '../common/request';
6
+ import { formatDateOnly, formatDateTime, getSafeLabel, handleDropdownError } from '../common/helpers';
7
+
8
+ export const createEvent = createAction({
9
+ auth: biginAuth,
10
+ name: 'createEvent',
11
+ displayName: 'Create Event',
12
+ description: 'Creates a new event in Bigin',
13
+ audience: 'both',
14
+ aiMetadata: { description: 'Creates a calendar event in Bigin CRM with a title, start and end date/time (end must be after start), plus optional all-day flag, venue, participants, description, and tags. Supports optional recurrence (daily/weekly/monthly/yearly RRULE) and reminders, and can be linked to a related Contact, Pipeline, or Company record. Use to schedule a meeting or appointment. Not idempotent: each call creates a new event.', idempotent: false },
15
+ props: {
16
+ eventTitle: Property.ShortText({
17
+ displayName: 'Event Title',
18
+ description: 'Provide the title or name of the event',
19
+ required: true,
20
+ }),
21
+ owner: usersDropdown,
22
+ startDateTime: Property.DateTime({
23
+ displayName: 'Start Date & Time',
24
+ description: 'Start date and time of the event',
25
+ required: true,
26
+ }),
27
+ endDateTime: Property.DateTime({
28
+ displayName: 'End Date & Time',
29
+ description: 'End date and time of the event',
30
+ required: true,
31
+ }),
32
+ allDay: Property.Checkbox({
33
+ displayName: 'All Day Event',
34
+ description: 'Mark this as an all-day event',
35
+ required: false,
36
+ }),
37
+ enableRecurring: Property.Checkbox({
38
+ displayName: 'Make Event Recurring',
39
+ description: 'Make this event recurring',
40
+ required: false,
41
+ }),
42
+ recurringInfo: Property.DynamicProperties({
43
+ auth: biginAuth,
44
+ displayName: 'Recurring Info',
45
+ refreshers: ['enableRecurring'],
46
+ required: false,
47
+ props: (propsValue, ctx): any => {
48
+ if (propsValue['enableRecurring']) {
49
+ return {
50
+ freq: Property.StaticDropdown({
51
+ displayName: 'Frequency',
52
+ required: true,
53
+ options: {
54
+ options: [
55
+ { label: 'Daily', value: 'DAILY' },
56
+ { label: 'Weekly', value: 'WEEKLY' },
57
+ { label: 'Monthly', value: 'MONTHLY' },
58
+ { label: 'Yearly', value: 'YEARLY' },
59
+ ],
60
+ },
61
+ }),
62
+ interval: Property.Number({
63
+ displayName: 'Interval',
64
+ required: true,
65
+ description:
66
+ 'Indicates the time gap between each event. The INTERVAL value range from 1 to 99. For example, an INTERVAL of 2 for a WEEKLY recurring event means that there will be a two-week gap between each event.',
67
+ defaultValue: 1,
68
+ }),
69
+ count: Property.Number({
70
+ displayName: 'Count',
71
+ required: true,
72
+ defaultValue: 1,
73
+ description:
74
+ 'Indicates the number of events you want to create. THE COUNT value range from 1 to 99. For example, a COUNT of 3 creates three individual events.',
75
+ }),
76
+ byday: Property.StaticDropdown({
77
+ displayName: 'By Day',
78
+ required: false,
79
+ description:
80
+ 'Indicates the day of the week the event repeats. The possible values are SU, MO, TU, WE, TH, FR, or SA. This is applicable only for weekly, and monthly events.',
81
+ options: {
82
+ options: [
83
+ { label: 'Sunday', value: 'SU' },
84
+ { label: 'Monday', value: 'MO' },
85
+ { label: 'Tuesday', value: 'TU' },
86
+ { label: 'Wednesday', value: 'WE' },
87
+ { label: 'Thursday', value: 'TH' },
88
+ { label: 'Friday', value: 'FR' },
89
+ { label: 'Saturday', value: 'SA' },
90
+ ],
91
+ },
92
+ }),
93
+ bymonthday: Property.Number({
94
+ displayName: 'By Month Day',
95
+ required: false,
96
+ description:
97
+ ' Indicates the day of the month the event repeats. The BYMONTHDAY value range from 1 to 31. This is applicable only for weekly and monthly events.',
98
+ }),
99
+ bysetpos: Property.StaticDropdown({
100
+ displayName: 'By Set Position',
101
+ required: false,
102
+ description:
103
+ 'Indicates the week of the month the event repeats. The possible values are 1 for the first week of the month, 2 for the second week of the month, 3 the for third week of the month, 4 for the fourth week of the month, or -1 for the last week of the month. This is applicable only for weekly and monthly events.',
104
+ options: {
105
+ options: [
106
+ { label: 'First Week of the Month', value: '1' },
107
+ { label: 'Second Week of the Month', value: '2' },
108
+ { label: 'Third Week of the Month', value: '3' },
109
+ { label: 'Fourth Week of the Month', value: '4' },
110
+ { label: 'Last Week of the Month', value: '-1' },
111
+ ],
112
+ },
113
+ }),
114
+ until: Property.ShortText({
115
+ displayName: 'Until (YYYY-MM-DD)',
116
+ description: 'Date the recurrence ends. Format: YYYY-MM-DD',
117
+ required: false,
118
+ }),
119
+ };
120
+ } else {
121
+ return {};
122
+ }
123
+ },
124
+ }),
125
+ enableReminder: Property.Checkbox({
126
+ displayName: 'Enable Reminder',
127
+ description: 'Enable reminder for this event',
128
+ required: false,
129
+ }),
130
+ reminderInfo: Property.DynamicProperties({
131
+ auth: biginAuth,
132
+ displayName: 'Reminder Information',
133
+ refreshers: ['enableReminder'],
134
+ required: false,
135
+ props: (propsValue, ctx): any => {
136
+
137
+ if (propsValue['enableReminder']) {
138
+ return {
139
+ reminderList: Property.Array({
140
+ displayName: 'Reminder List',
141
+ description:
142
+ 'Add multiple reminders (e.g., "1 hour", "30 minutes")',
143
+ required: false,
144
+ properties: {
145
+ unit: Property.Number({
146
+ displayName: 'Time Value',
147
+ description: 'Number of time units (e.g., 1, 30)',
148
+ required: true,
149
+ }),
150
+ period: Property.StaticDropdown({
151
+ displayName: 'Time Period',
152
+ required: true,
153
+ options: {
154
+ options: [
155
+ { label: 'Days', value: 'days' },
156
+ { label: 'Weeks', value: 'weeks' },
157
+ ],
158
+ },
159
+ }),
160
+ },
161
+ }),
162
+ };
163
+ } else {
164
+ return {};
165
+ }
166
+ },
167
+ }),
168
+ venue: Property.ShortText({
169
+ displayName: 'Venue',
170
+ description: 'Location or venue of the event',
171
+ required: false,
172
+ }),
173
+ relatedModule: Property.StaticDropdown({
174
+ displayName: 'Related Module',
175
+ description: 'Select the type of entity the event is related to',
176
+ required: false,
177
+ defaultValue: 'Contacts',
178
+ options: {
179
+ options: [
180
+ { label: 'Contacts', value: 'Contacts' },
181
+ { label: 'Pipelines', value: 'Pipelines' },
182
+ { label: 'Companies', value: 'Companies' },
183
+ ],
184
+ },
185
+ }),
186
+ relatedTo: Property.Dropdown({
187
+ auth: biginAuth,
188
+ displayName: 'Related To',
189
+ description: 'Select the specific record the event is related to',
190
+ required: false,
191
+ refreshers: ['auth', 'relatedModule'],
192
+ defaultValue: {},
193
+ options: async ({ auth, relatedModule }): Promise<any> => {
194
+ if (!auth) return handleDropdownError('Please connect your account first');
195
+ if (!relatedModule) return { options: [] };
196
+
197
+ const { access_token, data } = auth;
198
+ const api_domain = data['api_domain'];
199
+
200
+ const fetchMap: Record<string, () => Promise<any>> = {
201
+ Contacts: () =>
202
+ biginApiService.fetchContacts(access_token, api_domain),
203
+ Pipelines: () =>
204
+ biginApiService.fetchPipelinesRecords(access_token, api_domain),
205
+ Companies: () =>
206
+ biginApiService.fetchCompanies(access_token, api_domain),
207
+ };
208
+
209
+ const fetchFn =
210
+ fetchMap[(relatedModule as keyof typeof fetchMap) || 'Contacts'];
211
+ const response = await fetchFn();
212
+ const records = response?.data || [];
213
+
214
+ return {
215
+ options: records.map((item: any) => ({
216
+ label: getSafeLabel(item),
217
+ value: item.id,
218
+ })),
219
+ };
220
+ },
221
+ }),
222
+ participants: Property.Array({
223
+ displayName: 'Participants',
224
+ description: 'Add participants to the event',
225
+ required: false,
226
+ properties: {
227
+ type: Property.StaticDropdown({
228
+ displayName: 'Participant Type',
229
+ required: true,
230
+ options: {
231
+ options: [
232
+ { label: 'User', value: 'user' },
233
+ { label: 'Email', value: 'email' },
234
+ { label: 'Contact', value: 'contact' },
235
+ ],
236
+ },
237
+ }),
238
+ participant: Property.ShortText({
239
+ displayName: 'Participant ID/Email',
240
+ description: 'User ID, email address, or contact ID based on type',
241
+ required: true,
242
+ }),
243
+ },
244
+ }),
245
+ description: Property.LongText({
246
+ displayName: 'Description',
247
+ description: 'Additional descriptions or notes related to the event',
248
+ required: false,
249
+ }),
250
+ tag: tagsDropdown('Events'),
251
+ },
252
+ async run({ auth, propsValue }) {
253
+ const { access_token, data } = auth;
254
+ const api_domain = data['api_domain'];
255
+ const startDate = new Date(propsValue.startDateTime);
256
+ const endDate = new Date(propsValue.endDateTime);
257
+
258
+ if (endDate <= startDate) {
259
+ throw new Error('End date/time must be after start date/time');
260
+ }
261
+
262
+ const eventData: any = {
263
+ Event_Title: propsValue.eventTitle,
264
+ Start_DateTime: formatDateTime(propsValue.startDateTime),
265
+ End_DateTime: formatDateTime(propsValue.endDateTime),
266
+ };
267
+
268
+ if (propsValue.owner) {
269
+ eventData.Owner = { id: propsValue.owner };
270
+ }
271
+
272
+ if (propsValue.allDay) {
273
+ eventData.All_day = propsValue.allDay;
274
+ }
275
+
276
+ if (propsValue.enableRecurring && propsValue.recurringInfo) {
277
+ const recurringInfo = propsValue.recurringInfo as any;
278
+ const rruleParts: string[] = [];
279
+
280
+ const allowedFreq = ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'];
281
+ if (!allowedFreq.includes(recurringInfo.freq)) {
282
+ throw new Error('Invalid recurrence frequency. Allowed values: DAILY, WEEKLY, MONTHLY, YEARLY');
283
+ }
284
+ rruleParts.push(`FREQ=${recurringInfo.freq}`);
285
+
286
+ if (recurringInfo.interval !== undefined) {
287
+ const interval = Number(recurringInfo.interval);
288
+ if (Number.isNaN(interval) || interval < 1 || interval > 99) {
289
+ throw new Error('Interval must be a number between 1 and 99');
290
+ }
291
+ rruleParts.push(`INTERVAL=${recurringInfo.interval}`);
292
+ }
293
+
294
+ if (recurringInfo.count !== undefined) {
295
+ const count = Number(recurringInfo.count);
296
+ if (Number.isNaN(count) || count < 1 || count > 99) {
297
+ throw new Error('Count must be a number between 1 and 99');
298
+ }
299
+ rruleParts.push(`COUNT=${recurringInfo.count}`);
300
+ }
301
+
302
+ if (recurringInfo.byday) {
303
+ rruleParts.push(`BYDAY=${recurringInfo.byday}`);
304
+ }
305
+
306
+ if (recurringInfo.bymonthday !== undefined) {
307
+ const bymonthday = Number(recurringInfo.bymonthday);
308
+ if (Number.isNaN(bymonthday) || bymonthday < 1 || bymonthday > 31) {
309
+ throw new Error('BYMONTHDAY must be a number between 1 and 31');
310
+ }
311
+ rruleParts.push(`BYMONTHDAY=${recurringInfo.bymonthday}`);
312
+ }
313
+
314
+ if (recurringInfo.bysetpos) {
315
+ const allowedSetPos = ['1', '2', '3', '4', '-1'];
316
+ if (!allowedSetPos.includes(String(recurringInfo.bysetpos))) {
317
+ throw new Error('BYSETPOS must be one of 1, 2, 3, 4, -1');
318
+ }
319
+ rruleParts.push(`BYSETPOS=${recurringInfo.bysetpos}`);
320
+ }
321
+
322
+ if (recurringInfo.until) {
323
+ const until = formatDateOnly(recurringInfo.until);
324
+ rruleParts.push(`UNTIL=${until}`);
325
+ }
326
+
327
+ eventData.Recurring_Activity = {
328
+ RRULE: rruleParts.join(';') + ';',
329
+ };
330
+ }
331
+
332
+ if (propsValue.enableReminder && propsValue.reminderInfo) {
333
+ const reminderList = propsValue.reminderInfo['reminderList'] as any[];
334
+ eventData.Remind_At = reminderList.map((reminder: any) => ({
335
+ unit: reminder.unit,
336
+ period: reminder.period,
337
+ }));
338
+ }
339
+
340
+ if (propsValue.venue) {
341
+ eventData.Venue = propsValue.venue;
342
+ }
343
+
344
+ if (propsValue.relatedTo && propsValue.relatedModule) {
345
+ const relatedModuleMap = {
346
+ Contacts: 'Contacts',
347
+ Pipelines: 'Deals',
348
+ Companies: 'Accounts',
349
+ };
350
+
351
+ const relatedModule =
352
+ relatedModuleMap[
353
+ propsValue.relatedModule as keyof typeof relatedModuleMap
354
+ ];
355
+
356
+ eventData.Related_To = { id: propsValue.relatedTo };
357
+ eventData.$related_module = relatedModule;
358
+ }
359
+
360
+ if (propsValue.participants && Array.isArray(propsValue.participants)) {
361
+ eventData.Participants = propsValue.participants.map(
362
+ (participant: any) => ({
363
+ type: participant.type,
364
+ participant: participant.participant,
365
+ })
366
+ );
367
+ }
368
+
369
+ if (propsValue.description) {
370
+ eventData.Description = propsValue.description;
371
+ }
372
+
373
+ if (
374
+ propsValue.tag &&
375
+ Array.isArray(propsValue.tag) &&
376
+ propsValue.tag.length > 0
377
+ ) {
378
+ eventData.Tag = propsValue.tag.map((tagName) => ({ name: tagName }));
379
+ }
380
+
381
+ const payload = { data: [eventData] };
382
+
383
+ try {
384
+ const response = await biginApiService.createEvent(
385
+ access_token,
386
+ api_domain,
387
+ payload
388
+ );
389
+ return response.data[0];
390
+ } catch (error) {
391
+ console.error('Error creating event:', error);
392
+ throw new Error(
393
+ error instanceof Error
394
+ ? `Failed to create event: ${error.message}`
395
+ : 'Failed to create event due to an unknown error'
396
+ );
397
+ }
398
+ },
399
+ });