etl-integrations 0.1.81
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +34 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +5 -0
- data/CHANGELOG.md +38 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +105 -0
- data/Rakefile +12 -0
- data/lib/multiwoven/integrations/config.rb +13 -0
- data/lib/multiwoven/integrations/core/base_connector.rb +70 -0
- data/lib/multiwoven/integrations/core/constants.rb +46 -0
- data/lib/multiwoven/integrations/core/destination_connector.rb +14 -0
- data/lib/multiwoven/integrations/core/fullrefresher.rb +19 -0
- data/lib/multiwoven/integrations/core/http_client.rb +34 -0
- data/lib/multiwoven/integrations/core/query_builder.rb +27 -0
- data/lib/multiwoven/integrations/core/rate_limiter.rb +19 -0
- data/lib/multiwoven/integrations/core/source_connector.rb +38 -0
- data/lib/multiwoven/integrations/core/utils.rb +104 -0
- data/lib/multiwoven/integrations/destination/airtable/client.rb +153 -0
- data/lib/multiwoven/integrations/destination/airtable/config/catalog.json +6 -0
- data/lib/multiwoven/integrations/destination/airtable/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/airtable/config/spec.json +22 -0
- data/lib/multiwoven/integrations/destination/airtable/icon.svg +6 -0
- data/lib/multiwoven/integrations/destination/airtable/schema_helper.rb +141 -0
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/client.rb +124 -0
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/config/catalog.json +42 -0
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/config/spec.json +27 -0
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/icon.svg +23 -0
- data/lib/multiwoven/integrations/destination/google_sheets/client.rb +231 -0
- data/lib/multiwoven/integrations/destination/google_sheets/config/catalog.json +6 -0
- data/lib/multiwoven/integrations/destination/google_sheets/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/google_sheets/config/spec.json +74 -0
- data/lib/multiwoven/integrations/destination/google_sheets/icon.svg +1 -0
- data/lib/multiwoven/integrations/destination/hubspot/client.rb +107 -0
- data/lib/multiwoven/integrations/destination/hubspot/config/catalog.json +351 -0
- data/lib/multiwoven/integrations/destination/hubspot/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/hubspot/config/spec.json +17 -0
- data/lib/multiwoven/integrations/destination/hubspot/icon.svg +5 -0
- data/lib/multiwoven/integrations/destination/klaviyo/client.rb +116 -0
- data/lib/multiwoven/integrations/destination/klaviyo/config/catalog.json +103 -0
- data/lib/multiwoven/integrations/destination/klaviyo/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/klaviyo/config/spec.json +22 -0
- data/lib/multiwoven/integrations/destination/klaviyo/icon.svg +6 -0
- data/lib/multiwoven/integrations/destination/postgresql/client.rb +123 -0
- data/lib/multiwoven/integrations/destination/postgresql/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/postgresql/config/spec.json +68 -0
- data/lib/multiwoven/integrations/destination/postgresql/icon.svg +20 -0
- data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/client.rb +114 -0
- data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
- data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/config/meta.json +16 -0
- data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/config/spec.json +49 -0
- data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/icon.svg +16 -0
- data/lib/multiwoven/integrations/destination/salesforce_consumer_goods_cloud/schema_helper.rb +132 -0
- data/lib/multiwoven/integrations/destination/salesforce_crm/client.rb +117 -0
- data/lib/multiwoven/integrations/destination/salesforce_crm/config/catalog.json +320 -0
- data/lib/multiwoven/integrations/destination/salesforce_crm/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/salesforce_crm/config/spec.json +43 -0
- data/lib/multiwoven/integrations/destination/salesforce_crm/icon.svg +16 -0
- data/lib/multiwoven/integrations/destination/sftp/client.rb +133 -0
- data/lib/multiwoven/integrations/destination/sftp/config/catalog.json +16 -0
- data/lib/multiwoven/integrations/destination/sftp/config/meta.json +16 -0
- data/lib/multiwoven/integrations/destination/sftp/config/spec.json +50 -0
- data/lib/multiwoven/integrations/destination/sftp/icon.svg +1 -0
- data/lib/multiwoven/integrations/destination/slack/client.rb +114 -0
- data/lib/multiwoven/integrations/destination/slack/config/catalog.json +22 -0
- data/lib/multiwoven/integrations/destination/slack/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/slack/config/spec.json +22 -0
- data/lib/multiwoven/integrations/destination/slack/icon.svg +26 -0
- data/lib/multiwoven/integrations/destination/stripe/client.rb +82 -0
- data/lib/multiwoven/integrations/destination/stripe/config/catalog.json +128 -0
- data/lib/multiwoven/integrations/destination/stripe/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/stripe/config/spec.json +17 -0
- data/lib/multiwoven/integrations/destination/stripe/icon.svg +10 -0
- data/lib/multiwoven/integrations/destination/tally/client.rb +151 -0
- data/lib/multiwoven/integrations/destination/tally/config/catalog.json +62 -0
- data/lib/multiwoven/integrations/destination/tally/config/meta.json +15 -0
- data/lib/multiwoven/integrations/destination/tally/config/spec.json +45 -0
- data/lib/multiwoven/integrations/destination/tally/icon.svg +7 -0
- data/lib/multiwoven/integrations/protocol/protocol.json +189 -0
- data/lib/multiwoven/integrations/protocol/protocol.rb +216 -0
- data/lib/multiwoven/integrations/rollout.rb +32 -0
- data/lib/multiwoven/integrations/service.rb +79 -0
- data/lib/multiwoven/integrations/source/bigquery/client.rb +98 -0
- data/lib/multiwoven/integrations/source/bigquery/config/meta.json +15 -0
- data/lib/multiwoven/integrations/source/bigquery/config/spec.json +82 -0
- data/lib/multiwoven/integrations/source/bigquery/icon.svg +1 -0
- data/lib/multiwoven/integrations/source/databricks/client.rb +98 -0
- data/lib/multiwoven/integrations/source/databricks/config/meta.json +16 -0
- data/lib/multiwoven/integrations/source/databricks/config/spec.json +56 -0
- data/lib/multiwoven/integrations/source/databricks/icon.svg +19 -0
- data/lib/multiwoven/integrations/source/postgresql/client.rb +109 -0
- data/lib/multiwoven/integrations/source/postgresql/config/meta.json +15 -0
- data/lib/multiwoven/integrations/source/postgresql/config/spec.json +69 -0
- data/lib/multiwoven/integrations/source/postgresql/icon.svg +20 -0
- data/lib/multiwoven/integrations/source/redshift/client.rb +109 -0
- data/lib/multiwoven/integrations/source/redshift/config/meta.json +15 -0
- data/lib/multiwoven/integrations/source/redshift/config/spec.json +71 -0
- data/lib/multiwoven/integrations/source/redshift/icon.svg +15 -0
- data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/client.rb +123 -0
- data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
- data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/config/meta.json +17 -0
- data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/config/spec.json +50 -0
- data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/icon.svg +16 -0
- data/lib/multiwoven/integrations/source/salesforce_consumer_goods_cloud/schema_helper.rb +130 -0
- data/lib/multiwoven/integrations/source/snowflake/client.rb +92 -0
- data/lib/multiwoven/integrations/source/snowflake/config/meta.json +15 -0
- data/lib/multiwoven/integrations/source/snowflake/config/spec.json +82 -0
- data/lib/multiwoven/integrations/source/snowflake/icon.svg +10 -0
- data/lib/multiwoven/integrations/source/zoho_books/client.rb +155 -0
- data/lib/multiwoven/integrations/source/zoho_books/config/meta.json +16 -0
- data/lib/multiwoven/integrations/source/zoho_books/config/spec.json +43 -0
- data/lib/multiwoven/integrations/source/zoho_books/icon.svg +16 -0
- data/lib/multiwoven/integrations.rb +71 -0
- data/multiwoven-integrations-0.1.68.gem +0 -0
- data/sig/multiwoven/integrations.rbs +6 -0
- metadata +515 -0
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Multiwoven
|
4
|
+
module Integrations
|
5
|
+
module Source
|
6
|
+
module SalesforceConsumerGoodsCloud
|
7
|
+
module SchemaHelper
|
8
|
+
include Core::Constants
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def salesforce_field_to_json_schema_type(sf_field) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
|
13
|
+
case sf_field["type"]
|
14
|
+
when "string", "Email", "Phone", "Text", "TextArea", "TextEncrypted", "URL", "Picklist (Single)"
|
15
|
+
if sf_field["nillable"]
|
16
|
+
{ "type": %w[string null] }
|
17
|
+
else
|
18
|
+
{ "type": "string" }
|
19
|
+
end
|
20
|
+
when "double", "Currency", "Percent"
|
21
|
+
if sf_field["nillable"]
|
22
|
+
{ "type": %w[number null] }
|
23
|
+
else
|
24
|
+
{ "type": "number" }
|
25
|
+
end
|
26
|
+
when "boolean", "Checkbox"
|
27
|
+
if sf_field["nillable"]
|
28
|
+
{ "type": %w[boolean null] }
|
29
|
+
else
|
30
|
+
{ "type": "boolean" }
|
31
|
+
end
|
32
|
+
when "int", "AutoNumber"
|
33
|
+
if sf_field["nillable"]
|
34
|
+
{ "type": %w[integer null] }
|
35
|
+
else
|
36
|
+
{ "type": "integer" }
|
37
|
+
end
|
38
|
+
when "date"
|
39
|
+
if sf_field["nillable"]
|
40
|
+
{ "type": %w[string null], "format": "date" }
|
41
|
+
else
|
42
|
+
{ "type": "string", "format": "date" }
|
43
|
+
end
|
44
|
+
when "datetime", "DateTime"
|
45
|
+
if sf_field["nillable"]
|
46
|
+
{ "type": %w[string null], "format": "date-time" }
|
47
|
+
else
|
48
|
+
{ "type": "string", "format": "date-time" }
|
49
|
+
end
|
50
|
+
when "time"
|
51
|
+
if sf_field["nillable"]
|
52
|
+
{ "type": %w[string null], "format": "time" }
|
53
|
+
else
|
54
|
+
{ "type": "string", "format": "time" }
|
55
|
+
end
|
56
|
+
when "textarea", "Text Area (Long)", "Text Area (Rich)"
|
57
|
+
if sf_field["nillable"]
|
58
|
+
{ "type": %w[string null] }
|
59
|
+
else
|
60
|
+
{ "type": "string" }
|
61
|
+
end
|
62
|
+
when "picklist", "multipicklist", "Picklist (Multi-select)"
|
63
|
+
if sf_field[:picklistValues] && sf_field["nillable"]
|
64
|
+
enum_values = sf_field[:picklistValues].map { |val| val["value"] }
|
65
|
+
{ "type": %w[string null], "items": { "type": "string" }, "enum": enum_values }
|
66
|
+
elsif sf_field[:picklistValues]
|
67
|
+
enum_values = sf_field[:picklistValues].map { |val| val["value"] }
|
68
|
+
{ "type": "string", "items": { "type": "string" }, "enum": enum_values }
|
69
|
+
else
|
70
|
+
{ "type": "string", "items": { "type": "string" } }
|
71
|
+
end
|
72
|
+
when "reference", "Reference (Lookup & Master-Detail)"
|
73
|
+
if sf_field["nillable"]
|
74
|
+
{ "type": %w[string null] }
|
75
|
+
else
|
76
|
+
{ "type": "string" }
|
77
|
+
end
|
78
|
+
when "location", "Geolocation"
|
79
|
+
if sf_field["nillable"]
|
80
|
+
{ "type": %w[object null], "properties": { "latitude": { "type": "number" }, "longitude": { "type": "number" } } }
|
81
|
+
else
|
82
|
+
{ "type": "object", "properties": { "latitude": { "type": "number" }, "longitude": { "type": "number" } } }
|
83
|
+
end
|
84
|
+
else
|
85
|
+
if sf_field["nillable"]
|
86
|
+
{ "type": %w[string null] }
|
87
|
+
else
|
88
|
+
{ "type": "string" }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def create_json_schema_for_object(metadata)
|
94
|
+
fields_schema = metadata["fields"].map do |field|
|
95
|
+
{
|
96
|
+
"#{field[:name]}": salesforce_field_to_json_schema_type(field)
|
97
|
+
}
|
98
|
+
end.reduce(:merge)
|
99
|
+
|
100
|
+
json_schema = {
|
101
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
102
|
+
"title": metadata["name"],
|
103
|
+
"type": "object",
|
104
|
+
"additionalProperties": true,
|
105
|
+
"properties": fields_schema
|
106
|
+
}
|
107
|
+
|
108
|
+
required = metadata["fields"].map do |field|
|
109
|
+
field["name"] if field["nillable"] == false
|
110
|
+
end.compact
|
111
|
+
primary_key = metadata["fields"].map do |field|
|
112
|
+
field["name"] if field["nillable"] == false && field["unique"] == true
|
113
|
+
end.compact
|
114
|
+
|
115
|
+
{
|
116
|
+
"name": metadata["name"],
|
117
|
+
"action": "create",
|
118
|
+
"json_schema": json_schema,
|
119
|
+
"required": required,
|
120
|
+
"supported_sync_modes": %w[incremental],
|
121
|
+
"source_defined_primary_key": [primary_key],
|
122
|
+
"source_defined_cursor": false,
|
123
|
+
"default_cursor_field": nil
|
124
|
+
}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Multiwoven::Integrations::Source
|
4
|
+
module Snowflake
|
5
|
+
include Multiwoven::Integrations::Core
|
6
|
+
class Client < SourceConnector
|
7
|
+
def check_connection(connection_config)
|
8
|
+
connection_config = connection_config.with_indifferent_access
|
9
|
+
create_connection(connection_config)
|
10
|
+
ConnectionStatus.new(status: ConnectionStatusType["succeeded"]).to_multiwoven_message
|
11
|
+
rescue Sequel::DatabaseConnectionError => e
|
12
|
+
ConnectionStatus.new(status: ConnectionStatusType["failed"], message: e.message).to_multiwoven_message
|
13
|
+
end
|
14
|
+
|
15
|
+
def discover(connection_config)
|
16
|
+
connection_config = connection_config.with_indifferent_access
|
17
|
+
query = "SELECT table_name, column_name, data_type, is_nullable
|
18
|
+
FROM information_schema.columns
|
19
|
+
WHERE table_schema = \'#{connection_config[:schema]}\' AND table_catalog = \'#{connection_config[:database]}\'
|
20
|
+
ORDER BY table_name, ordinal_position;"
|
21
|
+
|
22
|
+
db = create_connection(connection_config)
|
23
|
+
|
24
|
+
records = []
|
25
|
+
db.fetch(query.gsub("\n", "")) do |row|
|
26
|
+
records << row
|
27
|
+
end
|
28
|
+
catalog = Catalog.new(streams: create_streams(records))
|
29
|
+
catalog.to_multiwoven_message
|
30
|
+
rescue StandardError => e
|
31
|
+
handle_exception(
|
32
|
+
"SNOWFLAKE:DISCOVER:EXCEPTION",
|
33
|
+
"error",
|
34
|
+
e
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def read(sync_config)
|
39
|
+
connection_config = sync_config.source.connection_specification
|
40
|
+
connection_config = connection_config.with_indifferent_access
|
41
|
+
query = sync_config.model.query
|
42
|
+
query = batched_query(query, sync_config.limit, sync_config.offset) unless sync_config.limit.nil? && sync_config.offset.nil?
|
43
|
+
|
44
|
+
db = create_connection(connection_config)
|
45
|
+
|
46
|
+
query(db, query)
|
47
|
+
rescue StandardError => e
|
48
|
+
handle_exception(
|
49
|
+
"SNOWFLAKE:READ:EXCEPTION",
|
50
|
+
"error",
|
51
|
+
e
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def query(connection, query)
|
58
|
+
records = []
|
59
|
+
connection.fetch(query) do |row|
|
60
|
+
records << RecordMessage.new(data: row, emitted_at: Time.now.to_i).to_multiwoven_message
|
61
|
+
end
|
62
|
+
records
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_connection(connection_config)
|
66
|
+
raise "Unsupported Auth type" if connection_config[:credentials][:auth_type] != "username/password"
|
67
|
+
|
68
|
+
Sequel.odbc(drvconnect: generate_drvconnect(connection_config))
|
69
|
+
end
|
70
|
+
|
71
|
+
def generate_drvconnect(connection_config)
|
72
|
+
c = connection_config[:credentials]
|
73
|
+
"driver=#{SNOWFLAKE_DRIVER_PATH};server=#{connection_config[:host]};uid=#{c[:username]};pwd=#{c[:password]};schema=#{connection_config[:schema]};database=#{connection_config[:database]};warehouse=#{connection_config[:warehouse]};"
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_streams(records)
|
77
|
+
group_by_table(records).map do |r|
|
78
|
+
Multiwoven::Integrations::Protocol::Stream.new(name: r[:tablename], action: StreamAction["fetch"], json_schema: convert_to_json_schema(r[:columns]))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def group_by_table(records)
|
83
|
+
records.group_by { |entry| entry[:table_name] }.map do |table_name, columns|
|
84
|
+
{
|
85
|
+
tablename: table_name,
|
86
|
+
columns: columns.map { |column| { column_name: column[:column_name], type: column[:data_type], optional: column[:is_nullable] == "YES" } }
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"name": "Snowflake",
|
4
|
+
"title": "Snowflake",
|
5
|
+
"connector_type": "source",
|
6
|
+
"category": "Data Warehouse",
|
7
|
+
"documentation_url": "https://docs.mutliwoven.com",
|
8
|
+
"github_issue_label": "source-snowflake",
|
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,82 @@
|
|
1
|
+
{
|
2
|
+
"documentation_url": "https://docs.multiwoven.com/integrations/sources/snowflake",
|
3
|
+
"stream_type": "dynamic",
|
4
|
+
"connector_query_type": "raw_sql",
|
5
|
+
"connection_specification": {
|
6
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
7
|
+
"title": "Snowflake",
|
8
|
+
"type": "object",
|
9
|
+
"required": ["host", "role", "warehouse", "database"],
|
10
|
+
"properties": {
|
11
|
+
"credentials": {
|
12
|
+
"title": "",
|
13
|
+
"type": "object",
|
14
|
+
"required": ["auth_type", "username", "password"],
|
15
|
+
"properties": {
|
16
|
+
"auth_type": {
|
17
|
+
"type": "string",
|
18
|
+
"default": "username/password",
|
19
|
+
"order": 0,
|
20
|
+
"readOnly": true
|
21
|
+
},
|
22
|
+
"username": {
|
23
|
+
"description": "The username you created to allow multiwoven to access the database.",
|
24
|
+
"examples": ["MULTIWOVEN_USER"],
|
25
|
+
"type": "string",
|
26
|
+
"title": "Username",
|
27
|
+
"order": 1
|
28
|
+
},
|
29
|
+
"password": {
|
30
|
+
"description": "The password associated with the username.",
|
31
|
+
"type": "string",
|
32
|
+
"multiwoven_secret": true,
|
33
|
+
"title": "Password",
|
34
|
+
"order": 2
|
35
|
+
}
|
36
|
+
},
|
37
|
+
"order": 0
|
38
|
+
},
|
39
|
+
"host": {
|
40
|
+
"description": "The host domain of the snowflake instance (must include the account, region, cloud environment, and end with snowflakecomputing.com).",
|
41
|
+
"examples": ["accountname.us-east-2.aws.snowflakecomputing.com"],
|
42
|
+
"type": "string",
|
43
|
+
"title": "Account Name",
|
44
|
+
"order": 1
|
45
|
+
},
|
46
|
+
"role": {
|
47
|
+
"description": "The role you created for multiwoven to access Snowflake.",
|
48
|
+
"examples": ["MULTIWOVEN_ROLE"],
|
49
|
+
"type": "string",
|
50
|
+
"title": "Role",
|
51
|
+
"order": 2
|
52
|
+
},
|
53
|
+
"warehouse": {
|
54
|
+
"description": "The warehouse you created for multiwoven to access data.",
|
55
|
+
"examples": ["MULTIWOVEN_WAREHOUSE"],
|
56
|
+
"type": "string",
|
57
|
+
"title": "Warehouse",
|
58
|
+
"order": 3
|
59
|
+
},
|
60
|
+
"database": {
|
61
|
+
"description": "The database you created for multiwoven to access data.",
|
62
|
+
"examples": ["MULTIWOVEN_DATABASE"],
|
63
|
+
"type": "string",
|
64
|
+
"title": "Database",
|
65
|
+
"order": 4
|
66
|
+
},
|
67
|
+
"schema": {
|
68
|
+
"description": "The source Snowflake schema tables. Leave empty to access tables from multiple schemas.",
|
69
|
+
"examples": ["MULTIWOVEN_SCHEMA"],
|
70
|
+
"type": "string",
|
71
|
+
"title": "Schema",
|
72
|
+
"order": 5
|
73
|
+
},
|
74
|
+
"jdbc_url_params": {
|
75
|
+
"description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3).",
|
76
|
+
"title": "JDBC URL Params",
|
77
|
+
"type": "string",
|
78
|
+
"order": 6
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<svg viewBox="0 0 44 44" stroke="#249edc" fill="#249edc" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<path d="M37.2637465,33.128906 L28.0879655,27.828125 C26.7989025,27.085938 25.1504655,27.527344 24.4043715,28.816406 C24.1153085,29.324219 24.0020275,29.882812 24.0567155,30.425781 L24.0567155,40.785156 C24.0567155,42.265625 25.2598395,43.46875 26.7442155,43.46875 C28.2246835,43.46875 29.4278085,42.265625 29.4278085,40.785156 L29.4278085,34.828125 L34.5684335,37.796875 C35.8574965,38.542969 37.5098395,38.097656 38.2520275,36.808594 C38.9981215,35.519531 38.5567155,33.871094 37.2637465,33.128906" id="Path"></path>
|
4
|
+
<path d="M14.4434335,21.769531 C14.4590585,20.8125 13.9551525,19.921875 13.1270275,19.441406 L3.95124649,14.144531 C3.55280849,13.914062 3.09577749,13.792969 2.63874649,13.792969 C1.69733949,13.792969 0.822339495,14.296875 0.353589495,15.109375 C-0.372972505,16.367188 0.060621495,17.980469 1.31843349,18.707031 L6.60749649,21.757812 L1.31843349,24.8125 C0.709058495,25.164062 0.271558495,25.730469 0.091871495,26.410156 C-0.091722505,27.089844 0.00202749496,27.800781 0.353589495,28.410156 C0.822339495,29.222656 1.69733949,29.726562 2.63483949,29.726562 C3.09577749,29.726562 3.55280849,29.605469 3.95124649,29.375 L13.1270275,24.078125 C13.9473395,23.601562 14.4512465,22.71875 14.4434335,21.769531" id="Path2"></path>
|
5
|
+
<path d="M6.03327749,10.390625 L15.2090585,15.6875 C16.2793715,16.308594 17.5996835,16.105469 18.4434335,15.28125 C18.9785895,14.789062 19.3106215,14.085938 19.3106215,13.304688 L19.3106215,2.6875 C19.3106215,1.203125 18.1074965,0 16.6270275,0 C15.1426525,0 13.9395275,1.203125 13.9395275,2.6875 L13.9395275,8.730469 L8.72858949,5.722656 C7.43952749,4.976562 5.79108949,5.417969 5.04499649,6.707031 C4.29890249,7.996094 4.74421549,9.644531 6.03327749,10.390625" id="Path3"></path>
|
6
|
+
<path d="M26.6660895,22.199219 C26.6660895,22.402344 26.5489025,22.683594 26.4043715,22.832031 L22.7676525,26.46875 C22.6231215,26.613281 22.3379655,26.730469 22.1348395,26.730469 L21.2090585,26.730469 C21.0059335,26.730469 20.7207775,26.613281 20.5762465,26.46875 L16.9356215,22.832031 C16.7910895,22.683594 16.6739025,22.402344 16.6739025,22.199219 L16.6739025,21.273438 C16.6739025,21.066406 16.7910895,20.785156 16.9356215,20.640625 L20.5762465,17 C20.7207775,16.855469 21.0059335,16.738281 21.2090585,16.738281 L22.1348395,16.738281 C22.3379655,16.738281 22.6231215,16.855469 22.7676525,17 L26.4043715,20.640625 C26.5489025,20.785156 26.6660895,21.066406 26.6660895,21.273438 L26.6660895,22.199219 Z M23.4199965,21.753906 L23.4199965,21.714844 C23.4199965,21.566406 23.3340585,21.359375 23.2285895,21.25 L22.1543715,20.179688 C22.0489025,20.070312 21.8418715,19.984375 21.6895275,19.984375 L21.6504655,19.984375 C21.5020275,19.984375 21.2949965,20.070312 21.1856215,20.179688 L20.1153085,21.25 C20.0098395,21.355469 19.9239025,21.5625 19.9239025,21.714844 L19.9239025,21.753906 C19.9239025,21.90625 20.0098395,22.113281 20.1153085,22.21875 L21.1856215,23.292969 C21.2949965,23.398438 21.5020275,23.484375 21.6504655,23.484375 L21.6895275,23.484375 C21.8418715,23.484375 22.0489025,23.398438 22.1543715,23.292969 L23.2285895,22.21875 C23.3340585,22.113281 23.4199965,21.90625 23.4199965,21.753906 Z" id="Combined-Shape"></path>
|
7
|
+
<path d="M28.0879655,15.6875 L37.2637465,10.390625 C38.5528085,9.648438 38.9981215,7.996094 38.2520275,6.707031 C37.5059335,5.417969 35.8574965,4.976562 34.5684335,5.722656 L29.4278085,8.691406 L29.4278085,2.6875 C29.4278085,1.203125 28.2246835,-5.68434189e-14 26.7442155,-5.68434189e-14 C25.2598395,-5.68434189e-14 24.0567155,1.203125 24.0567155,2.6875 L24.0567155,13.09375 C24.0059335,13.632812 24.1114025,14.195312 24.4043715,14.703125 C25.1504655,15.992188 26.7989025,16.433594 28.0879655,15.6875" id="Path4"></path>
|
8
|
+
<path d="M17.0489025,27.515625 C16.4395275,27.398438 15.7871835,27.496094 15.2090585,27.828125 L6.03327749,33.128906 C4.74421549,33.871094 4.29890249,35.519531 5.04499649,36.808594 C5.79108949,38.101562 7.43952749,38.542969 8.72858949,37.796875 L13.9395275,34.789062 L13.9395275,40.785156 C13.9395275,42.265625 15.1426525,43.46875 16.6270275,43.46875 C18.1074965,43.46875 19.3106215,42.265625 19.3106215,40.785156 L19.3106215,30.167969 C19.3106215,28.828125 18.3301525,27.71875 17.0489025,27.515625" id="Path5"></path>
|
9
|
+
<path d="M42.9981215,15.078125 C42.2559335,13.785156 40.6035895,13.34375 39.3145275,14.089844 L30.1387465,19.386719 C29.2598395,19.894531 28.7754655,20.824219 28.7910895,21.769531 C28.7832775,22.710938 29.2676525,23.628906 30.1387465,24.128906 L39.3145275,29.429688 C40.6035895,30.171875 42.2520275,29.730469 42.9981215,28.441406 C43.7442155,27.152344 43.2989025,25.503906 42.0098395,24.757812 L36.8145275,21.757812 L42.0098395,18.757812 C43.3028085,18.015625 43.7442155,16.367188 42.9981215,15.078125" id="Path6"></path>
|
10
|
+
</svg>
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# require "zoho_books" # or the correct gem for Zoho Books
|
4
|
+
require "stringio"
|
5
|
+
|
6
|
+
module Multiwoven
|
7
|
+
module Integrations
|
8
|
+
module Source
|
9
|
+
module ZohoBooks
|
10
|
+
include Multiwoven::Integrations::Core
|
11
|
+
|
12
|
+
class Client < DestinationConnector
|
13
|
+
prepend Multiwoven::Integrations::Core::RateLimiter
|
14
|
+
|
15
|
+
def check_connection(connection_config)
|
16
|
+
connection_config = connection_config.with_indifferent_access
|
17
|
+
puts "connection_config zoho books: #{connection_config}"
|
18
|
+
create_connection(connection_config)
|
19
|
+
# authenticate_client
|
20
|
+
success_status
|
21
|
+
rescue StandardError => e
|
22
|
+
handle_exception("ZOHO:BOOKS:DISCOVER:EXCEPTION:check_connection", "error", e)
|
23
|
+
failure_status(e)
|
24
|
+
end
|
25
|
+
|
26
|
+
def discover(_connection_config = nil)
|
27
|
+
catalog = build_catalog(load_catalog)
|
28
|
+
catalog.to_multiwoven_message
|
29
|
+
rescue StandardError => e
|
30
|
+
handle_exception("ZOHO:BOOKS:DISCOVER:EXCEPTION:discover", "error", e)
|
31
|
+
end
|
32
|
+
|
33
|
+
def write(sync_config, records, action = "create")
|
34
|
+
@action = sync_config.stream.action || action
|
35
|
+
create_connection(sync_config.destination.connection_specification)
|
36
|
+
process_records(records, sync_config.stream)
|
37
|
+
rescue StandardError => e
|
38
|
+
handle_exception("ZOHO:BOOKS:WRITE:EXCEPTION:write", "error", e)
|
39
|
+
end
|
40
|
+
|
41
|
+
# def setting_base_url(url)
|
42
|
+
# @base_url = url
|
43
|
+
# puts "setting_base_url only for zoho: #{@base_url}"
|
44
|
+
# end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def create_connection(config)
|
49
|
+
# config = config.with_indifferent_access
|
50
|
+
@client_id = config[:client_id]
|
51
|
+
@client_secret = config[:client_secret]
|
52
|
+
@refresh_token = config[:refresh_token]
|
53
|
+
@organization_id = config[:organization_id]
|
54
|
+
@data_center = config[:data_center]
|
55
|
+
@base_url = config[:base_url]
|
56
|
+
|
57
|
+
# Zoho token endpoint
|
58
|
+
token_url = "https://accounts.zoho.com/oauth/v2/token"
|
59
|
+
|
60
|
+
# Prepare the request parameters
|
61
|
+
uri = URI.parse(token_url)
|
62
|
+
params = {
|
63
|
+
client_id: @client_id,
|
64
|
+
client_secret: @client_secret,
|
65
|
+
refresh_token: @refresh_token,
|
66
|
+
grant_type: 'refresh_token'
|
67
|
+
}
|
68
|
+
|
69
|
+
# Make the HTTP POST request to get the access token
|
70
|
+
response = Net::HTTP.post_form(uri, params)
|
71
|
+
|
72
|
+
# Parse the response
|
73
|
+
result = JSON.parse(response.body)
|
74
|
+
|
75
|
+
# Check if the response has an error or return the access token
|
76
|
+
if result["access_token"]
|
77
|
+
@access_token = result["access_token"]
|
78
|
+
puts "@access_token = result[VITORY]: #{@access_token}"
|
79
|
+
@access_token
|
80
|
+
else
|
81
|
+
raise "Error fetching access token: #{result['error']}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def query(connection, query)
|
86
|
+
connection.exec(query) do |result|
|
87
|
+
result.map do |row|
|
88
|
+
RecordMessage.new(data: row, emitted_at: Time.now.to_i).to_multiwoven_message
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def process_records(records, stream)
|
94
|
+
write_success = 0
|
95
|
+
write_failure = 0
|
96
|
+
properties = stream.json_schema.with_indifferent_access[:properties]
|
97
|
+
records.each do |record_object|
|
98
|
+
record = extract_data(record_object, properties)
|
99
|
+
send_data_to_zoho_books(stream.name, record)
|
100
|
+
write_success += 1
|
101
|
+
rescue StandardError => e
|
102
|
+
handle_exception("ZOHO:BOOKS:WRITE:EXCEPTION:process_records", "error", e)
|
103
|
+
write_failure += 1
|
104
|
+
end
|
105
|
+
tracking_message(write_success, write_failure)
|
106
|
+
end
|
107
|
+
|
108
|
+
def send_data_to_zoho_books(stream_name, record = {})
|
109
|
+
args = build_args(@action, stream_name, record)
|
110
|
+
zoho_books_stream = @client.send(stream_name) # Update with Zoho Books API structure
|
111
|
+
zoho_books_data = { record_input: args }
|
112
|
+
zoho_books_stream.send(@action, zoho_books_data) # Adjust to the correct API action
|
113
|
+
end
|
114
|
+
|
115
|
+
def build_args(action, stream_name, record)
|
116
|
+
case action
|
117
|
+
when :upsert
|
118
|
+
[stream_name, record[:external_key], record]
|
119
|
+
when :destroy
|
120
|
+
[stream_name, record[:id]]
|
121
|
+
else
|
122
|
+
record
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# def authenticate_client
|
127
|
+
# @client.get_invoices # Replace with a Zoho Books API method to test connection
|
128
|
+
# end
|
129
|
+
|
130
|
+
def success_status
|
131
|
+
ConnectionStatus.new(status: ConnectionStatusType["succeeded"]).to_multiwoven_message
|
132
|
+
end
|
133
|
+
|
134
|
+
def failure_status(error)
|
135
|
+
ConnectionStatus.new(status: ConnectionStatusType["failed"], message: error.message).to_multiwoven_message
|
136
|
+
end
|
137
|
+
|
138
|
+
def load_catalog
|
139
|
+
read_json(CATALOG_SPEC_PATH)
|
140
|
+
end
|
141
|
+
|
142
|
+
def tracking_message(success, failure)
|
143
|
+
Multiwoven::Integrations::Protocol::TrackingMessage.new(
|
144
|
+
success: success, failed: failure
|
145
|
+
).to_multiwoven_message
|
146
|
+
end
|
147
|
+
|
148
|
+
def log_debug(message)
|
149
|
+
Multiwoven::Integrations::Service.logger.debug(message)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"name": "ZohoBooks",
|
4
|
+
"title": "Zoho Books",
|
5
|
+
"connector_type": "source",
|
6
|
+
"category": "Accounting",
|
7
|
+
"documentation_url": "https://docs.multiwoven.com/destinations/accounting/zohobooks",
|
8
|
+
"github_issue_label": "destination-zohobooks-invoices",
|
9
|
+
"icon": "icon.svg",
|
10
|
+
"license": "MIT",
|
11
|
+
"release_stage": "alpha",
|
12
|
+
"support_level": "community",
|
13
|
+
"tags": ["language:ruby", "multiwoven", "invoices"]
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"documentation_url": "https://docs.multiwoven.com/destinations/accounting/zohobooks",
|
3
|
+
"stream_type": "static",
|
4
|
+
"connection_specification": {
|
5
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
6
|
+
"title": "Zoho Books",
|
7
|
+
"type": "object",
|
8
|
+
"required": ["client_id", "client_secret", "refresh_token", "organization_id", "data_center"],
|
9
|
+
"properties": {
|
10
|
+
"client_id": {
|
11
|
+
"type": "string",
|
12
|
+
"title": "Client ID",
|
13
|
+
"description": "The OAuth 2.0 client ID for Zoho Books API access.",
|
14
|
+
"order": 0
|
15
|
+
},
|
16
|
+
"client_secret": {
|
17
|
+
"type": "string",
|
18
|
+
"title": "Client Secret",
|
19
|
+
"description": "The OAuth 2.0 client secret for Zoho Books API access.",
|
20
|
+
"order": 1
|
21
|
+
},
|
22
|
+
"refresh_token": {
|
23
|
+
"type": "string",
|
24
|
+
"title": "Refresh Token",
|
25
|
+
"description": "The OAuth 2.0 refresh token for Zoho Books API access.",
|
26
|
+
"order": 2
|
27
|
+
},
|
28
|
+
"organization_id": {
|
29
|
+
"type": "string",
|
30
|
+
"title": "Organization ID",
|
31
|
+
"description": "The unique identifier for your Zoho Books organization.",
|
32
|
+
"order": 3
|
33
|
+
},
|
34
|
+
"data_center": {
|
35
|
+
"type": "string",
|
36
|
+
"title": "Data Center",
|
37
|
+
"description": "The unique identifier for your Zoho Books organization.",
|
38
|
+
"order": 4
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
4
|
+
<style>
|
5
|
+
.st1{fill:#fff}
|
6
|
+
</style>
|
7
|
+
<g id="Icon">
|
8
|
+
<circle id="Background" cx="512" cy="512" r="512" style="fill:#c82336"/>
|
9
|
+
<g id="ZOHO_logo__x28_monochrome_edit_by_krisu_x29_">
|
10
|
+
<path id="O_1_" class="st1" d="M810.3 452.6 829 431v147.8l-18.7 18.7V452.6zm-137.7-2.4h135.2l19-21.9-134.2.1m45.2 62.6c-9.3 0-16.4 3.2-21.7 9.6-5.3 6.4-7.9 15.2-7.9 26.6 0 11.2 2.7 19.9 8 26.2 5.3 6.3 12.4 9.5 21.6 9.5 9.2 0 16.3-3.2 21.5-9.5 5.3-6.4 7.9-15.1 7.9-26.2 0-11.4-2.7-20.2-7.9-26.6-5.2-6.4-12.3-9.6-21.5-9.6zm69.1-37.4v145.5H671.1V453.6h135.8zm-15.2 73.6c0-8-1.4-15.5-4.1-22.3-2.7-6.8-6.7-13-12.1-18.4-5.1-5.2-10.8-9.1-17.2-11.8-6.3-2.6-13.2-3.9-20.5-3.9-7.4 0-14.3 1.3-20.7 3.9-6.4 2.6-12.1 6.6-17.2 11.8-5.3 5.4-9.3 11.5-12 18.3-2.7 6.8-4 14.3-4 22.4 0 8 1.3 15.4 4 22.3s6.7 13.1 12 18.5c4.9 5.1 10.6 9 17 11.6 6.4 2.6 13.3 3.9 20.9 3.9 7.3 0 14.1-1.3 20.5-3.9 6.4-2.6 12.1-6.5 17.2-11.6 5.3-5.5 9.4-11.6 12.1-18.5 2.7-6.8 4.1-14.3 4.1-22.3z"/>
|
11
|
+
<path id="H" class="st1" d="m675.2 552-9 25.1L648 448.7l10.1-28.9m-133.4 45.3-.2-1.7L645 447l10.7-30.6-133.4 18.5-9.5 31.8 11.9-1.6zm138.6 115.6-131.7 18.5-17.9-126 13.4 6 .7-1.5-.5-2.1-14.1-6.4-.4-2.5 11.8-1.6.4 1.7 119.7-16.3 18.6 130.2zm-26.4-14.4c0-1-.1-2.1-.3-3.3l-13.1-89.3c-.6-4.1-2-7.2-4.3-9.3-1.8-1.6-4.1-2.5-6.7-2.5-.7 0-1.3.1-2 .2-3.5.5-6.1 2.1-7.7 4.7-1.2 1.9-1.8 4.2-1.8 6.9 0 1 .1 2.1.3 3.2l4.9 34.3-38.3 5.6-4.9-34.3c-.6-4-2-7.1-4.2-9.2-1.8-1.7-4.1-2.6-6.6-2.6-.6 0-1.2 0-1.8.1-3.6.5-6.4 2.1-8 4.7-1.2 1.9-1.8 4.2-1.8 6.9 0 1 .1 2.1.3 3.3L554 575c.6 4.1 2 7.2 4.4 9.2 1.8 1.6 4.1 2.4 6.8 2.4.7 0 1.5-.1 2.2-.2 3.3-.5 5.9-2.1 7.4-4.7 1.1-1.9 1.6-4.1 1.6-6.7 0-1-.1-2.1-.3-3.3l-5.4-35.3 38.3-5.6 5.4 35.3c.6 4.1 2 7.2 4.3 9.2 1.8 1.6 4.1 2.4 6.7 2.4.7 0 1.3-.1 2.1-.2 3.4-.5 6.1-2.1 7.7-4.7 1.2-1.6 1.7-3.9 1.7-6.5z"/>
|
12
|
+
<path id="O" class="st1" d="m353.6 543-6.2-47 47.2-111.9 11.7 39.4L357.6 534l-4 9zm101.9-65.8c-3.9-1.7-7.7-2.5-11.4-2.5-4.2 0-8.3 1.1-12.2 3.2-7.4 4.1-13.4 11.5-18 22.4-3 7.1-4.5 13.6-4.5 19.6 0 3 .4 5.9 1.1 8.6 2.3 8.1 7.5 13.8 15.9 17.4 3.9 1.6 7.6 2.5 11.3 2.5 4.2 0 8.2-1.1 12.2-3.2 7.4-4 13.3-11.3 17.8-22 3.1-7.3 4.6-14 4.6-20.1 0-2.9-.4-5.7-1.1-8.4-2.3-8.2-7.4-13.9-15.7-17.5zm62.2-39.6-120.1-55 11.8 39.8 117.8 53.2m-.1 3.6-53.3 121.1L355.6 547v-.1l53.3-121 118.2 53.3zm-31.9 30.6v-2.2c0-6.8-1.2-13.5-3.6-20-2.5-6.9-6.2-12.9-10.9-17.8-4.7-5-10.4-8.9-17.1-11.7-6.7-2.8-13.4-4.2-20.2-4.2h-.3c-6.9 0-13.7 1.6-20.4 4.6-7 3.1-13.1 7.3-18.3 12.8-5.2 5.5-9.4 12.1-12.7 19.8-3.2 7.6-5 15.2-5.3 22.8 0 .9-.1 1.7-.1 2.6 0 6.7 1.2 13.3 3.4 19.7 2.4 6.8 6 12.6 10.8 17.6 4.7 4.9 10.6 8.9 17.5 11.8 6.6 2.8 13.3 4.2 20.1 4.2h.2c6.8 0 13.6-1.5 20.3-4.4 7.1-3.2 13.2-7.5 18.5-13 5.2-5.5 9.5-12.1 12.7-19.7 3.3-7.8 5.1-15.4 5.4-22.9z"/>
|
13
|
+
<path id="Z" class="st1" d="m349.5 573.2-19-124.8 8.1-42.3 18.8 126-7.9 41.1zm-2.6 5.2-130.7 20.5-21-128.4 132.2-20.2 19.5 128.1zm-30.1-14.1c0-.7-.1-1.4-.2-2.2-.3-1.8-1-3.4-2-4.6-1-1.2-2.4-2.2-4.2-2.8-1.8-.6-3.9-.9-6.4-.9-2.4 0-5.1.3-8.1.8l-34.9 6c.4-2.7 1.7-6.2 4.1-10.5 2.6-4.8 6.5-10.6 11.6-17.4 1.8-2.4 3.1-4.1 4-5.4.7-.8 1.6-2 2.8-3.6 8-10.5 12.9-19 14.8-25.7 1.1-3.8 1.7-7.6 2-11.5.1-1.1.1-2.1.1-3.1 0-2.8-.2-5.5-.7-8.2-.4-2.4-1-4.5-1.8-6.1-.8-1.6-1.8-2.9-3.1-3.6-1.4-.9-3.4-1.2-6-1.2-2.2 0-4.8.3-7.8.8l-40.4 6.9c-4.9.8-8.5 2.3-10.8 4.4-1.8 1.7-2.8 3.9-2.8 6.5 0 .7.1 1.4.2 2.1.6 3.4 2.4 5.9 5.2 7.2 1.7.8 3.8 1.1 6.2 1.1 1.6 0 3.4-.2 5.4-.5l33.8-5.7c.1.6.1 1.2.1 1.8 0 2.1-.4 4.2-1.1 6.2-1 2.8-3.5 6.8-7.5 11.9-1.1 1.4-2.9 3.5-5.2 6.5-9.1 11-15.6 20.4-19.6 28.3-2.8 5.4-4.7 10.7-5.8 15.9-.6 3-.9 6-.9 8.8 0 2 .2 4 .5 5.8.5 2.7 1.1 4.9 2 6.7.9 1.8 2 3.1 3.5 3.9 1.3.7 3.3 1 5.9 1 3.4 0 7.9-.5 13.7-1.5l36.6-6.3c6.5-1.1 11-2.7 13.6-4.8 2.2-1.9 3.3-4.3 3.2-7zM204.3 422.5l-6.7 33.3-2.3 11.3 132.1-20.2 8.7-45.5-131.8 21.1z"/>
|
14
|
+
</g>
|
15
|
+
</g>
|
16
|
+
</svg>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "dry-struct"
|
5
|
+
require "dry-schema"
|
6
|
+
require "dry-types"
|
7
|
+
require "odbc"
|
8
|
+
require "sequel"
|
9
|
+
require "byebug"
|
10
|
+
require "net/http"
|
11
|
+
require "uri"
|
12
|
+
require "active_support/core_ext/hash/indifferent_access"
|
13
|
+
require "restforce"
|
14
|
+
require "logger"
|
15
|
+
require "slack-ruby-client"
|
16
|
+
require "git"
|
17
|
+
require "ruby-limiter"
|
18
|
+
require "hubspot-api-client"
|
19
|
+
require "google/apis/sheets_v4"
|
20
|
+
require "stringio"
|
21
|
+
require "stripe"
|
22
|
+
require "net/sftp"
|
23
|
+
require "csv"
|
24
|
+
require "securerandom"
|
25
|
+
|
26
|
+
# Service
|
27
|
+
require_relative "integrations/config"
|
28
|
+
require_relative "integrations/rollout"
|
29
|
+
require_relative "integrations/service"
|
30
|
+
|
31
|
+
# Core
|
32
|
+
require_relative "integrations/core/constants"
|
33
|
+
require_relative "integrations/core/utils"
|
34
|
+
require_relative "integrations/core/rate_limiter"
|
35
|
+
require_relative "integrations/core/fullrefresher"
|
36
|
+
require_relative "integrations/protocol/protocol"
|
37
|
+
require_relative "integrations/core/base_connector"
|
38
|
+
require_relative "integrations/core/source_connector"
|
39
|
+
require_relative "integrations/core/destination_connector"
|
40
|
+
require_relative "integrations/core/http_client"
|
41
|
+
require_relative "integrations/core/query_builder"
|
42
|
+
|
43
|
+
# Source
|
44
|
+
require_relative "integrations/source/snowflake/client"
|
45
|
+
require_relative "integrations/source/redshift/client"
|
46
|
+
require_relative "integrations/source/bigquery/client"
|
47
|
+
require_relative "integrations/source/postgresql/client"
|
48
|
+
require_relative "integrations/source/databricks/client"
|
49
|
+
require_relative "integrations/source/salesforce_consumer_goods_cloud/client"
|
50
|
+
require_relative "integrations/source/zoho_books/client"
|
51
|
+
|
52
|
+
# Destination
|
53
|
+
require_relative "integrations/destination/klaviyo/client"
|
54
|
+
require_relative "integrations/destination/salesforce_crm/client"
|
55
|
+
require_relative "integrations/destination/facebook_custom_audience/client"
|
56
|
+
require_relative "integrations/destination/slack/client"
|
57
|
+
require_relative "integrations/destination/hubspot/client"
|
58
|
+
require_relative "integrations/destination/google_sheets/client"
|
59
|
+
require_relative "integrations/destination/airtable/client"
|
60
|
+
require_relative "integrations/destination/stripe/client"
|
61
|
+
require_relative "integrations/destination/salesforce_consumer_goods_cloud/client"
|
62
|
+
require_relative "integrations/destination/sftp/client"
|
63
|
+
require_relative "integrations/destination/postgresql/client"
|
64
|
+
require_relative "integrations/destination/tally/client"
|
65
|
+
|
66
|
+
module Multiwoven
|
67
|
+
module Integrations
|
68
|
+
class Error < StandardError; end
|
69
|
+
# Your code goes here...
|
70
|
+
end
|
71
|
+
end
|
Binary file
|