multiwoven-integrations 0.1.17 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/multiwoven/integrations/core/base_connector.rb +5 -1
- data/lib/multiwoven/integrations/core/destination_connector.rb +3 -1
- data/lib/multiwoven/integrations/core/source_connector.rb +2 -0
- data/lib/multiwoven/integrations/core/utils.rb +1 -1
- data/lib/multiwoven/integrations/destination/facebook_custom_audience/client.rb +25 -28
- data/lib/multiwoven/integrations/destination/slack/client.rb +1 -1
- data/lib/multiwoven/integrations/destination/slack/config/catalog.json +2 -53
- data/lib/multiwoven/integrations/rollout.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 429328f071eab809197f11563a5c87a91ca1d83db1f89f67edc001b2d8aa0d08
|
4
|
+
data.tar.gz: fdbe36a9021b0eae79cff29ec7002859f03993e354d61a45e01024b293ea5835
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b17d88517b0b196bef171d72abb99f8ae9faa8e1b8e62c4e9296e86d821025544c742e35a526b5cd1a35a31e8f1959183648a24dcb8ac0269ec34dca5de87e0
|
7
|
+
data.tar.gz: 96d942afc5d2a4015534b57d72b2f8f35fdb91bec1004e5d180ecf451d46a5cc980fdfca406335de9d7ef522e041c49dcba459d56f297ead36223e701f389ac3
|
@@ -10,6 +10,7 @@ module Multiwoven
|
|
10
10
|
def connector_spec
|
11
11
|
@connector_spec ||= begin
|
12
12
|
spec_json = keys_to_symbols(read_json(CONNECTOR_SPEC_PATH)).to_json
|
13
|
+
# returns Protocol::ConnectorSpecification
|
13
14
|
ConnectorSpecification.from_json(spec_json)
|
14
15
|
end
|
15
16
|
end
|
@@ -19,17 +20,20 @@ module Multiwoven
|
|
19
20
|
icon_name = client_meta_data[:data][:icon]
|
20
21
|
icon_url = "https://raw.githubusercontent.com/Multiwoven/multiwoven-integrations/#{MAIN_BRANCH_SHA}/assets/images/connectors/#{icon_name}"
|
21
22
|
client_meta_data[:data][:icon] = icon_url
|
22
|
-
|
23
|
+
# returns hash
|
23
24
|
@meta_data ||= client_meta_data
|
24
25
|
end
|
25
26
|
|
27
|
+
# Connection config is a hash
|
26
28
|
def check_connection(_connection_config)
|
27
29
|
raise "Not implemented"
|
28
30
|
# returns Protocol.ConnectionStatus
|
29
31
|
end
|
30
32
|
|
33
|
+
# Connection config is a hash
|
31
34
|
def discover(_connection_config)
|
32
35
|
raise "Not implemented"
|
36
|
+
# returns Protocol::Catalog
|
33
37
|
end
|
34
38
|
|
35
39
|
private
|
@@ -3,9 +3,11 @@
|
|
3
3
|
module Multiwoven
|
4
4
|
module Integrations::Core
|
5
5
|
class DestinationConnector < BaseConnector
|
6
|
+
# records is transformed json payload send it to the destination
|
7
|
+
# SyncConfig is the Protocol::SyncConfig object
|
6
8
|
def write(_sync_config, _records, _action = "insert")
|
7
9
|
raise "Not implemented"
|
8
|
-
# return
|
10
|
+
# return Protocol::TrackingMessage
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -3,10 +3,12 @@
|
|
3
3
|
module Multiwoven
|
4
4
|
module Integrations::Core
|
5
5
|
class SourceConnector < BaseConnector
|
6
|
+
# accepts Protocol::SyncConfig
|
6
7
|
def read(_sync_config)
|
7
8
|
raise "Not implemented"
|
8
9
|
# setup sync configs
|
9
10
|
# call query(connection, query)
|
11
|
+
# Returns list of RecordMessage
|
10
12
|
end
|
11
13
|
|
12
14
|
private
|
@@ -65,7 +65,7 @@ module Multiwoven
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def extract_data(record_object, properties)
|
68
|
-
data_attributes = record_object.with_indifferent_access
|
68
|
+
data_attributes = record_object.with_indifferent_access
|
69
69
|
data_attributes.select { |key, _| properties.key?(key.to_sym) }
|
70
70
|
end
|
71
71
|
|
@@ -3,7 +3,8 @@
|
|
3
3
|
module Multiwoven::Integrations::Destination
|
4
4
|
module FacebookCustomAudience
|
5
5
|
include Multiwoven::Integrations::Core
|
6
|
-
class Client < DestinationConnector
|
6
|
+
class Client < DestinationConnector # rubocop:disable Metrics/ClassLength
|
7
|
+
MAX_CHUNK_SIZE = 10_000
|
7
8
|
def check_connection(connection_config)
|
8
9
|
connection_config = connection_config.with_indifferent_access
|
9
10
|
access_token = connection_config[:access_token]
|
@@ -54,8 +55,8 @@ module Multiwoven::Integrations::Destination
|
|
54
55
|
url = generate_url(sync_config, connection_config)
|
55
56
|
write_success = 0
|
56
57
|
write_failure = 0
|
57
|
-
records.
|
58
|
-
payload = create_payload(
|
58
|
+
records.each_slice(MAX_CHUNK_SIZE) do |chunk|
|
59
|
+
payload = create_payload(chunk, sync_config.stream.json_schema.with_indifferent_access)
|
59
60
|
response = Multiwoven::Integrations::Core::HttpClient.request(
|
60
61
|
url,
|
61
62
|
sync_config.stream.request_method,
|
@@ -63,28 +64,22 @@ module Multiwoven::Integrations::Destination
|
|
63
64
|
headers: auth_headers(access_token)
|
64
65
|
)
|
65
66
|
if success?(response)
|
66
|
-
write_success +=
|
67
|
+
write_success += chunk.size
|
67
68
|
else
|
68
|
-
write_failure +=
|
69
|
+
write_failure += chunk.size
|
69
70
|
end
|
70
71
|
rescue StandardError => e
|
71
|
-
|
72
|
-
|
73
|
-
)
|
74
|
-
write_failure += 1
|
72
|
+
handle_exception("FACEBOOK:RECORD:WRITE:EXCEPTION", "error", e)
|
73
|
+
write_failure += chunk.size
|
75
74
|
end
|
75
|
+
|
76
76
|
tracker = Multiwoven::Integrations::Protocol::TrackingMessage.new(
|
77
77
|
success: write_success,
|
78
78
|
failed: write_failure
|
79
79
|
)
|
80
80
|
tracker.to_multiwoven_message
|
81
81
|
rescue StandardError => e
|
82
|
-
|
83
|
-
handle_exception(
|
84
|
-
"FACEBOOK:WRITE:EXCEPTION",
|
85
|
-
"error",
|
86
|
-
e
|
87
|
-
)
|
82
|
+
handle_exception("FACEBOOK:WRITE:EXCEPTION", "error", e)
|
88
83
|
end
|
89
84
|
|
90
85
|
private
|
@@ -93,28 +88,30 @@ module Multiwoven::Integrations::Destination
|
|
93
88
|
sync_config.stream.url.gsub("{audience_id}", connection_config[:audience_id])
|
94
89
|
end
|
95
90
|
|
96
|
-
def create_payload(
|
97
|
-
schema, data = extract_schema_and_data(
|
91
|
+
def create_payload(records, json_schema)
|
92
|
+
schema, data = extract_schema_and_data(records, json_schema)
|
98
93
|
{
|
99
94
|
"payload" => {
|
100
95
|
"schema" => schema,
|
101
|
-
"data" =>
|
96
|
+
"data" => data
|
102
97
|
}
|
103
98
|
}
|
104
99
|
end
|
105
100
|
|
106
|
-
def extract_schema_and_data(
|
101
|
+
def extract_schema_and_data(records, json_schema)
|
107
102
|
schema_properties = json_schema[:properties]
|
108
|
-
schema =
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
103
|
+
schema = records.first.keys.map(&:to_s).map(&:upcase)
|
104
|
+
data = []
|
105
|
+
records.each do |record|
|
106
|
+
encrypted_data_array = []
|
107
|
+
record.with_indifferent_access.each do |key, value|
|
108
|
+
schema_key = key.upcase
|
109
|
+
encrypted_value = schema_properties[schema_key] && schema_properties[schema_key]["x-hashRequired"] ? Digest::SHA256.hexdigest(value.to_s) : value
|
110
|
+
encrypted_data_array << encrypted_value
|
111
|
+
end
|
112
|
+
data << encrypted_data_array
|
115
113
|
end
|
116
|
-
|
117
|
-
[schema, encrypted_data_array]
|
114
|
+
[schema, data]
|
118
115
|
end
|
119
116
|
|
120
117
|
def auth_headers(access_token)
|
@@ -72,7 +72,7 @@ module Multiwoven
|
|
72
72
|
def build_args(stream_name, record)
|
73
73
|
case stream_name
|
74
74
|
when "chat_postMessage"
|
75
|
-
{ channel: channel_id, text: slack_code_block(record
|
75
|
+
{ channel: channel_id, text: slack_code_block(record) }
|
76
76
|
else
|
77
77
|
raise "Stream name not found: #{stream_name}"
|
78
78
|
end
|
@@ -9,63 +9,12 @@
|
|
9
9
|
"properties": {
|
10
10
|
"text": {
|
11
11
|
"type": ["string", "null"]
|
12
|
-
},
|
13
|
-
"attachments": {
|
14
|
-
"type": ["string", "null"]
|
15
|
-
},
|
16
|
-
"blocks": {
|
17
|
-
"type": ["array", "null"],
|
18
|
-
"items": {
|
19
|
-
"type": "string"
|
20
|
-
}
|
21
|
-
},
|
22
|
-
"as_user": {
|
23
|
-
"type": ["boolean", "null"]
|
24
|
-
},
|
25
|
-
"icon_emoji": {
|
26
|
-
"type": ["string", "null"]
|
27
|
-
},
|
28
|
-
"icon_url": {
|
29
|
-
"type": ["string", "null"]
|
30
|
-
},
|
31
|
-
"link_names": {
|
32
|
-
"type": ["boolean", "null"]
|
33
|
-
},
|
34
|
-
"metadata": {
|
35
|
-
"type": ["string", "null"]
|
36
|
-
},
|
37
|
-
"mrkdwn": {
|
38
|
-
"type": ["boolean", "null"]
|
39
|
-
},
|
40
|
-
"parse": {
|
41
|
-
"type": ["string", "null"]
|
42
|
-
},
|
43
|
-
"reply_broadcast": {
|
44
|
-
"type": ["boolean", "null"]
|
45
|
-
},
|
46
|
-
"thread_ts": {
|
47
|
-
"type": ["string", "null"]
|
48
|
-
},
|
49
|
-
"unfurl_links": {
|
50
|
-
"type": ["boolean", "null"]
|
51
|
-
},
|
52
|
-
"unfurl_media": {
|
53
|
-
"type": ["boolean", "null"]
|
54
|
-
},
|
55
|
-
"username": {
|
56
|
-
"type": ["string", "null"]
|
57
12
|
}
|
58
13
|
},
|
59
|
-
"oneOf": [
|
60
|
-
{ "required": ["text"] },
|
61
|
-
{ "required": ["attachments"] },
|
62
|
-
{ "required": ["blocks"] }
|
63
|
-
]
|
14
|
+
"oneOf": [{ "required": ["text"] }]
|
64
15
|
},
|
65
16
|
"supported_sync_modes": ["full_refresh", "incremental"],
|
66
|
-
"source_defined_cursor": true
|
67
|
-
"default_cursor_field": ["updated"],
|
68
|
-
"source_defined_primary_key": [["Id"]]
|
17
|
+
"source_defined_cursor": true
|
69
18
|
}
|
70
19
|
]
|
71
20
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multiwoven-integrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Subin T P
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -362,7 +362,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
362
362
|
- !ruby/object:Gem::Version
|
363
363
|
version: '0'
|
364
364
|
requirements: []
|
365
|
-
rubygems_version: 3.
|
365
|
+
rubygems_version: 3.4.1
|
366
366
|
signing_key:
|
367
367
|
specification_version: 4
|
368
368
|
summary: Integration suite for open source reverse ETL platform
|