outhad-integrations 0.32.0
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +43 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +5 -0
- data/README.md +76 -0
- data/Rakefile +12 -0
- data/lib/outhad/integrations/config.rb +14 -0
- data/lib/outhad/integrations/core/base_connector.rb +79 -0
- data/lib/outhad/integrations/core/constants.rb +103 -0
- data/lib/outhad/integrations/core/destination_connector.rb +20 -0
- data/lib/outhad/integrations/core/fullrefresher.rb +19 -0
- data/lib/outhad/integrations/core/http_client.rb +17 -0
- data/lib/outhad/integrations/core/http_helper.rb +36 -0
- data/lib/outhad/integrations/core/query_builder.rb +33 -0
- data/lib/outhad/integrations/core/rate_limiter.rb +19 -0
- data/lib/outhad/integrations/core/source_connector.rb +66 -0
- data/lib/outhad/integrations/core/streaming_http_client.rb +21 -0
- data/lib/outhad/integrations/core/unstructured_source_connector.rb +52 -0
- data/lib/outhad/integrations/core/utils.rb +123 -0
- data/lib/outhad/integrations/core/vector_source_connector.rb +14 -0
- data/lib/outhad/integrations/destination/airtable/client.rb +157 -0
- data/lib/outhad/integrations/destination/airtable/config/catalog.json +6 -0
- data/lib/outhad/integrations/destination/airtable/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/airtable/config/spec.json +23 -0
- data/lib/outhad/integrations/destination/airtable/icon.svg +6 -0
- data/lib/outhad/integrations/destination/airtable/schema_helper.rb +141 -0
- data/lib/outhad/integrations/destination/ais_data_store/client.rb +130 -0
- data/lib/outhad/integrations/destination/ais_data_store/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/ais_data_store/config/spec.json +68 -0
- data/lib/outhad/integrations/destination/ais_data_store/icon.svg +4 -0
- data/lib/outhad/integrations/destination/amazon_s3/client.rb +92 -0
- data/lib/outhad/integrations/destination/amazon_s3/config/catalog.json +16 -0
- data/lib/outhad/integrations/destination/amazon_s3/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/amazon_s3/config/spec.json +56 -0
- data/lib/outhad/integrations/destination/amazon_s3/icon.svg +34 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/client.rb +147 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/config/spec.json +44 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/icon.svg +65 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/client.rb +125 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/config/catalog.json +42 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/config/spec.json +28 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/icon.svg +23 -0
- data/lib/outhad/integrations/destination/google_sheets/client.rb +240 -0
- data/lib/outhad/integrations/destination/google_sheets/config/catalog.json +6 -0
- data/lib/outhad/integrations/destination/google_sheets/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/google_sheets/config/spec.json +75 -0
- data/lib/outhad/integrations/destination/google_sheets/icon.svg +1 -0
- data/lib/outhad/integrations/destination/http/client.rb +106 -0
- data/lib/outhad/integrations/destination/http/config/catalog.json +16 -0
- data/lib/outhad/integrations/destination/http/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/http/config/spec.json +24 -0
- data/lib/outhad/integrations/destination/http/icon.svg +9 -0
- data/lib/outhad/integrations/destination/hubspot/client.rb +122 -0
- data/lib/outhad/integrations/destination/hubspot/config/catalog.json +351 -0
- data/lib/outhad/integrations/destination/hubspot/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/hubspot/config/spec.json +18 -0
- data/lib/outhad/integrations/destination/hubspot/icon.svg +5 -0
- data/lib/outhad/integrations/destination/iterable/client.rb +111 -0
- data/lib/outhad/integrations/destination/iterable/config/catalog.json +47 -0
- data/lib/outhad/integrations/destination/iterable/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/iterable/config/spec.json +19 -0
- data/lib/outhad/integrations/destination/iterable/icon.svg +71 -0
- data/lib/outhad/integrations/destination/klaviyo/client.rb +119 -0
- data/lib/outhad/integrations/destination/klaviyo/config/catalog.json +103 -0
- data/lib/outhad/integrations/destination/klaviyo/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/klaviyo/config/spec.json +24 -0
- data/lib/outhad/integrations/destination/klaviyo/icon.svg +6 -0
- data/lib/outhad/integrations/destination/mailchimp/client.rb +141 -0
- data/lib/outhad/integrations/destination/mailchimp/config/catalog.json +142 -0
- data/lib/outhad/integrations/destination/mailchimp/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/mailchimp/config/spec.json +28 -0
- data/lib/outhad/integrations/destination/mailchimp/icon.svg +4 -0
- data/lib/outhad/integrations/destination/maria_db/client.rb +114 -0
- data/lib/outhad/integrations/destination/maria_db/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/maria_db/config/spec.json +48 -0
- data/lib/outhad/integrations/destination/maria_db/icon.svg +15 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/client.rb +150 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/config/catalog.json +161 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/config/spec.json +35 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/icon.svg +2 -0
- data/lib/outhad/integrations/destination/microsoft_excel/client.rb +198 -0
- data/lib/outhad/integrations/destination/microsoft_excel/config/catalog.json +7 -0
- data/lib/outhad/integrations/destination/microsoft_excel/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/microsoft_excel/config/spec.json +19 -0
- data/lib/outhad/integrations/destination/microsoft_excel/icon.svg +18 -0
- data/lib/outhad/integrations/destination/microsoft_sql/client.rb +137 -0
- data/lib/outhad/integrations/destination/microsoft_sql/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/microsoft_sql/config/spec.json +68 -0
- data/lib/outhad/integrations/destination/microsoft_sql/icon.svg +22 -0
- data/lib/outhad/integrations/destination/odoo/client.rb +109 -0
- data/lib/outhad/integrations/destination/odoo/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/odoo/config/spec.json +39 -0
- data/lib/outhad/integrations/destination/odoo/icon.svg +21 -0
- data/lib/outhad/integrations/destination/oracle_db/client.rb +112 -0
- data/lib/outhad/integrations/destination/oracle_db/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/oracle_db/config/spec.json +47 -0
- data/lib/outhad/integrations/destination/oracle_db/icon.svg +4 -0
- data/lib/outhad/integrations/destination/pinecone_db/client.rb +154 -0
- data/lib/outhad/integrations/destination/pinecone_db/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/pinecone_db/config/spec.json +32 -0
- data/lib/outhad/integrations/destination/pinecone_db/icon.svg +1 -0
- data/lib/outhad/integrations/destination/postgresql/client.rb +130 -0
- data/lib/outhad/integrations/destination/postgresql/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/postgresql/config/spec.json +68 -0
- data/lib/outhad/integrations/destination/postgresql/icon.svg +20 -0
- data/lib/outhad/integrations/destination/qdrant/client.rb +184 -0
- data/lib/outhad/integrations/destination/qdrant/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/qdrant/config/spec.json +23 -0
- data/lib/outhad/integrations/destination/qdrant/icon.svg +1 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/client.rb +136 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/meta.json +16 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/spec.json +52 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/icon.svg +16 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/schema_helper.rb +132 -0
- data/lib/outhad/integrations/destination/salesforce_crm/client.rb +114 -0
- data/lib/outhad/integrations/destination/salesforce_crm/config/catalog.json +320 -0
- data/lib/outhad/integrations/destination/salesforce_crm/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/salesforce_crm/config/spec.json +46 -0
- data/lib/outhad/integrations/destination/salesforce_crm/icon.svg +16 -0
- data/lib/outhad/integrations/destination/sftp/client.rb +186 -0
- data/lib/outhad/integrations/destination/sftp/config/catalog.json +16 -0
- data/lib/outhad/integrations/destination/sftp/config/meta.json +16 -0
- data/lib/outhad/integrations/destination/sftp/config/spec.json +73 -0
- data/lib/outhad/integrations/destination/sftp/icon.svg +1 -0
- data/lib/outhad/integrations/destination/slack/client.rb +125 -0
- data/lib/outhad/integrations/destination/slack/config/catalog.json +22 -0
- data/lib/outhad/integrations/destination/slack/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/slack/config/spec.json +23 -0
- data/lib/outhad/integrations/destination/slack/icon.svg +26 -0
- data/lib/outhad/integrations/destination/stripe/client.rb +94 -0
- data/lib/outhad/integrations/destination/stripe/config/catalog.json +128 -0
- data/lib/outhad/integrations/destination/stripe/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/stripe/config/spec.json +18 -0
- data/lib/outhad/integrations/destination/stripe/icon.svg +10 -0
- data/lib/outhad/integrations/destination/zendesk/client.rb +132 -0
- data/lib/outhad/integrations/destination/zendesk/config/catalog.json +110 -0
- data/lib/outhad/integrations/destination/zendesk/config/meta.json +18 -0
- data/lib/outhad/integrations/destination/zendesk/config/spec.json +32 -0
- data/lib/outhad/integrations/destination/zendesk/icon.svg +63 -0
- data/lib/outhad/integrations/protocol/protocol.json +189 -0
- data/lib/outhad/integrations/protocol/protocol.rb +228 -0
- data/lib/outhad/integrations/rollout.rb +66 -0
- data/lib/outhad/integrations/service.rb +55 -0
- data/lib/outhad/integrations/source/amazon_s3/client.rb +235 -0
- data/lib/outhad/integrations/source/amazon_s3/config/meta.json +16 -0
- data/lib/outhad/integrations/source/amazon_s3/config/spec.json +119 -0
- data/lib/outhad/integrations/source/amazon_s3/icon.svg +34 -0
- data/lib/outhad/integrations/source/anthropic/client.rb +135 -0
- data/lib/outhad/integrations/source/anthropic/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/anthropic/config/meta.json +16 -0
- data/lib/outhad/integrations/source/anthropic/config/spec.json +56 -0
- data/lib/outhad/integrations/source/anthropic/icon.svg +1 -0
- data/lib/outhad/integrations/source/aws_athena/client.rb +109 -0
- data/lib/outhad/integrations/source/aws_athena/config/meta.json +16 -0
- data/lib/outhad/integrations/source/aws_athena/config/spec.json +63 -0
- data/lib/outhad/integrations/source/aws_athena/icon.svg +22 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/client.rb +91 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/config/meta.json +16 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/config/spec.json +58 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/icon.svg +1 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/client.rb +79 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/config/meta.json +16 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/config/spec.json +52 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/icon.svg +7 -0
- data/lib/outhad/integrations/source/bigquery/client.rb +98 -0
- data/lib/outhad/integrations/source/bigquery/config/meta.json +16 -0
- data/lib/outhad/integrations/source/bigquery/config/spec.json +83 -0
- data/lib/outhad/integrations/source/bigquery/icon.svg +1 -0
- data/lib/outhad/integrations/source/clickhouse/client.rb +102 -0
- data/lib/outhad/integrations/source/clickhouse/config/meta.json +16 -0
- data/lib/outhad/integrations/source/clickhouse/config/spec.json +42 -0
- data/lib/outhad/integrations/source/clickhouse/icon.svg +25 -0
- data/lib/outhad/integrations/source/databricks/client.rb +98 -0
- data/lib/outhad/integrations/source/databricks/config/meta.json +17 -0
- data/lib/outhad/integrations/source/databricks/config/spec.json +56 -0
- data/lib/outhad/integrations/source/databricks/icon.svg +19 -0
- data/lib/outhad/integrations/source/databrics_model/client.rb +89 -0
- data/lib/outhad/integrations/source/databrics_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/databrics_model/config/meta.json +17 -0
- data/lib/outhad/integrations/source/databrics_model/config/spec.json +63 -0
- data/lib/outhad/integrations/source/databrics_model/icon.svg +19 -0
- data/lib/outhad/integrations/source/firecrawl/client.rb +151 -0
- data/lib/outhad/integrations/source/firecrawl/config/catalog.json +29 -0
- data/lib/outhad/integrations/source/firecrawl/config/meta.json +17 -0
- data/lib/outhad/integrations/source/firecrawl/config/spec.json +31 -0
- data/lib/outhad/integrations/source/firecrawl/icon.svg +4 -0
- data/lib/outhad/integrations/source/generic_open_ai/client.rb +118 -0
- data/lib/outhad/integrations/source/generic_open_ai/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/generic_open_ai/config/meta.json +16 -0
- data/lib/outhad/integrations/source/generic_open_ai/config/spec.json +63 -0
- data/lib/outhad/integrations/source/generic_open_ai/icon.svg +6 -0
- data/lib/outhad/integrations/source/google_vertex_model/client.rb +83 -0
- data/lib/outhad/integrations/source/google_vertex_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/google_vertex_model/config/meta.json +17 -0
- data/lib/outhad/integrations/source/google_vertex_model/config/spec.json +105 -0
- data/lib/outhad/integrations/source/google_vertex_model/icon.svg +2 -0
- data/lib/outhad/integrations/source/http_model/client.rb +108 -0
- data/lib/outhad/integrations/source/http_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/http_model/config/meta.json +16 -0
- data/lib/outhad/integrations/source/http_model/config/spec.json +70 -0
- data/lib/outhad/integrations/source/http_model/icon.svg +9 -0
- data/lib/outhad/integrations/source/intuit_quick_books/client.rb +213 -0
- data/lib/outhad/integrations/source/intuit_quick_books/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/intuit_quick_books/config/meta.json +17 -0
- data/lib/outhad/integrations/source/intuit_quick_books/config/spec.json +44 -0
- data/lib/outhad/integrations/source/intuit_quick_books/icon.svg +1 -0
- data/lib/outhad/integrations/source/maria_db/client.rb +92 -0
- data/lib/outhad/integrations/source/maria_db/config/meta.json +16 -0
- data/lib/outhad/integrations/source/maria_db/config/spec.json +48 -0
- data/lib/outhad/integrations/source/maria_db/icon.svg +15 -0
- data/lib/outhad/integrations/source/odoo/client.rb +106 -0
- data/lib/outhad/integrations/source/odoo/config/meta.json +15 -0
- data/lib/outhad/integrations/source/odoo/config/spec.json +39 -0
- data/lib/outhad/integrations/source/odoo/icon.svg +21 -0
- data/lib/outhad/integrations/source/open_ai/client.rb +118 -0
- data/lib/outhad/integrations/source/open_ai/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/open_ai/config/meta.json +16 -0
- data/lib/outhad/integrations/source/open_ai/config/spec.json +56 -0
- data/lib/outhad/integrations/source/open_ai/icon.svg +1 -0
- data/lib/outhad/integrations/source/oracle_db/client.rb +127 -0
- data/lib/outhad/integrations/source/oracle_db/config/meta.json +16 -0
- data/lib/outhad/integrations/source/oracle_db/config/spec.json +47 -0
- data/lib/outhad/integrations/source/oracle_db/icon.svg +4 -0
- data/lib/outhad/integrations/source/pinecone_db/client.rb +73 -0
- data/lib/outhad/integrations/source/pinecone_db/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/pinecone_db/config/meta.json +16 -0
- data/lib/outhad/integrations/source/pinecone_db/config/spec.json +34 -0
- data/lib/outhad/integrations/source/pinecone_db/icon.svg +2 -0
- data/lib/outhad/integrations/source/postgresql/client.rb +112 -0
- data/lib/outhad/integrations/source/postgresql/config/meta.json +16 -0
- data/lib/outhad/integrations/source/postgresql/config/spec.json +86 -0
- data/lib/outhad/integrations/source/postgresql/icon.svg +20 -0
- data/lib/outhad/integrations/source/qdrant/client.rb +86 -0
- data/lib/outhad/integrations/source/qdrant/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/qdrant/config/meta.json +16 -0
- data/lib/outhad/integrations/source/qdrant/config/spec.json +29 -0
- data/lib/outhad/integrations/source/qdrant/icon.svg +1 -0
- data/lib/outhad/integrations/source/redshift/client.rb +109 -0
- data/lib/outhad/integrations/source/redshift/config/meta.json +16 -0
- data/lib/outhad/integrations/source/redshift/config/spec.json +71 -0
- data/lib/outhad/integrations/source/redshift/icon.svg +15 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/client.rb +133 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/meta.json +18 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/spec.json +53 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/icon.svg +16 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/schema_helper.rb +130 -0
- data/lib/outhad/integrations/source/sftp/client.rb +133 -0
- data/lib/outhad/integrations/source/sftp/config/meta.json +16 -0
- data/lib/outhad/integrations/source/sftp/config/spec.json +59 -0
- data/lib/outhad/integrations/source/sftp/icon.svg +1 -0
- data/lib/outhad/integrations/source/snowflake/client.rb +92 -0
- data/lib/outhad/integrations/source/snowflake/config/meta.json +16 -0
- data/lib/outhad/integrations/source/snowflake/config/spec.json +82 -0
- data/lib/outhad/integrations/source/snowflake/icon.svg +10 -0
- data/lib/outhad/integrations/source/watsonx_ai/client.rb +194 -0
- data/lib/outhad/integrations/source/watsonx_ai/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/watsonx_ai/config/meta.json +16 -0
- data/lib/outhad/integrations/source/watsonx_ai/config/spec.json +74 -0
- data/lib/outhad/integrations/source/watsonx_ai/icon.svg +1 -0
- data/lib/outhad/integrations/source/watsonx_data/client.rb +146 -0
- data/lib/outhad/integrations/source/watsonx_data/config/meta.json +17 -0
- data/lib/outhad/integrations/source/watsonx_data/config/spec.json +72 -0
- data/lib/outhad/integrations/source/watsonx_data/icon.svg +1 -0
- data/lib/outhad/integrations.rb +129 -0
- data/outhad-integrations.gemspec +79 -0
- data/sig/outhad/integrations.rbs +6 -0
- metadata +866 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Outhad::Integrations::Destination
|
4
|
+
module FacebookCustomAudience
|
5
|
+
include Outhad::Integrations::Core
|
6
|
+
class Client < DestinationConnector
|
7
|
+
prepend Outhad::Integrations::Core::RateLimiter
|
8
|
+
MAX_CHUNK_SIZE = 10_000
|
9
|
+
def check_connection(connection_config)
|
10
|
+
connection_config = connection_config.with_indifferent_access
|
11
|
+
access_token = connection_config[:access_token]
|
12
|
+
response = Outhad::Integrations::Core::HttpClient.request(
|
13
|
+
FACEBOOK_AUDIENCE_GET_ALL_ACCOUNTS,
|
14
|
+
HTTP_GET,
|
15
|
+
headers: auth_headers(access_token)
|
16
|
+
)
|
17
|
+
if success?(response)
|
18
|
+
ad_account_exists?(response, connection_config[:ad_account_id])
|
19
|
+
ConnectionStatus.new(status: ConnectionStatusType["succeeded"]).to_outhad_message
|
20
|
+
else
|
21
|
+
ConnectionStatus.new(status: ConnectionStatusType["failed"]).to_outhad_message
|
22
|
+
end
|
23
|
+
rescue StandardError => e
|
24
|
+
ConnectionStatus.new(status: ConnectionStatusType["failed"], message: e.message).to_outhad_message
|
25
|
+
end
|
26
|
+
|
27
|
+
def discover(_connection_config = nil)
|
28
|
+
catalog_json = read_json(CATALOG_SPEC_PATH)
|
29
|
+
catalog = build_catalog(catalog_json)
|
30
|
+
catalog.to_outhad_message
|
31
|
+
rescue StandardError => e
|
32
|
+
handle_exception(e, {
|
33
|
+
context: "FACEBOOK AUDIENCE:DISCOVER:EXCEPTION",
|
34
|
+
type: "error"
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
def write(sync_config, records, _action = "destination_insert")
|
39
|
+
connection_config = sync_config.destination.connection_specification.with_indifferent_access
|
40
|
+
access_token = connection_config[:access_token]
|
41
|
+
url = generate_url(sync_config, connection_config)
|
42
|
+
write_success = 0
|
43
|
+
write_failure = 0
|
44
|
+
records.each_slice(MAX_CHUNK_SIZE) do |chunk|
|
45
|
+
payload = create_payload(chunk, sync_config.stream.json_schema.with_indifferent_access)
|
46
|
+
response = Outhad::Integrations::Core::HttpClient.request(
|
47
|
+
url,
|
48
|
+
sync_config.stream.request_method,
|
49
|
+
payload: payload,
|
50
|
+
headers: auth_headers(access_token)
|
51
|
+
)
|
52
|
+
if success?(response)
|
53
|
+
write_success += chunk.size
|
54
|
+
else
|
55
|
+
write_failure += chunk.size
|
56
|
+
end
|
57
|
+
rescue StandardError => e
|
58
|
+
handle_exception(e, {
|
59
|
+
context: "FACEBOOK:RECORD:WRITE:EXCEPTION",
|
60
|
+
type: "error",
|
61
|
+
sync_id: sync_config.sync_id,
|
62
|
+
sync_run_id: sync_config.sync_run_id
|
63
|
+
})
|
64
|
+
write_failure += chunk.size
|
65
|
+
end
|
66
|
+
|
67
|
+
tracker = Outhad::Integrations::Protocol::TrackingMessage.new(
|
68
|
+
success: write_success,
|
69
|
+
failed: write_failure
|
70
|
+
)
|
71
|
+
tracker.to_outhad_message
|
72
|
+
rescue StandardError => e
|
73
|
+
handle_exception(e, {
|
74
|
+
context: "FACEBOOK:RECORD:WRITE:EXCEPTION",
|
75
|
+
type: "error",
|
76
|
+
sync_id: sync_config.sync_id,
|
77
|
+
sync_run_id: sync_config.sync_run_id
|
78
|
+
})
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def generate_url(sync_config, connection_config)
|
84
|
+
sync_config.stream.url.gsub("{audience_id}", connection_config[:audience_id])
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_payload(records, json_schema)
|
88
|
+
schema, data = extract_schema_and_data(records, json_schema)
|
89
|
+
{
|
90
|
+
"payload" => {
|
91
|
+
"schema" => schema,
|
92
|
+
"data" => data
|
93
|
+
}
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def extract_schema_and_data(records, json_schema)
|
98
|
+
schema_properties = json_schema[:properties]
|
99
|
+
schema = records.first.keys.map(&:to_s).map(&:upcase)
|
100
|
+
data = []
|
101
|
+
records.each do |record|
|
102
|
+
encrypted_data_array = []
|
103
|
+
record.with_indifferent_access.each do |key, value|
|
104
|
+
schema_key = key.upcase
|
105
|
+
encrypted_value = schema_properties[schema_key] && schema_properties[schema_key]["x-hashRequired"] ? Digest::SHA256.hexdigest(value.to_s) : value
|
106
|
+
encrypted_data_array << encrypted_value
|
107
|
+
end
|
108
|
+
data << encrypted_data_array
|
109
|
+
end
|
110
|
+
[schema, data]
|
111
|
+
end
|
112
|
+
|
113
|
+
def ad_account_exists?(response, ad_account_id)
|
114
|
+
return if extract_data(response).any? { |ad_account| ad_account["id"] == "act_#{ad_account_id}" }
|
115
|
+
|
116
|
+
raise ArgumentError, "Ad account not found in business account"
|
117
|
+
end
|
118
|
+
|
119
|
+
def extract_data(response)
|
120
|
+
response_body = response.body
|
121
|
+
JSON.parse(response_body)["data"] if response_body
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
{
|
2
|
+
"request_rate_limit": 600,
|
3
|
+
"request_rate_limit_unit": "minute",
|
4
|
+
"request_rate_concurrency": 10,
|
5
|
+
"streams": [
|
6
|
+
{
|
7
|
+
"name": "audience",
|
8
|
+
"action": "create",
|
9
|
+
"method": "POST",
|
10
|
+
"batch_support": true,
|
11
|
+
"batch_size": 10000,
|
12
|
+
"url": "https://graph.facebook.com/v18.0/{audience_id}/users",
|
13
|
+
"json_schema": {
|
14
|
+
"type": "object",
|
15
|
+
"additionalProperties": true,
|
16
|
+
"properties": {
|
17
|
+
"EMAIL": { "type": ["string", "null"], "default": null, "title": "Email", "x-hashRequired": true },
|
18
|
+
"PHONE": { "type": ["string", "null"], "default": null, "title": "Phone", "x-hashRequired": true },
|
19
|
+
"GEN": { "type": ["string", "null"], "default": null, "title": "Gender", "x-hashRequired": true },
|
20
|
+
"FI": { "type": ["string", "null"], "default": null, "title": "First Initial", "x-hashRequired": true },
|
21
|
+
"FN": { "type": ["string", "null"], "default": null, "title": "First Name", "x-hashRequired": true },
|
22
|
+
"DOBD": { "type": ["string", "null"], "default": null, "title": "Date of Birth (Day)", "x-hashRequired": true },
|
23
|
+
"DOBM": { "type": ["string", "null"], "default": null, "title": "Date of Birth (Month)", "x-hashRequired": true },
|
24
|
+
"DOBY": { "type": ["string", "null"], "default": null, "title": "Date of Birth (Year)", "x-hashRequired": true },
|
25
|
+
"LN": { "type": ["string", "null"], "default": null, "title": "Last Name", "x-hashRequired": true },
|
26
|
+
"CT": { "type": ["string", "null"], "default": null, "title": "City", "x-hashRequired": true },
|
27
|
+
"ST": { "type": ["string", "null"], "default": null, "title": "State", "x-hashRequired": true },
|
28
|
+
"ZIP": { "type": ["string", "null"], "default": null, "title": "Zip Code", "x-hashRequired": true },
|
29
|
+
"COUNTRY": { "type": ["string", "null"], "default": null, "title": "Country", "x-hashRequired": true },
|
30
|
+
"EXTERN_ID": { "type": ["string", "null"], "default": null, "title": "External ID", "x-hashRequired": false},
|
31
|
+
"LOOKALIKE_VALUE": { "type": ["number", "null"], "default": null, "title": "Lookalike Value", "x-hashRequired": false },
|
32
|
+
"MADID": { "type": ["string", "null"], "default": null, "title": "Mobile ID", "x-hashRequired": false },
|
33
|
+
"PAGEUID": { "type": ["string", "null"], "default": null, "title": "Page-Scoped ID", "x-hashRequired": false }
|
34
|
+
}
|
35
|
+
},
|
36
|
+
"supported_sync_modes": ["incremental"],
|
37
|
+
"source_defined_cursor": true,
|
38
|
+
"default_cursor_field": ["updated"],
|
39
|
+
"source_defined_primary_key": [["email"]]
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"name": "FacebookCustomAudience",
|
4
|
+
"title": "Facebook Custom Audiences",
|
5
|
+
"connector_type": "destination",
|
6
|
+
"category": "Ad-Tech",
|
7
|
+
"documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/adtech/facebook-ads",
|
8
|
+
"github_issue_label": "destination-facebook",
|
9
|
+
"icon": "icon.svg",
|
10
|
+
"license": "MIT",
|
11
|
+
"release_stage": "alpha",
|
12
|
+
"support_level": "community",
|
13
|
+
"tags": ["language:ruby", "outhad"]
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/adtech/facebook-ads",
|
3
|
+
"stream_type": "static",
|
4
|
+
"connection_specification": {
|
5
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
6
|
+
"title": "Facebook Custom Audiences",
|
7
|
+
"type": "object",
|
8
|
+
"required": ["access_token", "ad_account_id", "audience_id"],
|
9
|
+
"properties": {
|
10
|
+
"access_token": {
|
11
|
+
"type": "string",
|
12
|
+
"outhad_secret": true,
|
13
|
+
"title": "Access Token",
|
14
|
+
"order": 0
|
15
|
+
},
|
16
|
+
"ad_account_id": {
|
17
|
+
"type": "string",
|
18
|
+
"title": "Ad Account Id",
|
19
|
+
"order": 1
|
20
|
+
},
|
21
|
+
"audience_id": {
|
22
|
+
"type": "string",
|
23
|
+
"title": "Audience Id",
|
24
|
+
"order": 2
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1365.3333 1365.3333" height="1365.3333" width="1365.3333" xml:space="preserve" id="svg2" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
2
|
+
<metadata id="metadata8">
|
3
|
+
<rdf:RDF>
|
4
|
+
<cc:Work rdf:about="">
|
5
|
+
<dc:format>
|
6
|
+
image/svg+xml
|
7
|
+
</dc:format>
|
8
|
+
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage">
|
9
|
+
</dc:type>
|
10
|
+
</cc:Work>
|
11
|
+
</rdf:RDF>
|
12
|
+
</metadata>
|
13
|
+
<defs id="defs6">
|
14
|
+
</defs>
|
15
|
+
<g transform="matrix(1.3333333,0,0,-1.3333333,0,1365.3333)" id="g10">
|
16
|
+
<g transform="scale(0.1)" id="g12">
|
17
|
+
<path id="path14" style="fill:#1877f2;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 10240,5120 c 0,2827.7 -2292.3,5120 -5120,5120 C 2292.3,10240 0,7947.7 0,5120 0,2564.46 1872.31,446.301 4320,62.1992 V 3640 H 3020 v 1480 h 1300 v 1128 c 0,1283.2 764.38,1992 1933.9,1992 560.17,0 1146.1,-100 1146.1,-100 V 6880 H 6754.38 C 6118.35,6880 5920,6485.33 5920,6080.43 V 5120 H 7340 L 7113,3640 H 5920 V 62.1992 C 8367.69,446.301 10240,2564.46 10240,5120">
|
18
|
+
</path>
|
19
|
+
<path id="path16" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 7113,3640 227,1480 H 5920 v 960.43 c 0,404.9 198.35,799.57 834.38,799.57 H 7400 v 1260 c 0,0 -585.93,100 -1146.1,100 C 5084.38,8240 4320,7531.2 4320,6248 V 5120 H 3020 V 3640 H 4320 V 62.1992 C 4580.67,21.3008 4847.84,0 5120,0 c 272.16,0 539.33,21.3008 800,62.1992 V 3640 h 1193">
|
20
|
+
</path>
|
21
|
+
</g>
|
22
|
+
</g>
|
23
|
+
</svg>
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Outhad
|
4
|
+
module Integrations
|
5
|
+
module Destination
|
6
|
+
module GoogleSheets
|
7
|
+
include Outhad::Integrations::Core
|
8
|
+
|
9
|
+
class Client < DestinationConnector
|
10
|
+
prepend Outhad::Integrations::Core::Fullrefresher
|
11
|
+
prepend Outhad::Integrations::Core::RateLimiter
|
12
|
+
MAX_CHUNK_SIZE = 10_000
|
13
|
+
|
14
|
+
def check_connection(connection_config)
|
15
|
+
connection_config = connection_config.with_indifferent_access
|
16
|
+
authorize_client(connection_config)
|
17
|
+
fetch_google_spread_sheets(connection_config)
|
18
|
+
success_status
|
19
|
+
rescue StandardError => e
|
20
|
+
failure_status(e)
|
21
|
+
end
|
22
|
+
|
23
|
+
def discover(connection_config)
|
24
|
+
connection_config = connection_config.with_indifferent_access
|
25
|
+
authorize_client(connection_config)
|
26
|
+
spreadsheets = fetch_google_spread_sheets(connection_config)
|
27
|
+
catalog = build_catalog_from_spreadsheets(spreadsheets, connection_config)
|
28
|
+
catalog.to_outhad_message
|
29
|
+
rescue StandardError => e
|
30
|
+
handle_exception(e, {
|
31
|
+
context: "GOOGLE_SHEETS:CRM:DISCOVER:EXCEPTION",
|
32
|
+
type: "error"
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
def write(sync_config, records, action = "create")
|
37
|
+
setup_write_environment(sync_config, action)
|
38
|
+
process_record_chunks(records, sync_config)
|
39
|
+
rescue StandardError => e
|
40
|
+
handle_exception(e, {
|
41
|
+
context: "GOOGLE_SHEETS:CRM:WRITE:EXCEPTION",
|
42
|
+
type: "error",
|
43
|
+
sync_id: sync_config.sync_id,
|
44
|
+
sync_run_id: sync_config.sync_run_id
|
45
|
+
})
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear_all_records(sync_config)
|
49
|
+
setup_write_environment(sync_config, "clear")
|
50
|
+
connection_specification = sync_config.destination.connection_specification.with_indifferent_access
|
51
|
+
spreadsheet = fetch_google_spread_sheets(connection_specification)
|
52
|
+
sheet_ids = spreadsheet.sheets.map(&:properties).map(&:sheet_id)
|
53
|
+
|
54
|
+
delete_extra_sheets(sheet_ids)
|
55
|
+
|
56
|
+
unless sheet_ids.empty?
|
57
|
+
clear_response = clear_sheet_data(spreadsheet.sheets.first.properties.title)
|
58
|
+
return control_message("Successfully cleared data.", "succeeded") if clear_response&.cleared_range
|
59
|
+
end
|
60
|
+
|
61
|
+
control_message("Failed to clear data.", "failed")
|
62
|
+
rescue StandardError => e
|
63
|
+
control_message(e.message, "failed")
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# To define the level of access granted to your app, you need to identify and declare authorization scopes which is provided by google scopse https://developers.google.com/sheets/api/scopes
|
69
|
+
def authorize_client(config)
|
70
|
+
credentials = config[:credentials_json]
|
71
|
+
@client = Google::Apis::SheetsV4::SheetsService.new
|
72
|
+
@client.authorization = Google::Auth::ServiceAccountCredentials.make_creds(
|
73
|
+
json_key_io: StringIO.new(credentials.to_json),
|
74
|
+
scope: GOOGLE_SHEETS_SCOPE
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Extract spreadsheet id from the spreadsheet link and return the metadata for all the sheets
|
79
|
+
def fetch_google_spread_sheets(connection_config)
|
80
|
+
spreadsheet_id = extract_spreadsheet_id(connection_config[:spreadsheet_link])
|
81
|
+
@client.get_spreadsheet(spreadsheet_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
# dynamically builds catalog based on spreadsheet metadata
|
85
|
+
def build_catalog_from_spreadsheets(spreadsheet, connection_config)
|
86
|
+
catalog = build_catalog(load_catalog)
|
87
|
+
@spreadsheet_id = extract_spreadsheet_id(connection_config[:spreadsheet_link])
|
88
|
+
|
89
|
+
spreadsheet.sheets.each do |sheet|
|
90
|
+
process_sheet_for_catalog(sheet, catalog)
|
91
|
+
end
|
92
|
+
|
93
|
+
catalog
|
94
|
+
end
|
95
|
+
|
96
|
+
# Builds catalog for the single spreadsheet based on column name
|
97
|
+
def process_sheet_for_catalog(sheet, catalog)
|
98
|
+
sheet_name, last_column_index = extract_sheet_properties(sheet)
|
99
|
+
column_names = fetch_column_names(sheet_name, last_column_index)
|
100
|
+
catalog.streams << generate_json_schema(column_names, sheet_name) if column_names
|
101
|
+
end
|
102
|
+
|
103
|
+
def extract_sheet_properties(sheet)
|
104
|
+
[sheet.properties.title, sheet.properties.grid_properties.column_count]
|
105
|
+
end
|
106
|
+
|
107
|
+
def fetch_column_names(sheet_name, last_column_index)
|
108
|
+
header_range = generate_header_range(sheet_name, last_column_index)
|
109
|
+
spread_sheet_value(header_range)&.flatten
|
110
|
+
end
|
111
|
+
|
112
|
+
def spread_sheet_value(header_range)
|
113
|
+
@spread_sheet_value ||= @client.get_spreadsheet_values(@spreadsheet_id, header_range).values
|
114
|
+
end
|
115
|
+
|
116
|
+
def generate_header_range(sheet_name, last_column_index)
|
117
|
+
"#{sheet_name}!A1:#{column_index_to_letter(last_column_index)}1"
|
118
|
+
end
|
119
|
+
|
120
|
+
def column_index_to_letter(index)
|
121
|
+
("A".."ZZZ").to_a[index - 1]
|
122
|
+
end
|
123
|
+
|
124
|
+
def generate_json_schema(column_names, sheet_name)
|
125
|
+
{
|
126
|
+
name: sheet_name,
|
127
|
+
action: "create",
|
128
|
+
batch_support: true,
|
129
|
+
batch_size: 10_000,
|
130
|
+
json_schema: generate_properties_schema(column_names),
|
131
|
+
supported_sync_modes: %w[incremental full_refresh]
|
132
|
+
}.with_indifferent_access
|
133
|
+
end
|
134
|
+
|
135
|
+
def generate_properties_schema(column_names)
|
136
|
+
properties = column_names.each_with_object({}) do |field, props|
|
137
|
+
props[field] = { "type" => "string" }
|
138
|
+
end
|
139
|
+
|
140
|
+
{ "$schema" => JSON_SCHEMA_URL, "type" => "object", "properties" => properties }
|
141
|
+
end
|
142
|
+
|
143
|
+
def setup_write_environment(sync_config, action)
|
144
|
+
@action = sync_config.stream.action || action
|
145
|
+
connection_specification = sync_config.destination.connection_specification.with_indifferent_access
|
146
|
+
@spreadsheet_id = extract_spreadsheet_id(connection_specification[:spreadsheet_link])
|
147
|
+
authorize_client(connection_specification)
|
148
|
+
end
|
149
|
+
|
150
|
+
def extract_spreadsheet_id(link)
|
151
|
+
link[GOOGLE_SPREADSHEET_ID_REGEX, 1] || link
|
152
|
+
end
|
153
|
+
|
154
|
+
# Batch has a limit of sending 2MB data. So creating a chunk of records to meet that limit
|
155
|
+
def process_record_chunks(records, sync_config)
|
156
|
+
log_message_array = []
|
157
|
+
write_success = 0
|
158
|
+
write_failure = 0
|
159
|
+
|
160
|
+
records.each_slice(MAX_CHUNK_SIZE) do |chunk|
|
161
|
+
values = prepare_chunk_values(chunk, sync_config.stream)
|
162
|
+
request, response = *update_sheet_values(values, sync_config.stream.name)
|
163
|
+
write_success += values.size
|
164
|
+
log_message_array << log_request_response("info", request, response)
|
165
|
+
rescue StandardError => e
|
166
|
+
handle_exception(e, {
|
167
|
+
context: "GOOGLE_SHEETS:RECORD:WRITE:EXCEPTION",
|
168
|
+
type: "error",
|
169
|
+
sync_id: sync_config.sync_id,
|
170
|
+
sync_run_id: sync_config.sync_run_id
|
171
|
+
})
|
172
|
+
write_failure += chunk.size
|
173
|
+
log_message_array << log_request_response("error", request, e.message)
|
174
|
+
end
|
175
|
+
tracking_message(write_success, write_failure, log_message_array)
|
176
|
+
end
|
177
|
+
|
178
|
+
# We need to format the data to adhere to google sheets API format. This converts the sync mapped data to 2D array format expected by google sheets API
|
179
|
+
def prepare_chunk_values(chunk, stream)
|
180
|
+
last_column_index = spread_sheet_value(stream.name).count
|
181
|
+
fields = fetch_column_names(stream.name, last_column_index)
|
182
|
+
|
183
|
+
chunk.map do |row|
|
184
|
+
row_values = Array.new(fields.size, nil)
|
185
|
+
row.each do |key, value|
|
186
|
+
index = fields.index(key.to_s)
|
187
|
+
row_values[index] = value if index
|
188
|
+
end
|
189
|
+
row_values
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def update_sheet_values(values, stream_name)
|
194
|
+
row_count = spread_sheet_value(stream_name).count
|
195
|
+
range = "#{stream_name}!A#{row_count + 1}"
|
196
|
+
value_range = Google::Apis::SheetsV4::ValueRange.new(range: range, values: values)
|
197
|
+
|
198
|
+
batch_update_request = Google::Apis::SheetsV4::BatchUpdateValuesRequest.new(
|
199
|
+
value_input_option: "RAW",
|
200
|
+
data: [value_range]
|
201
|
+
)
|
202
|
+
|
203
|
+
# TODO: Remove & this is added for the test to pass we need
|
204
|
+
response = @client&.batch_update_values(@spreadsheet_id, batch_update_request)
|
205
|
+
[batch_update_request, response]
|
206
|
+
end
|
207
|
+
|
208
|
+
def load_catalog
|
209
|
+
read_json(CATALOG_SPEC_PATH)
|
210
|
+
end
|
211
|
+
|
212
|
+
def delete_extra_sheets(sheet_ids)
|
213
|
+
# Leave one sheet intact as a spreadsheet must have at least one sheet.
|
214
|
+
# Delete all other sheets.
|
215
|
+
(sheet_ids.length - 1).times do |i|
|
216
|
+
request = Google::Apis::SheetsV4::BatchUpdateSpreadsheetRequest.new(
|
217
|
+
requests: [{ delete_sheet: { sheet_id: sheet_ids[i + 1] } }]
|
218
|
+
)
|
219
|
+
@client.batch_update_spreadsheet(@spreadsheet_id, request)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def clear_sheet_data(sheet_title)
|
224
|
+
clear_request = Google::Apis::SheetsV4::ClearValuesRequest.new
|
225
|
+
@client&.clear_values(@spreadsheet_id, "#{sheet_title}!A2:Z", clear_request)
|
226
|
+
end
|
227
|
+
|
228
|
+
def control_message(message, status)
|
229
|
+
ControlMessage.new(
|
230
|
+
type: "full_refresh",
|
231
|
+
emitted_at: Time.now.to_i,
|
232
|
+
status: ConnectionStatusType[status],
|
233
|
+
meta: { detail: message }
|
234
|
+
).to_outhad_message
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"name": "GoogleSheets",
|
4
|
+
"title": "Google Sheets",
|
5
|
+
"connector_type": "destination",
|
6
|
+
"category": "Productivity Tools",
|
7
|
+
"documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/productivity-tools/google-sheets",
|
8
|
+
"github_issue_label": "destination-google-sheets",
|
9
|
+
"icon": "icon.svg",
|
10
|
+
"license": "MIT",
|
11
|
+
"release_stage": "alpha",
|
12
|
+
"support_level": "community",
|
13
|
+
"tags": ["language:ruby", "outhad"]
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
{
|
2
|
+
"documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/productivity-tools/google-sheets",
|
3
|
+
"stream_type": "dynamic",
|
4
|
+
"connection_specification": {
|
5
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
6
|
+
"title": "Google Sheets",
|
7
|
+
"type": "object",
|
8
|
+
"required": ["credentials_json"],
|
9
|
+
"properties": {
|
10
|
+
"spreadsheet_link": {
|
11
|
+
"type": "string"
|
12
|
+
},
|
13
|
+
"credentials_json": {
|
14
|
+
"type": "object",
|
15
|
+
"description": "You can get the keys from the Google Cloud web console. First, go to the IAM page and select Service Accounts from the left menu. Next, locate your service account in the list, click on its Keys tab, and then click Add Key. Lastly, click Create new key and select JSON.",
|
16
|
+
"title": "",
|
17
|
+
"properties": {
|
18
|
+
"type": {
|
19
|
+
"type": "string",
|
20
|
+
"enum": ["service_account"]
|
21
|
+
},
|
22
|
+
"project_id": {
|
23
|
+
"type": "string"
|
24
|
+
},
|
25
|
+
"private_key_id": {
|
26
|
+
"type": "string"
|
27
|
+
},
|
28
|
+
"private_key": {
|
29
|
+
"type": "string",
|
30
|
+
"outhad_secret": true
|
31
|
+
},
|
32
|
+
"client_email": {
|
33
|
+
"type": "string",
|
34
|
+
"format": "email"
|
35
|
+
},
|
36
|
+
"client_id": {
|
37
|
+
"type": "string"
|
38
|
+
},
|
39
|
+
"auth_uri": {
|
40
|
+
"type": "string",
|
41
|
+
"format": "uri"
|
42
|
+
},
|
43
|
+
"token_uri": {
|
44
|
+
"type": "string",
|
45
|
+
"format": "uri"
|
46
|
+
},
|
47
|
+
"auth_provider_x509_cert_url": {
|
48
|
+
"type": "string",
|
49
|
+
"format": "uri"
|
50
|
+
},
|
51
|
+
"client_x509_cert_url": {
|
52
|
+
"type": "string",
|
53
|
+
"format": "uri"
|
54
|
+
},
|
55
|
+
"universe_domain": {
|
56
|
+
"type": "string"
|
57
|
+
}
|
58
|
+
},
|
59
|
+
"required": [
|
60
|
+
"type",
|
61
|
+
"project_id",
|
62
|
+
"private_key_id",
|
63
|
+
"private_key",
|
64
|
+
"client_email",
|
65
|
+
"client_id",
|
66
|
+
"auth_uri",
|
67
|
+
"token_uri",
|
68
|
+
"auth_provider_x509_cert_url",
|
69
|
+
"client_x509_cert_url",
|
70
|
+
"universe_domain"
|
71
|
+
]
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242423 333333" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"><defs><mask id="c"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="200294" y1="91174.8" x2="200294" y2="176113"><stop offset="0" stop-opacity=".02" stop-color="#fff"/><stop offset="1" stop-opacity=".2" stop-color="#fff"/></linearGradient><path fill="url(#a)" d="M158015 84111h84558v99065h-84558z"/></mask><mask id="e"><radialGradient id="b" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="0" fx="0" fy="0"><stop offset="0" stop-opacity="0" stop-color="#fff"/><stop offset="1" stop-opacity=".098" stop-color="#fff"/></radialGradient><path fill="url(#b)" d="M-150-150h242723v333633H-150z"/></mask><radialGradient id="f" gradientUnits="userSpaceOnUse" cx="9696.85" cy="10000.4" r="166667" fx="9696.85" fy="10000.4"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff"/></radialGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="200294" y1="95125.2" x2="200294" y2="172162"><stop offset="0" stop-color="#263138"/><stop offset="1" stop-color="#263138"/></linearGradient></defs><g fill-rule="nonzero"><path d="M151513 0H22729C10227 0 1 10227 1 22728v287877c0 12505 10227 22728 22728 22728h196966c12505 0 22728-10224 22728-22728V90911l-53028-37880L151513 0z" fill="#0f9c57"/><path d="M60606 162880v109853h121216V162880H60606zm53032 94698H75757v-18938h37881v18938zm0-30301H75757v-18946h37881v18946zm0-30310H75757v-18936h37881v18936zm53030 60611h-37884v-18938h37884v18938zm0-30301h-37884v-18946h37884v18946zm0-30310h-37884v-18936h37884v18936z" fill="#f0f0f0"/><path mask="url(#c)" fill="url(#d)" d="M158165 84261l84258 84245V90911z"/><path d="M151513 0v68184c0 12557 10173 22727 22727 22727h68183L151513 0z" fill="#87cdac"/><path d="M22728 0C10226 0 0 10227 0 22729v1893C0 12123 10227 1894 22728 1894h128784V1H22728z" fill="#fff" fill-opacity=".2"/><path d="M219694 331443H22728C10226 331443 0 321213 0 308715v1890c0 12505 10227 22728 22728 22728h196966c12505 0 22728-10224 22728-22728v-1890c0 12499-10224 22728-22728 22728z" fill="#263138" fill-opacity=".2"/><path d="M174239 90911c-12554 0-22727-10170-22727-22727v1893c0 12557 10173 22727 22727 22727h68183v-1893h-68183z" fill="#263138" fill-opacity=".102"/><path d="M151513 0H22729C10227 0 1 10227 1 22729v287876c0 12505 10227 22728 22728 22728h196966c12505 0 22728-10224 22728-22728V90911L151513 0z" mask="url(#e)" fill="url(#f)"/></g></svg>
|