etl-integrations 0.1.81

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +34 -0
  4. data/.ruby-version +1 -0
  5. data/.vscode/settings.json +5 -0
  6. data/CHANGELOG.md +38 -0
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +105 -0
  10. data/Rakefile +12 -0
  11. data/lib/multiwoven/integrations/config.rb +13 -0
  12. data/lib/multiwoven/integrations/core/base_connector.rb +70 -0
  13. data/lib/multiwoven/integrations/core/constants.rb +46 -0
  14. data/lib/multiwoven/integrations/core/destination_connector.rb +14 -0
  15. data/lib/multiwoven/integrations/core/fullrefresher.rb +19 -0
  16. data/lib/multiwoven/integrations/core/http_client.rb +34 -0
  17. data/lib/multiwoven/integrations/core/query_builder.rb +27 -0
  18. data/lib/multiwoven/integrations/core/rate_limiter.rb +19 -0
  19. data/lib/multiwoven/integrations/core/source_connector.rb +38 -0
  20. data/lib/multiwoven/integrations/core/utils.rb +104 -0
  21. data/lib/multiwoven/integrations/destination/airtable/client.rb +153 -0
  22. data/lib/multiwoven/integrations/destination/airtable/config/catalog.json +6 -0
  23. data/lib/multiwoven/integrations/destination/airtable/config/meta.json +15 -0
  24. data/lib/multiwoven/integrations/destination/airtable/config/spec.json +22 -0
  25. data/lib/multiwoven/integrations/destination/airtable/icon.svg +6 -0
  26. data/lib/multiwoven/integrations/destination/airtable/schema_helper.rb +141 -0
  27. data/lib/multiwoven/integrations/destination/facebook_custom_audience/client.rb +124 -0
  28. data/lib/multiwoven/integrations/destination/facebook_custom_audience/config/catalog.json +42 -0
  29. data/lib/multiwoven/integrations/destination/facebook_custom_audience/config/meta.json +15 -0
  30. data/lib/multiwoven/integrations/destination/facebook_custom_audience/config/spec.json +27 -0
  31. data/lib/multiwoven/integrations/destination/facebook_custom_audience/icon.svg +23 -0
  32. data/lib/multiwoven/integrations/destination/google_sheets/client.rb +231 -0
  33. data/lib/multiwoven/integrations/destination/google_sheets/config/catalog.json +6 -0
  34. data/lib/multiwoven/integrations/destination/google_sheets/config/meta.json +15 -0
  35. data/lib/multiwoven/integrations/destination/google_sheets/config/spec.json +74 -0
  36. data/lib/multiwoven/integrations/destination/google_sheets/icon.svg +1 -0
  37. data/lib/multiwoven/integrations/destination/hubspot/client.rb +107 -0
  38. data/lib/multiwoven/integrations/destination/hubspot/config/catalog.json +351 -0
  39. data/lib/multiwoven/integrations/destination/hubspot/config/meta.json +15 -0
  40. data/lib/multiwoven/integrations/destination/hubspot/config/spec.json +17 -0
  41. data/lib/multiwoven/integrations/destination/hubspot/icon.svg +5 -0
  42. data/lib/multiwoven/integrations/destination/klaviyo/client.rb +116 -0
  43. data/lib/multiwoven/integrations/destination/klaviyo/config/catalog.json +103 -0
  44. data/lib/multiwoven/integrations/destination/klaviyo/config/meta.json +15 -0
  45. data/lib/multiwoven/integrations/destination/klaviyo/config/spec.json +22 -0
  46. data/lib/multiwoven/integrations/destination/klaviyo/icon.svg +6 -0
  47. data/lib/multiwoven/integrations/destination/postgresql/client.rb +123 -0
  48. data/lib/multiwoven/integrations/destination/postgresql/config/meta.json +15 -0
  49. data/lib/multiwoven/integrations/destination/postgresql/config/spec.json +68 -0
  50. data/lib/multiwoven/integrations/destination/postgresql/icon.svg +20 -0
  51. data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/client.rb +114 -0
  52. data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
  53. data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/config/meta.json +16 -0
  54. data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/config/spec.json +49 -0
  55. data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/icon.svg +16 -0
  56. data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/schema_helper.rb +132 -0
  57. data/lib/multiwoven/integrations/destination/salesforce_crm/client.rb +117 -0
  58. data/lib/multiwoven/integrations/destination/salesforce_crm/config/catalog.json +320 -0
  59. data/lib/multiwoven/integrations/destination/salesforce_crm/config/meta.json +15 -0
  60. data/lib/multiwoven/integrations/destination/salesforce_crm/config/spec.json +43 -0
  61. data/lib/multiwoven/integrations/destination/salesforce_crm/icon.svg +16 -0
  62. data/lib/multiwoven/integrations/destination/sftp/client.rb +133 -0
  63. data/lib/multiwoven/integrations/destination/sftp/config/catalog.json +16 -0
  64. data/lib/multiwoven/integrations/destination/sftp/config/meta.json +16 -0
  65. data/lib/multiwoven/integrations/destination/sftp/config/spec.json +50 -0
  66. data/lib/multiwoven/integrations/destination/sftp/icon.svg +1 -0
  67. data/lib/multiwoven/integrations/destination/slack/client.rb +114 -0
  68. data/lib/multiwoven/integrations/destination/slack/config/catalog.json +22 -0
  69. data/lib/multiwoven/integrations/destination/slack/config/meta.json +15 -0
  70. data/lib/multiwoven/integrations/destination/slack/config/spec.json +22 -0
  71. data/lib/multiwoven/integrations/destination/slack/icon.svg +26 -0
  72. data/lib/multiwoven/integrations/destination/stripe/client.rb +82 -0
  73. data/lib/multiwoven/integrations/destination/stripe/config/catalog.json +128 -0
  74. data/lib/multiwoven/integrations/destination/stripe/config/meta.json +15 -0
  75. data/lib/multiwoven/integrations/destination/stripe/config/spec.json +17 -0
  76. data/lib/multiwoven/integrations/destination/stripe/icon.svg +10 -0
  77. data/lib/multiwoven/integrations/destination/tally/client.rb +151 -0
  78. data/lib/multiwoven/integrations/destination/tally/config/catalog.json +62 -0
  79. data/lib/multiwoven/integrations/destination/tally/config/meta.json +15 -0
  80. data/lib/multiwoven/integrations/destination/tally/config/spec.json +45 -0
  81. data/lib/multiwoven/integrations/destination/tally/icon.svg +7 -0
  82. data/lib/multiwoven/integrations/protocol/protocol.json +189 -0
  83. data/lib/multiwoven/integrations/protocol/protocol.rb +216 -0
  84. data/lib/multiwoven/integrations/rollout.rb +32 -0
  85. data/lib/multiwoven/integrations/service.rb +79 -0
  86. data/lib/multiwoven/integrations/source/bigquery/client.rb +98 -0
  87. data/lib/multiwoven/integrations/source/bigquery/config/meta.json +15 -0
  88. data/lib/multiwoven/integrations/source/bigquery/config/spec.json +82 -0
  89. data/lib/multiwoven/integrations/source/bigquery/icon.svg +1 -0
  90. data/lib/multiwoven/integrations/source/databricks/client.rb +98 -0
  91. data/lib/multiwoven/integrations/source/databricks/config/meta.json +16 -0
  92. data/lib/multiwoven/integrations/source/databricks/config/spec.json +56 -0
  93. data/lib/multiwoven/integrations/source/databricks/icon.svg +19 -0
  94. data/lib/multiwoven/integrations/source/postgresql/client.rb +109 -0
  95. data/lib/multiwoven/integrations/source/postgresql/config/meta.json +15 -0
  96. data/lib/multiwoven/integrations/source/postgresql/config/spec.json +69 -0
  97. data/lib/multiwoven/integrations/source/postgresql/icon.svg +20 -0
  98. data/lib/multiwoven/integrations/source/redshift/client.rb +109 -0
  99. data/lib/multiwoven/integrations/source/redshift/config/meta.json +15 -0
  100. data/lib/multiwoven/integrations/source/redshift/config/spec.json +71 -0
  101. data/lib/multiwoven/integrations/source/redshift/icon.svg +15 -0
  102. data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/client.rb +123 -0
  103. data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
  104. data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/config/meta.json +17 -0
  105. data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/config/spec.json +50 -0
  106. data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/icon.svg +16 -0
  107. data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/schema_helper.rb +130 -0
  108. data/lib/multiwoven/integrations/source/snowflake/client.rb +92 -0
  109. data/lib/multiwoven/integrations/source/snowflake/config/meta.json +15 -0
  110. data/lib/multiwoven/integrations/source/snowflake/config/spec.json +82 -0
  111. data/lib/multiwoven/integrations/source/snowflake/icon.svg +10 -0
  112. data/lib/multiwoven/integrations/source/zoho_books/client.rb +155 -0
  113. data/lib/multiwoven/integrations/source/zoho_books/config/meta.json +16 -0
  114. data/lib/multiwoven/integrations/source/zoho_books/config/spec.json +43 -0
  115. data/lib/multiwoven/integrations/source/zoho_books/icon.svg +16 -0
  116. data/lib/multiwoven/integrations.rb +71 -0
  117. data/multiwoven-integrations-0.1.68.gem +0 -0
  118. data/sig/multiwoven/integrations.rbs +6 -0
  119. metadata +515 -0
