diff --git a/lib/connectors/campaignmonitor.rb b/lib/connectors/campaignmonitor.rb new file mode 100644 index 0000000..9052d18 --- /dev/null +++ b/lib/connectors/campaignmonitor.rb @@ -0,0 +1,40 @@ +module Connectors + class CampaignMonitor + def self.call(params:, auth:) + new(params, auth) + end + + def initialize(params, auth) + @params = params + @auth = auth + @refresh_token = auth.credentials.refresh_token + @oauth_token = auth.credentials.token + @expires = auth.credentials.expires_at + end + + attr_reader :params, :auth + private :params, :auth + + def connector_code + "campaignmonitor" + end + + def description + "campaignmonitor mailinglist" + end + + def account_identifiers + { + #there is nothing from Omniauth that we could use + } + end + + def credential_details + { + refresh_token: @refresh_token, + oauth_token: @oauth_token, + expires: @expires, + } + end + end +end \ No newline at end of file diff --git a/lib/external_service_new/campaignmonitor_dispatcher.rb b/lib/external_service_new/campaignmonitor_dispatcher.rb new file mode 100644 index 0000000..51a7009 --- /dev/null +++ b/lib/external_service_new/campaignmonitor_dispatcher.rb @@ -0,0 +1,40 @@ +require "oj" +require "rest_client" +require "external_service_new/rest_client_dispatcher" +require "createsend" + +module ExternalServiceNew + class CampaignMonitorDispatcher < RestClientDispatcher + PAGE_SIZE_MAX = 1000 + PAGE_SIZE_MIN = 10 + + def initialize(account_identifiers: nil, credential_details:, sleep_time_seconds: 5, client: RestClient) + account_identifiers = account_identifiers.symbolize_keys + credential_details = credential_details.symbolize_keys + @auth = { + access_token: credential_details.fetch(:oauth_token), + refresh_token: credential_details.fetch(:refresh_token) + } + + cs = CreateSend::CreateSend.new @auth + clients = cs.clients + @client = CreateSend::Client.new @auth, clients[0].ClientID + end + + #method = :lists will get the lists + #method = :subscribers get the subscribers of a list + def dispatch(method, id: nil, page: 1, page_size: PAGE_SIZE_MAX) + super() do + if (method == :lists) + @client.lists + elsif (method == :subscribers) + if (page_size < PAGE_SIZE_MIN) + page_size = PAGE_SIZE_MIN + end + list_client = CreateSend::List.new @auth, id + list_client.active("", page, page_size, "email", "asc") + end + end + end + end +end diff --git a/lib/external_service_new/campaignmonitor_downloader.rb b/lib/external_service_new/campaignmonitor_downloader.rb new file mode 100644 index 0000000..4d15fd6 --- /dev/null +++ b/lib/external_service_new/campaignmonitor_downloader.rb @@ -0,0 +1,59 @@ +module ExternalServiceNew + class CampaignMonitorDownloader + def initialize(dispatcher:, logger:nil) + @dispatcher = dispatcher + @logger = logger + end + + def each_list(&block) + return to_enum(:each_list) unless block + response = dispatcher.dispatch(:lists).each do |list| + # We are doing an other request to get the total number of email by list + email_count = dispatcher.dispatch(:subscribers, id:list.ListID, page_size:10) + block.call(list[:ListID], list[:Name], email_count[:TotalNumberOfRecords]) + end + end + + def each_email(list_id:, &block) + raise "list_id must not be nil" unless list_id + CreatesendInternalDownloader.new( + dispatcher: dispatcher, + logger: logger + ).each_email(list_id: list_id, &block) + end + + private + + attr_reader :dispatcher, :logger + end + + class CreatesendInternalDownloader + def initialize(dispatcher:, filters: nil, logger:nil) + raise "dispatcher must not be nil, found #{dispatcher.inspect}" unless dispatcher + + @dispatcher = dispatcher + @filters = filters + @logger = logger + end + + def each_email(list_id:, &block) + page = 1 + return to_enum(:each_email) unless block + logger && logger.info("Downloading Campaign Monitor ListId: #{list_id} with #{filters ? filters.inspect : "no filters"}") + + loop do + response = dispatcher.dispatch(:subscribers, id: list_id, page: page) + break if response[:Results].empty? + response[:Results].each{|contact| yield(contact[:EmailAddress])} + + page +=1 + end + + logger && logger.info("Downloaded Campaign Monitor ListID: #{list_id}") + end + + private + + attr_reader :dispatcher, :filters, :logger + end +end diff --git a/lib/external_service_new/zendesk_dispatcher.rb b/lib/external_service_new/zendesk_dispatcher.rb index 6ac636d..f8ebea0 100644 --- a/lib/external_service_new/zendesk_dispatcher.rb +++ b/lib/external_service_new/zendesk_dispatcher.rb @@ -21,7 +21,7 @@ def initialize(account_identifiers: nil, credential_details:, sleep_time_seconds def dispatch(method, path) super() do - @client.search(method => path).fetch() + @client.search(method => path) end end end diff --git a/lib/external_service_new/zendesk_downloader.rb b/lib/external_service_new/zendesk_downloader.rb index 62d9af2..8308fa8 100644 --- a/lib/external_service_new/zendesk_downloader.rb +++ b/lib/external_service_new/zendesk_downloader.rb @@ -27,6 +27,8 @@ def each_email(id: nil, &block) end class ZendeskInternalDownloader + # maximum of 100 records per page + PER_PAGE = 100 def initialize(dispatcher:, filters: nil, logger:nil) raise "dispatcher must not be nil, found #{dispatcher.inspect}" unless dispatcher @@ -36,17 +38,26 @@ def initialize(dispatcher:, filters: nil, logger:nil) end def each_email(&block) + page = 1 return to_enum(:each_email) unless block logger && logger.info("Downloading Zendesk Customer List with #{filters ? filters.inspect : "no filters"}") - response = dispatcher.dispatch(:query, "type:user role:end-user") - response.each {|contact| yield(contact["email"])} + loop do + response = dispatcher.dispatch(:query, each_email_path).per_page(PER_PAGE).page(page).fetch + break if response.empty? + response.each{|contact| yield(contact["email"])} + + page +=1 + end logger && logger.info("Downloaded Zendesk )Customer List") end private + def each_email_path + "type:user role:end-user" + end attr_reader :dispatcher, :filters, :logger end end diff --git a/lib/wafflehouse.rb b/lib/wafflehouse.rb index 508d901..711b051 100644 --- a/lib/wafflehouse.rb +++ b/lib/wafflehouse.rb @@ -1,9 +1,12 @@ +require "connectors/campaignmonitor" require "connectors/hubspot" require "connectors/mailchimp" require "connectors/shopify" require "connectors/salesforce" require "connectors/zendesk" require "external_service_new/rest_client_dispatcher" +require "external_service_new/campaignmonitor_dispatcher" +require "external_service_new/campaignmonitor_downloader" require "external_service_new/hubspot_dispatcher" require "external_service_new/hubspot_downloader" require "external_service_new/mailchimp_dispatcher" diff --git a/lib/wafflehouse/version.rb b/lib/wafflehouse/version.rb index 707aefc..ae99155 100644 --- a/lib/wafflehouse/version.rb +++ b/lib/wafflehouse/version.rb @@ -1,3 +1,3 @@ module Wafflehouse - VERSION = "1.2.2" + VERSION = "1.3.0" end diff --git a/wafflehouse.gemspec b/wafflehouse.gemspec index a69fad5..79e3b97 100644 --- a/wafflehouse.gemspec +++ b/wafflehouse.gemspec @@ -32,6 +32,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'oj' spec.add_dependency 'rest-client' spec.add_dependency 'zendesk_api' + spec.add_dependency 'createsend' end