mass-client 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a619577f5edc948803f9f6259ea6f4d73b2dfc10b2edbd2afd416940ce8f6f8e
4
+ data.tar.gz: f58d14d86a1734b5ff228743edfc19783f644ce728c32279d338372c8edcbda1
5
+ SHA512:
6
+ metadata.gz: c6fa03f641077d58980e0b19b6cf8140e0883705b255d687ec8a1019b64ef2e8f0474b4d4cfa3b2d9d30b28991328cdd62548b8380786ec313a9563470fb0426
7
+ data.tar.gz: '096188736400e59e26dc19eef3e6a91436c8da8fc7a24b65a84e67ea3df8504a7973309f1a58a8c2bf359660f88c38dd5dcaeea054680b90372f08cc2462f684'
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Channel < BlackStack::Base
3
+ def self.object_name
4
+ 'channel'
5
+ end
6
+ end
7
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Company < BlackStack::Base
3
+ def self.object_name
4
+ 'company'
5
+ end
6
+ end
7
+ end # module Mass
@@ -0,0 +1,14 @@
1
+ module Mass
2
+ class ConnectionCheck < BlackStack::Base
3
+ attr_accessor :profile
4
+
5
+ def self.object_name
6
+ 'connectioncheck'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ self.profile = Mass::Profile.get(h['id_profile']).child_class_instance if h['id_profile']
12
+ end
13
+ end # class ConnectionCheck
14
+ end # module Mass
@@ -0,0 +1,8 @@
1
+ module Mass
2
+ class DataType < BlackStack::Base
3
+ def self.object_name
4
+ 'data_type'
5
+ end
6
+
7
+ end # class DataType
8
+ end # module Mass
@@ -0,0 +1,51 @@
1
+ module Mass
2
+ class Enrichment < BlackStack::Base
3
+ attr_accessor :type, :profile, :lead, :company, :profile_type
4
+
5
+ def self.object_name
6
+ 'enrichment'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ self.type = Mass::EnrichmentType.new(h['enrichment_type_desc']) if h['enrichment_type_desc']
12
+ self.profile = Mass::Profile.new(h['profile']).child_class_instance if h['profile']
13
+ self.lead = Mass::Lead.new(h['lead']) if h['lead']
14
+ self.company = Mass::Company.new(h['company']) if h['company']
15
+ self.profile_type = Mass::ProfileType.page(
16
+ page: 1,
17
+ limit: 1,
18
+ filters: {
19
+ name: h['profile_type']
20
+ }
21
+ ).first.child_class_instance if h['profile_type']
22
+ end
23
+
24
+ # convert the enrichment_type into the ruby class to create an instance.
25
+ # example: Apollo --> Mass::ApolloAPI
26
+ def class_name_from_enrichment_type
27
+ enrichment_type = self.desc['enrichment_type']
28
+ "Mass::#{enrichment_type}"
29
+ end
30
+
31
+ # crate an instance of the profile type using the class defined in the `desc['name']` attribute.
32
+ # override the base method
33
+ def child_class_instance
34
+ enrichment_type = self.desc['enrichment_type']
35
+ key = self.class_name_from_enrichment_type
36
+ raise "Source code of enrichment type #{enrichment_type} not found. Create a class #{key} in the folder `/lib` of your mass-sdk." unless Kernel.const_defined?(key)
37
+ ret = Kernel.const_get(key).new(self.desc)
38
+ return ret
39
+ end
40
+
41
+ # Update the lead or company with new information.
42
+ #
43
+ def do(
44
+ logger:nil
45
+ )
46
+ # TODO: Code Me!
47
+ end
48
+
49
+
50
+ end # class Enrichment
51
+ end # module Mass
@@ -0,0 +1,60 @@
1
+ module Mass
2
+ # Enrichment module.
3
+ # List of methods you have to overload if you develop a profile type that supports enrichment operations.
4
+ #
5
+ class EnrichmentType < BlackStack::Base
6
+ def self.object_name
7
+ 'enrichment_type'
8
+ end # def self.object_name
9
+
10
+ # If the profile `access` is not `:rpa`, raise an exception.
11
+ # Return `true` if the `url` is valid.
12
+ # Return `false` if the `url` is not valid.
13
+ #
14
+ # Overload this method in the child class.
15
+ #
16
+ def valid_enrichment_url?(url:)
17
+ # If the profile `access` is not `:rpa`, raise an exception.
18
+ raise "The method `valid_enrichment_url?` is not allowed for #{self.access.to_s} access." if self.access != :rpa
19
+ # Return `true` if the `url` is valid.
20
+ # Return `false` if the `url` is not valid.
21
+ true
22
+ end # def valid_enrichment_url?
23
+
24
+ # Return the same URL in a normalized form:
25
+ # - remove all GET parameters.
26
+ # - remove all trailing slashes.
27
+ #
28
+ # If the profile `access` is not `:rpa`, raise an exception.
29
+ # If the `url` is not valid, raise an exception.
30
+ # Return the normalized URL.
31
+ #
32
+ # Overload this method in the child class.
33
+ #
34
+ def normalized_enrichment_url(url:)
35
+ # If the profile `access` is not `:rpa`, raise an exception.
36
+ raise "The method `normalized_enrichment_url` is not allowed for #{self.access.to_s} access." if self.access != :rpa
37
+ # Return the same URL in a normalized form:
38
+ # - remove all GET parameters.
39
+ # - remove all trailing slashes.
40
+ url = url.gsub(/\?.*$/, '').strip
41
+ url = ret.gsub(/\/+$/, '')
42
+ # Return the normalized URL.
43
+ url
44
+ end # def normalized_enrichment_url
45
+
46
+ # If the profile `access` is not `:api`, raise an exception.
47
+ # Parameter `params` must be a hash.
48
+ # Return `true` if the `params` are valid.
49
+ # Return `false` if the `params` are not valid.
50
+ def valid_enrichment_params?(params:)
51
+ # If the profile `access` is not `:api`, raise an exception.
52
+ raise "The method `valid_enrichment_params?` is not allowed for #{self.access.to_s} access." if self.access != :api
53
+ # Parameter `params` must be a hash.
54
+ raise "The parameter `params` must be a hash." if !params.is_a?(Hash)
55
+ # Return `true` if the `params` are valid.
56
+ # Return `false` if the `params` are not valid.
57
+ true
58
+ end # def valid_enrichment_params?
59
+ end # class EnrichmentType
60
+ end # module Mass
@@ -0,0 +1,15 @@
1
+ module Mass
2
+ class Event < BlackStack::Base
3
+ attr_accessor :lead, :company
4
+
5
+ def self.object_name
6
+ 'event'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ #self.lead = Mass::Lead.new(h['lead_desc']).child_class_instance if h['lead_desc']
12
+ #self.company = Mass::Company.new(h['company_desc']).child_class_instance if h['company_desc']
13
+ end
14
+ end # class Event
15
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Headcount < BlackStack::Base
3
+ def self.object_name
4
+ 'headcount'
5
+ end
6
+ end # class Headcount
7
+ end # module Mass
@@ -0,0 +1,14 @@
1
+ module Mass
2
+ class InboxCheck < BlackStack::Base
3
+ attr_accessor :profile
4
+
5
+ def self.object_name
6
+ 'inboxcheck'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ self.profile = Mass::Profile.get(h['id_profile']).child_class_instance if h['id_profile']
12
+ end
13
+ end # class InboxCheck
14
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Industry < BlackStack::Base
3
+ def self.object_name
4
+ 'industry'
5
+ end
6
+ end # class Industry
7
+ end # module Mass
@@ -0,0 +1,60 @@
1
+ module Mass
2
+ class Job < BlackStack::Base
3
+ attr_accessor :profile, :source
4
+
5
+ def self.object_name
6
+ 'job'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ self.profile = Mass::Profile.new(h['profile']).child_class_instance if h['profile']
12
+ self.source = Mass::Source.new(h['source_desc']).child_class_instance if h['source_desc']
13
+ end
14
+
15
+ # Submit a hash descriptor to the server for an upsert.
16
+ # Optimizaton: remove the events from the job descriptor, and submit events one by one.
17
+ def upsert
18
+ job = self
19
+ events = job.desc['events'].dup
20
+ job.desc['events'] = []
21
+
22
+ # cap the number of events to job.desc['max_events']
23
+ events = events[0..job.desc['max_events']-1] if job.desc['max_events'] && events.size > job.desc['max_events']
24
+
25
+ # initialize the id_account and id_job for each event
26
+ events.each { |e|
27
+ e['id_account'] = job.desc['id_account']
28
+ e['id_job'] = job.desc['id']
29
+ }
30
+
31
+ # upsert the events
32
+ events = events.map { |e| Mass::Event.new(e) }
33
+ super()
34
+ #k = 0
35
+ #puts
36
+ events.each { |e|
37
+ #k += 1
38
+ #print "k: #{k}... "
39
+ res = e.upsert
40
+ #puts res.nil? ? "nil" : res.desc['id']
41
+ }
42
+
43
+ job.desc['events'] = events.map { |e| e.desc } # setup the events array into the job again
44
+ end
45
+
46
+ def do(logger:nil)
47
+ self.source.do(
48
+ job: self,
49
+ logger: logger,
50
+ )
51
+ end
52
+
53
+ # return true if the assigned profile can download multiple files (allow_browser_to_download_multiple_files)
54
+ # and the source can download pictures (download_pictures)
55
+ def can_download_images?
56
+ self.profile.desc['allow_browser_to_download_multiple_files'] && self.source.desc['download_pictures']
57
+ end
58
+
59
+ end # class Job
60
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Lead < BlackStack::Base
3
+ def self.object_name
4
+ 'lead'
5
+ end
6
+ end
7
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Location < BlackStack::Base
3
+ def self.object_name
4
+ 'location'
5
+ end
6
+ end # class Location
7
+ end # module Mass
@@ -0,0 +1,42 @@
1
+ module Mass
2
+ class Outreach < BlackStack::Base
3
+ attr_accessor :type, :profile, :lead, :company, :profile_type
4
+
5
+ def self.object_name
6
+ 'outreach'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ self.type = Mass::OutreachType.new(h['outreach_type_desc']) if h['outreach_type_desc']
12
+ self.profile = Mass::Profile.new(h['profile']).child_class_instance if h['profile']
13
+ self.lead = Mass::Lead.new(h['lead']) if h['lead']
14
+ self.company = Mass::Company.new(h['company']) if h['company']
15
+ self.profile_type = Mass::ProfileType.page(
16
+ page: 1,
17
+ limit: 1,
18
+ filters: {
19
+ name: h['profile_type']
20
+ }
21
+ ).first.child_class_instance if h['profile_type']
22
+ end
23
+
24
+ # convert the outreach_type into the ruby class to create an instance.
25
+ # example: Apollo --> Mass::ApolloAPI
26
+ def class_name_from_outreach_type
27
+ outreach_type = self.desc['outreach_type']
28
+ "Mass::#{outreach_type}"
29
+ end
30
+
31
+ # crate an instance of the profile type using the class defined in the `desc['name']` attribute.
32
+ # override the base method
33
+ def child_class_instance
34
+ outreach_type = self.desc['outreach_type']
35
+ key = self.class_name_from_outreach_type
36
+ raise "Source code of outreach type #{outreach_type} not found. Create a class #{key} in the folder `/lib` of your mass-sdk." unless Kernel.const_defined?(key)
37
+ ret = Kernel.const_get(key).new(self.desc)
38
+ return ret
39
+ end
40
+
41
+ end # class Outreach
42
+ end # module Mass
@@ -0,0 +1,76 @@
1
+ module Mass
2
+ # Outreach module.
3
+ # List of methods you have to overload if you develop a profile type that supports outreach operations.
4
+ #
5
+ class OutreachType < BlackStack::Base
6
+ def self.object_name
7
+ 'outreach_type'
8
+ end # def self.object_name
9
+
10
+ # If the profile `access` is not `:rpa`, raise an exception.
11
+ # Return `true` if the `url` is valid.
12
+ # Return `false` if the `url` is not valid.
13
+ #
14
+ # Overload this method in the child class.
15
+ #
16
+ def valid_outreach_url?(url:)
17
+ # If the profile `access` is not `:rpa`, raise an exception.
18
+ raise "The method `valid_outreach_url?` is not allowed for #{self.access.to_s} access." if self.access != :rpa
19
+ # Return `true` if the `url` is valid.
20
+ # Return `false` if the `url` is not valid.
21
+ true
22
+ end # def valid_outreach_url?
23
+
24
+ # Return the same URL in a normalized form:
25
+ # - remove all GET parameters.
26
+ # - remove all trailing slashes.
27
+ #
28
+ # If the profile `access` is not `:rpa`, raise an exception.
29
+ # If the `url` is not valid, raise an exception.
30
+ # Return the normalized URL.
31
+ #
32
+ # Overload this method in the child class.
33
+ #
34
+ def normalized_outreach_url(url:)
35
+ # If the profile `access` is not `:rpa`, raise an exception.
36
+ raise "The method `normalized_outreach_url` is not allowed for #{self.access.to_s} access." if self.access != :rpa
37
+ # If the `url` is not valid, raise an exception.
38
+ raise "The URL is not valid." if !self.valid_outreach_url?(url: url)
39
+ # Return the same URL in a normalized form:
40
+ # - remove all GET parameters.
41
+ # - remove all trailing slashes.
42
+ url = url.gsub(/\?.*$/, '').strip
43
+ url = ret.gsub(/\/+$/, '')
44
+ # Return the normalized URL.
45
+ url
46
+ end # def normalized_outreach_url
47
+
48
+ # If the profile `access` is not `:api`, raise an exception.
49
+ # Parameter `params` must be a hash.
50
+ # Return `true` if the `params` are valid.
51
+ # Return `false` if the `params` are not valid.
52
+ def valid_outreach_params?(params:)
53
+ # If the profile `access` is not `:api`, raise an exception.
54
+ raise "The method `valid_outreach_params?` is not allowed for #{self.access.to_s} access." if self.access != :api
55
+ # Parameter `params` must be a hash.
56
+ raise "The parameter `params` must be a hash." if !params.is_a?(Hash)
57
+ # Return `true` if the `params` are valid.
58
+ # Return `false` if the `params` are not valid.
59
+ true
60
+ end # def valid_outreach_params?
61
+
62
+ # If the profile `access` is not `:mta`, raise an exception.
63
+ # Parameter `params` must be a hash.
64
+ # Return `true` if the `params` are valid.
65
+ # Return `false` if the `params` are not valid.
66
+ def valid_outreach_mta?(mta:)
67
+ # If the profile `access` is not `:api`, raise an exception.
68
+ raise "The method `valid_outreach_mta?` is not allowed for #{self.access.to_s} access." if self.access != :mta
69
+ # Parameter `params` must be a hash.
70
+ raise "The parameter `mta` must be a hash." if !mta.is_a?(Hash)
71
+ # Return `true` if the `params` are valid.
72
+ # Return `false` if the `params` are not valid.
73
+ true
74
+ end # def valid_outreach_mta?
75
+ end # class OutreachType
76
+ end # module Mass
@@ -0,0 +1,108 @@
1
+ module Mass
2
+ class Profile < BlackStack::Base
3
+ attr_accessor :type
4
+
5
+ def self.object_name
6
+ 'profile'
7
+ end
8
+
9
+ def initialize(h)
10
+ super(h)
11
+ self.type = Mass::ProfileType.new(h['profile_type_desc']).child_class_instance
12
+ end
13
+
14
+ # convert the profile_type into the ruby class to create an instance.
15
+ # example: Apollo --> Mass::ApolloAPI
16
+ def class_name_from_profile_type
17
+ profile_type = self.desc['profile_type']
18
+ "Mass::#{profile_type}"
19
+ end
20
+
21
+ # crate an instance of the profile type using the class defined in the `desc['name']` attribute.
22
+ # override the base method
23
+ def child_class_instance
24
+ profile_type = self.desc['profile_type']
25
+ key = self.class_name_from_profile_type
26
+ binding.pry
27
+ raise "Source code of profile type #{profile_type} not found. Create a class #{key} in the folder `/lib` of your mass-sdk." unless Kernel.const_defined?(key)
28
+ ret = Kernel.const_get(key).new(self.desc)
29
+ return ret
30
+ end
31
+
32
+ # return true of the profile is running
33
+ # if its profile type is rpa-access, then it will return true if the browser is running.
34
+ # else, it will return always true.
35
+ def running?
36
+ if self.type.desc['access'].to_sym == :rpa
37
+ c = AdsPowerClient.new(key: ADSPOWER_API_KEY)
38
+ return c.check(self.desc['ads_power_id'])
39
+ end
40
+ return true
41
+ end
42
+
43
+ # Scrape the inbox of the profile.
44
+ # Return a an array of hash descriptors of outreach records.
45
+ #
46
+ # Parameters:
47
+ # - limit: the maximum number of messages to scrape. Default: 100.
48
+ # - only_unread: if true, then only the unread messages will be scraped. Default: true.
49
+ # - logger: a logger object to log the process. Default: nil.
50
+ #
51
+ # Example of a hash descritor into the returned array:
52
+ # ```
53
+ # {
54
+ # # a scraped message is always a :performed message
55
+ # 'status' => :performed,
56
+ # # what is the outreach type?
57
+ # # e.g.: :LinkedIn_DirectMessage
58
+ # # decide this in the child class.
59
+ # 'outreach_type' => nil,
60
+ # # hash descriptor of the profile who is scraping the inbox
61
+ # 'profile' => self.desc,
62
+ # # hash descriptor of the lead who is the conversation partner
63
+ # 'lead' => nil,
64
+ # # if the message has been sent by the profile, it is :outgoing.
65
+ # # if the message has been sent by the lead, it is :incoming.
66
+ # 'direction' => nil,
67
+ # # the content of the message
68
+ # 'subject' => nil,
69
+ # 'body' => nil,
70
+ # }
71
+ # ```
72
+ #
73
+ def inboxcheck(limit: 100, only_unread:true, logger:nil)
74
+ []
75
+ end # def inboxcheck
76
+
77
+ # Scrape the inbox of the profile.
78
+ # Return a an array of hash descriptors of outreach records.
79
+ #
80
+ # Parameters:
81
+ # - limit: the maximum number of connections to scrape. Default: 100.
82
+ # - logger: a logger object to log the process. Default: nil.
83
+ #
84
+ # Example of a hash descritor into the returned array:
85
+ # ```
86
+ # {
87
+ # # a scraped message is always a :performed message
88
+ # 'status' => :performed,
89
+ # # what is the outreach type?
90
+ # # e.g.: :LinkedIn_ConnectionRequest
91
+ # # decide this in the child class.
92
+ # 'outreach_type' => nil,
93
+ # # hash descriptor of the profile who is scraping the inbox
94
+ # 'profile' => self.desc,
95
+ # # hash descriptor of the lead who is the conversation partner
96
+ # 'lead' => nil,
97
+ # # if the message has been sent by the profile, it is :outgoing.
98
+ # # if the message has been sent by the lead, it is :incoming.
99
+ # 'direction' => :accepted,
100
+ # }
101
+ # ```
102
+ #
103
+ def connectioncheck(limit: 100, logger:nil)
104
+ []
105
+ end # def inboxcheck
106
+
107
+ end # class Profile
108
+ end # module Mass
@@ -0,0 +1,10 @@
1
+ module Mass
2
+ # Base class.
3
+ # List of methods you have to overload if you develop a profile type.
4
+ #
5
+ class ProfileType < BlackStack::Base
6
+ def self.object_name
7
+ 'profile_type'
8
+ end
9
+ end # class ProfileType
10
+ end # module Mass
@@ -0,0 +1,40 @@
1
+ module Mass
2
+ class Request < BlackStack::Base
3
+ def self.object_name
4
+ 'request'
5
+ end
6
+
7
+ def perform(l)
8
+ if self.desc['state'] == 'online'
9
+ self.start_browser(l)
10
+ elsif self.desc['state'] == 'idle'
11
+ self.stop_browser(l)
12
+ else
13
+ raise "Unknown or unsupported request state: #{self.desc['state'].to_s}."
14
+ end
15
+ end
16
+
17
+ def start_browser(l=nil)
18
+ l = BlackStack::DummyLogger.new(nil) if l.nil?
19
+ #raise "Profile is not waiting to start" if self.desc['profile']['state'].to_sym != :starting
20
+ # start browser
21
+ p = Mass::ProfileRPA.new(self.desc['profile'])
22
+ p.driver
23
+ # update profile state
24
+ p.desc['state'] = :scraping_inbox
25
+ p.upsert
26
+ end
27
+
28
+ def stop_browser(l=nil)
29
+ l = BlackStack::DummyLogger.new(nil) if l.nil?
30
+ #raise "Profile is not waiting to stop" if self.desc['profile']['state'].to_sym != :stopping
31
+ c = AdsPowerClient.new(key: ADSPOWER_API_KEY)
32
+ c.stop(self.desc['profile']['ads_power_id']) if c.check(self.desc['profile']['ads_power_id'])
33
+ # get the profile for updating
34
+ p = Mass::Profile.new(self.desc['profile'])
35
+ p.desc['state'] = :idle
36
+ p.upsert
37
+ end
38
+
39
+ end # class Request
40
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Revenue < BlackStack::Base
3
+ def self.object_name
4
+ 'revenue'
5
+ end
6
+ end # class Revenue
7
+ end # module Mass
@@ -0,0 +1,7 @@
1
+ module Mass
2
+ class Rule < BlackStack::Base
3
+ def self.object_name
4
+ 'rule'
5
+ end
6
+ end # class Rule
7
+ end # module Mass