@@ -0,0 +1,351 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "streams": [
6
+ {
7
+ "name": "contacts",
8
+ "action": "create",
9
+ "json_schema": {
10
+ "$schema": "http://json-schema.org/draft-07/schema#",
11
+ "title": "HubSpot CRM",
12
+ "type": "object",
13
+ "required": ["email"],
14
+ "properties": {
15
+ "properties": {
16
+ "type": "object",
17
+ "properties": {
18
+ "email": {
19
+ "type": "string",
20
+ "format": "email",
21
+ "description": "The contact's email address."
22
+ },
23
+ "firstname": {
24
+ "type": "string",
25
+ "description": "The contact's first name."
26
+ },
27
+ "lastname": {
28
+ "type": "string",
29
+ "description": "The contact's last name."
30
+ },
31
+ "phone": {
32
+ "type": "string",
33
+ "description": "The contact's phone number."
34
+ },
35
+ "company": {
36
+ "type": "string",
37
+ "description": "The contact's company name."
38
+ },
39
+ "website": {
40
+ "type": "string",
41
+ "format": "uri",
42
+ "description": "The contact's website URL."
43
+ },
44
+ "lifecyclestage": {
45
+ "type": "string",
46
+ "description": "The contact's lifecycle stage."
47
+ }
48
+ },
49
+ "additionalProperties": {
50
+ "type": ["string", "number", "boolean"],
51
+ "description": "Allows for additional custom properties with basic data types."
52
+ }
53
+ },
54
+ "associations": {
55
+ "type": "array",
56
+ "description": "An array of associated objects for the contact.",
57
+ "items": {
58
+ "type": "object",
59
+ "properties": {
60
+ "to": {
61
+ "type": "object",
62
+ "required": ["id"],
63
+ "properties": {
64
+ "id": {
65
+ "type": "integer",
66
+ "description": "The unique identifier of the associated object."
67
+ }
68
+ }
69
+ },
70
+ "types": {
71
+ "type": "array",
72
+ "items": {
73
+ "type": "object",
74
+ "required": ["associationCategory", "associationTypeId"],
75
+ "properties": {
76
+ "associationCategory": {
77
+ "type": "string",
78
+ "description": "The category of the association.",
79
+ "enum": [
80
+ "HUBSPOT_DEFINED",
81
+ "USER_DEFINED",
82
+ "INTEGRATOR_DEFINED"
83
+ ]
84
+ },
85
+ "associationTypeId": {
86
+ "type": "integer",
87
+ "description": "The unique identifier of the association type."
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ },
97
+ "supported_sync_modes": ["incremental"],
98
+ "source_defined_cursor": true,
99
+ "default_cursor_field": ["updated"]
100
+ },
101
+ {
102
+ "name": "companies",
103
+ "action": "create",
104
+ "json_schema": {
105
+ "$schema": "http://json-schema.org/draft-07/schema#",
106
+ "type": "object",
107
+ "properties": {
108
+ "inputs": {
109
+ "type": "array",
110
+ "items": {
111
+ "type": "object",
112
+ "properties": {
113
+ "associations": {
114
+ "type": "array",
115
+ "items": {
116
+ "type": "object",
117
+ "properties": {
118
+ "types": {
119
+ "type": "array",
120
+ "items": {
121
+ "type": "object",
122
+ "properties": {
123
+ "associationCategory": {
124
+ "type": "string",
125
+ "enum": [
126
+ "HUBSPOT_DEFINED",
127
+ "USER_DEFINED",
128
+ "INTEGRATOR_DEFINED"
129
+ ]
130
+ },
131
+ "associationTypeId": {
132
+ "type": "integer"
133
+ }
134
+ }
135
+ }
136
+ },
137
+ "to": {
138
+ "type": "object",
139
+ "properties": {
140
+ "id": {
141
+ "type": "string"
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ },
148
+ "properties": {
149
+ "type": "object",
150
+ "properties": {
151
+ "city": {
152
+ "type": "string"
153
+ },
154
+ "name": {
155
+ "type": "string"
156
+ },
157
+ "phone": {
158
+ "type": "string"
159
+ },
160
+ "state": {
161
+ "type": "string"
162
+ },
163
+ "domain": {
164
+ "type": "string"
165
+ },
166
+ "industry": {
167
+ "type": "string"
168
+ }
169
+ },
170
+ "required": ["name", "domain"]
171
+ }
172
+ },
173
+ "required": ["properties"]
174
+ }
175
+ }
176
+ },
177
+ "required": ["inputs"]
178
+ },
179
+ "supported_sync_modes": [ "incremental"],
180
+ "source_defined_cursor": true,
181
+ "default_cursor_field": ["updated"]
182
+ },
183
+ {
184
+ "name": "deals",
185
+ "action": "create",
186
+ "json_schema": {
187
+ "$schema": "http://json-schema.org/draft-07/schema#",
188
+ "type": "object",
189
+ "properties": {
190
+ "properties": {
191
+ "type": "object",
192
+ "properties": {
193
+ "amount": {
194
+ "type": "string",
195
+ "pattern": "^[0-9]+(\\.[0-9]{1,2})?$"
196
+ },
197
+ "closedate": {
198
+ "type": "string",
199
+ "format": "date-time"
200
+ },
201
+ "dealname": {
202
+ "type": "string"
203
+ },
204
+ "pipeline": {
205
+ "type": "string"
206
+ },
207
+ "dealstage": {
208
+ "type": "string",
209
+ "enum": [
210
+ "appointmentscheduled",
211
+ "qualifiedtobuy",
212
+ "presentationscheduled",
213
+ "decisionmakerboughtin",
214
+ "contractsent",
215
+ "closedwon",
216
+ "closedlost"
217
+ ]
218
+ },
219
+ "hubspot_owner_id": {
220
+ "type": "string",
221
+ "pattern": "^[0-9]+$"
222
+ }
223
+ },
224
+ "required": ["dealname", "pipeline", "dealstage"]
225
+ },
226
+ "associations": {
227
+ "type": "array",
228
+ "items": {
229
+ "type": "object",
230
+ "properties": {
231
+ "to": {
232
+ "type": "object",
233
+ "properties": {
234
+ "id": {
235
+ "type": "integer"
236
+ }
237
+ },
238
+ "required": ["id"]
239
+ },
240
+ "types": {
241
+ "type": "array",
242
+ "items": {
243
+ "type": "object",
244
+ "properties": {
245
+ "associationCategory": {
246
+ "type": "string",
247
+ "enum": [
248
+ "HUBSPOT_DEFINED",
249
+ "USER_DEFINED",
250
+ "INTEGRATOR_DEFINED"
251
+ ]
252
+ },
253
+ "associationTypeId": {
254
+ "type": "integer"
255
+ }
256
+ },
257
+ "required": ["associationCategory", "associationTypeId"]
258
+ }
259
+ }
260
+ },
261
+ "required": ["to", "types"]
262
+ }
263
+ }
264
+ },
265
+ "required": ["properties"]
266
+ },
267
+ "supported_sync_modes": ["incremental"],
268
+ "source_defined_cursor": true,
269
+ "default_cursor_field": ["updated"]
270
+ },
271
+ {
272
+ "name": "line_items",
273
+ "action": "create",
274
+ "json_schema": {
275
+ "$schema": "http://json-schema.org/draft-07/schema#",
276
+ "type": "object",
277
+ "properties": {
278
+ "properties": {
279
+ "type": "object",
280
+ "properties": {
281
+ "name": {
282
+ "type": "string"
283
+ },
284
+ "price": {
285
+ "type": "string",
286
+ "pattern": "^[0-9]+(\\.[0-9]{1,2})?$"
287
+ },
288
+ "quantity": {
289
+ "type": "string",
290
+ "pattern": "^[0-9]+$"
291
+ },
292
+ "hs_product_id": {
293
+ "type": "string",
294
+ "pattern": "^[0-9]+$"
295
+ },
296
+ "recurringbillingfrequency": {
297
+ "type": "string"
298
+ },
299
+ "hs_recurring_billing_period": {
300
+ "type": "string"
301
+ }
302
+ },
303
+ "required": ["name", "price"]
304
+ },
305
+ "associations": {
306
+ "type": "array",
307
+ "items": {
308
+ "type": "object",
309
+ "properties": {
310
+ "to": {
311
+ "type": "object",
312
+ "properties": {
313
+ "id": {
314
+ "type": "integer"
315
+ }
316
+ },
317
+ "required": ["id"]
318
+ },
319
+ "types": {
320
+ "type": "array",
321
+ "items": {
322
+ "type": "object",
323
+ "properties": {
324
+ "associationCategory": {
325
+ "type": "string",
326
+ "enum": [
327
+ "HUBSPOT_DEFINED",
328
+ "USER_DEFINED",
329
+ "INTEGRATOR_DEFINED"
330
+ ]
331
+ },
332
+ "associationTypeId": {
333
+ "type": "integer"
334
+ }
335
+ },
336
+ "required": ["associationCategory", "associationTypeId"]
337
+ }
338
+ }
339
+ },
340
+ "required": ["to", "types"]
341
+ }
342
+ }
343
+ },
344
+ "required": ["properties", "associations"]
345
+ },
346
+ "supported_sync_modes": ["incremental"],
347
+ "source_defined_cursor": true,
348
+ "default_cursor_field": ["updated"]
349
+ }
350
+ ]
351
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "Hubspot",
4
+ "title": "HubSpot CRM",
5
+ "connector_type": "destination",
6
+ "category": "CRM",
7
+ "documentation_url": "https://docs.multiwoven.com/destinations/crm/hubspot",
8
+ "github_issue_label": "destination-hubspot-crm",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "multiwoven"]
14
+ }
15
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "documentation_url": "https://docs.multiwoven.com/destinations/crm/hubspot",
3
+ "stream_type": "static",
4
+ "connection_specification": {
5
+ "$schema": "http://json-schema.org/draft-07/schema#",
6
+ "title": "HubSpot CRM",
7
+ "type": "object",
8
+ "required": ["access_token"],
9
+ "properties": {
10
+ "access_token": {
11
+ "type": "string",
12
+ "title": "Access Token",
13
+ "order": 0
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
2
+ <svg width="800px" height="800px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
3
+ <circle cx="512" cy="512" r="512" style="fill:#ff7a59"/>
4
+ <path d="M623.8 624.94c-38.23 0-69.24-30.67-69.24-68.51s31-68.52 69.24-68.52 69.26 30.67 69.26 68.52-31 68.51-69.26 68.51m20.74-200.42v-61a46.83 46.83 0 0 0 27.33-42.29v-1.41c0-25.78-21.32-46.86-47.35-46.86h-1.43c-26 0-47.35 21.09-47.35 46.86v1.41a46.85 46.85 0 0 0 27.33 42.29v61a135.08 135.08 0 0 0-63.86 27.79l-169.1-130.17A52.49 52.49 0 0 0 372 309c0-29.21-23.89-52.92-53.4-53s-53.45 23.59-53.48 52.81 23.85 52.88 53.36 52.93a53.29 53.29 0 0 0 26.33-7.09l166.38 128.1a132.14 132.14 0 0 0 2.07 150.3l-50.62 50.1A43.42 43.42 0 1 0 450.1 768c24.24 0 43.9-19.46 43.9-43.45a42.24 42.24 0 0 0-2-12.42l50-49.52a135.28 135.28 0 0 0 81.8 27.47c74.61 0 135.06-59.83 135.06-133.65 0-66.82-49.62-122-114.33-131.91" style="fill:#ffffff;fill-rule:evenodd"/>
5
+ </svg>
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven::Integrations::Destination
4
+ module Klaviyo
5
+ include Multiwoven::Integrations::Core
6
+ class Client < DestinationConnector
7
+ prepend Multiwoven::Integrations::Core::RateLimiter
8
+ def check_connection(connection_config)
9
+ connection_config = connection_config.with_indifferent_access
10
+ api_key = connection_config[:private_api_key]
11
+
12
+ response = Multiwoven::Integrations::Core::HttpClient.request(
13
+ KLAVIYO_AUTH_ENDPOINT,
14
+ HTTP_POST,
15
+ payload: KLAVIYO_AUTH_PAYLOAD,
16
+ headers: auth_headers(api_key)
17
+ )
18
+ parse_response(response)
19
+ end
20
+
21
+ def discover(_connection_config = nil)
22
+ catalog_json = read_json(CATALOG_SPEC_PATH)
23
+
24
+ catalog = build_catalog(catalog_json)
25
+
26
+ catalog.to_multiwoven_message
27
+ rescue StandardError => e
28
+ handle_exception(
29
+ "KLAVIYO:DISCOVER:EXCEPTION",
30
+ "error",
31
+ e
32
+ )
33
+ end
34
+
35
+ def write(sync_config, records, _action = "insert")
36
+ connection_config = sync_config.destination.connection_specification.with_indifferent_access
37
+ connection_config = connection_config.with_indifferent_access
38
+ url = sync_config.stream.url
39
+
40
+ request_method = sync_config.stream.request_method
41
+
42
+ write_success = 0
43
+ write_failure = 0
44
+ records.each do |record|
45
+ # pre process payload
46
+ # Add hardcode values into payload
47
+ record["data"] ||= {}
48
+ record["data"]["type"] = sync_config.stream.name
49
+
50
+ response = Multiwoven::Integrations::Core::HttpClient.request(
51
+ url,
52
+ request_method,
53
+ payload: record,
54
+ headers: auth_headers(connection_config["private_api_key"])
55
+ )
56
+ if success?(response)
57
+ write_success += 1
58
+ else
59
+ write_failure += 1
60
+ end
61
+ rescue StandardError => e
62
+ logger.error(
63
+ "KLAVIYO:RECORD:WRITE:FAILURE: #{e.message}"
64
+ )
65
+ write_failure += 1
66
+ end
67
+ tracker = Multiwoven::Integrations::Protocol::TrackingMessage.new(
68
+ success: write_success,
69
+ failed: write_failure
70
+ )
71
+ tracker.to_multiwoven_message
72
+ rescue StandardError => e
73
+ # TODO: Handle rate limiting seperately
74
+ handle_exception(
75
+ "KLAVIYO:WRITE:EXCEPTION",
76
+ "error",
77
+ e
78
+ )
79
+ end
80
+
81
+ private
82
+
83
+ def parse_response(response)
84
+ if success?(response)
85
+ ConnectionStatus.new(
86
+ status: ConnectionStatusType["succeeded"]
87
+ ).to_multiwoven_message
88
+ else
89
+ message = extract_message(response)
90
+ ConnectionStatus.new(
91
+ status: ConnectionStatusType["failed"], message: message
92
+ ).to_multiwoven_message
93
+ end
94
+ end
95
+
96
+ def success?(response)
97
+ response && %w[200 201].include?(response.code)
98
+ end
99
+
100
+ def extract_message(response)
101
+ JSON.parse(response.body)["message"]
102
+ rescue StandardError => e
103
+ "Klaviyo auth failed: #{e.message}"
104
+ end
105
+
106
+ def auth_headers(api_key)
107
+ {
108
+ "Accept" => "application/json",
109
+ "Authorization" => "Klaviyo-API-Key #{api_key}",
110
+ "Revision" => "2023-02-22",
111
+ "Content-Type" => "application/json"
112
+ }
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,103 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "streams": [
6
+ {
7
+ "name": "profile",
8
+ "action": "create",
9
+ "url": "https://a.klaviyo.com/api/profiles",
10
+ "method": "POST",
11
+ "json_schema": {
12
+ "$schema": "http://json-schema.org/draft-07/schema#",
13
+ "type": "object",
14
+ "properties": {
15
+ "data": {
16
+ "type": "object",
17
+ "properties": {
18
+ "type": {
19
+ "type": "string",
20
+ "enum": ["profile"]
21
+ },
22
+ "attributes": {
23
+ "type": "object",
24
+ "properties": {
25
+ "email": {
26
+ "type": "string",
27
+ "format": "email"
28
+ },
29
+ "phone_number": {
30
+ "type": "string"
31
+ },
32
+ "external_id": {
33
+ "type": "string",
34
+ "format": "uuid"
35
+ },
36
+ "first_name": {
37
+ "type": "string"
38
+ },
39
+ "last_name": {
40
+ "type": "string"
41
+ },
42
+ "organization": {
43
+ "type": "string"
44
+ },
45
+ "title": {
46
+ "type": "string"
47
+ },
48
+ "image": {
49
+ "type": "string",
50
+ "format": "uri"
51
+ },
52
+ "location": {
53
+ "type": "object",
54
+ "properties": {
55
+ "address1": {
56
+ "type": "string"
57
+ },
58
+ "address2": {
59
+ "type": "string"
60
+ },
61
+ "city": {
62
+ "type": "string"
63
+ },
64
+ "country": {
65
+ "type": "string"
66
+ },
67
+ "region": {
68
+ "type": "string"
69
+ },
70
+ "zip": {
71
+ "type": "string"
72
+ },
73
+ "timezone": {
74
+ "type": "string"
75
+ },
76
+ "ip": {
77
+ "type": "string",
78
+ "format": "ipv4"
79
+ }
80
+ }
81
+ },
82
+ "properties": {
83
+ "type": "object",
84
+ "additionalProperties": {
85
+ "type": "string"
86
+ }
87
+ }
88
+ },
89
+ "required": ["email", "phone_number"]
90
+ }
91
+ },
92
+ "required": ["type", "attributes"]
93
+ }
94
+ },
95
+ "required": ["data"]
96
+ },
97
+ "supported_sync_modes": ["incremental"],
98
+ "source_defined_cursor": true,
99
+ "default_cursor_field": ["updated"],
100
+ "source_defined_primary_key": [["id", "email"]]
101
+ }
102
+ ]
103
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "Klaviyo",
4
+ "title": "Klaviyo",
5
+ "connector_type": "destination",
6
+ "category": "Marketing Automation",
7
+ "documentation_url": "https://docs.mutliwoven.com",
8
+ "github_issue_label": "destination-klaviyo",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "multiwoven"]
14
+ }
15
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "documentation_url": "https://docs.multiwoven.com/integrations/destination/klaviyo",
3
+ "stream_type": "static",
4
+ "connection_specification": {
5
+ "$schema": "http://json-schema.org/draft-07/schema#",
6
+ "title": "Klaviyo",
7
+ "type": "object",
8
+ "required": ["public_api_key", "private_api_key"],
9
+ "properties": {
10
+ "public_api_key": {
11
+ "type": "string",
12
+ "title": "Public API Key",
13
+ "order": 0
14
+ },
15
+ "private_api_key": {
16
+ "type": "string",
17
+ "title": "Private API Key",
18
+ "order": 1
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,6 @@
1
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 67.8 45.4" style="enable-background:new 0 0 67.8 45.4;" xml:space="preserve">
2
+ <g>
3
+ <path d="M67.8,45.4H0V0h67.8L53.6,22.7L67.8,45.4L67.8,45.4z">
4
+ </path>
5
+ </g>
6
+ </svg>