context_io 1.0.0.pre.beta
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/.gitignore +9 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.md +190 -0
- data/README.md +147 -0
- data/Rakefile +10 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/context_io.gemspec +45 -0
- data/lib/context_io.rb +104 -0
- data/lib/context_io/account.rb +143 -0
- data/lib/context_io/account/contact.rb +59 -0
- data/lib/context_io/account/email_address.rb +33 -0
- data/lib/context_io/account/files.rb +58 -0
- data/lib/context_io/account/sources.rb +83 -0
- data/lib/context_io/account/sync.rb +34 -0
- data/lib/context_io/account/threads.rb +35 -0
- data/lib/context_io/connection.rb +25 -0
- data/lib/context_io/oauth_provider.rb +33 -0
- data/lib/context_io/shared/connect_token.rb +35 -0
- data/lib/context_io/shared/discovery.rb +31 -0
- data/lib/context_io/shared/folder.rb +57 -0
- data/lib/context_io/shared/message.rb +112 -0
- data/lib/context_io/shared/webhook.rb +43 -0
- data/lib/context_io/utilities/api_call_made.rb +5 -0
- data/lib/context_io/utilities/call_helpers.rb +145 -0
- data/lib/context_io/utilities/collection_helper.rb +41 -0
- data/lib/context_io/utilities/deleted_resource.rb +15 -0
- data/lib/context_io/utilities/request.rb +21 -0
- data/lib/context_io/utilities/valid_parameters/get_params.rb +60 -0
- data/lib/context_io/utilities/valid_parameters/post_params.rb +48 -0
- data/lib/context_io/version.rb +3 -0
- metadata +204 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class Sync
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
private
|
5
|
+
attr_reader :parent
|
6
|
+
|
7
|
+
public
|
8
|
+
attr_reader :status, :success, :connection, :response, :api_call_made
|
9
|
+
def initialize(parent:,
|
10
|
+
response: nil,
|
11
|
+
status: nil,
|
12
|
+
success: nil,
|
13
|
+
api_call_made: nil)
|
14
|
+
@parent = parent
|
15
|
+
@connection = parent.connection
|
16
|
+
@response = response
|
17
|
+
@status = status
|
18
|
+
@success = success
|
19
|
+
@api_call_made = api_call_made
|
20
|
+
end
|
21
|
+
|
22
|
+
def call_url
|
23
|
+
"#{parent.call_url}/sync"
|
24
|
+
end
|
25
|
+
|
26
|
+
def get
|
27
|
+
request = Request.new(connection, :get, call_url)
|
28
|
+
@response = request.response
|
29
|
+
@status = request.status
|
30
|
+
@success = check_success(status)
|
31
|
+
self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class Threads
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
THREADS_READERS = %I(gmail_thread_id email_message_ids person_info messages)
|
5
|
+
|
6
|
+
private
|
7
|
+
attr_reader :parent
|
8
|
+
|
9
|
+
public
|
10
|
+
attr_reader :api_call_made
|
11
|
+
attr_reader :status, :success, :connection, :thread_id, *THREADS_READERS
|
12
|
+
def initialize(parent:,
|
13
|
+
identifier: nil,
|
14
|
+
response: nil,
|
15
|
+
status: nil,
|
16
|
+
success: nil,
|
17
|
+
api_call_made: nil)
|
18
|
+
@parent = parent
|
19
|
+
@connection = parent.connection
|
20
|
+
@thread_id = identifier
|
21
|
+
@response = response
|
22
|
+
@status = status
|
23
|
+
@success = success
|
24
|
+
@api_call_made = api_call_made
|
25
|
+
end
|
26
|
+
|
27
|
+
def call_url
|
28
|
+
build_url("threads", thread_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def get(**kwargs)
|
32
|
+
get_request(given_params: kwargs, valid_params: ValidGetParams::THREAD)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "faraday_middleware"
|
3
|
+
|
4
|
+
module ContextIO
|
5
|
+
class Connection
|
6
|
+
ROOT_URL = "https://api.context.io"
|
7
|
+
USER_AGENT = "context_io-ruby-2.0"
|
8
|
+
|
9
|
+
attr_reader :key, :secret
|
10
|
+
def initialize(key, secret)
|
11
|
+
@key = key
|
12
|
+
@secret = secret
|
13
|
+
end
|
14
|
+
|
15
|
+
def connect
|
16
|
+
connection ||= Faraday::Connection.new(ROOT_URL) do |f|
|
17
|
+
f.headers["User-Agent"] = USER_AGENT
|
18
|
+
f.request :oauth, consumer_key: key, consumer_secret: secret
|
19
|
+
f.request :url_encoded
|
20
|
+
f.request :retry, max: 0
|
21
|
+
f.adapter Faraday.default_adapter
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class OauthProvider
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
OAUTH_READERS = %I(type provider_consumer_key provider_consumer_secret resource_url)
|
5
|
+
private
|
6
|
+
attr_reader :connection
|
7
|
+
|
8
|
+
public
|
9
|
+
attr_accessor :api_call_made
|
10
|
+
attr_reader :status, :parent, :success, :key, *OAUTH_READERS
|
11
|
+
def initialize(parent:,
|
12
|
+
identifier: nil,
|
13
|
+
response: nil,
|
14
|
+
status: nil,
|
15
|
+
success: nil,
|
16
|
+
api_call_made: nil)
|
17
|
+
@parent = parent
|
18
|
+
@connection = parent.connection
|
19
|
+
@response = response
|
20
|
+
@status = status
|
21
|
+
@success = success
|
22
|
+
@key = identifier
|
23
|
+
@api_call_made = api_call_made
|
24
|
+
if response
|
25
|
+
parse_response(response)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def call_url
|
30
|
+
build_url("oauth_providers", key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class ConnectToken
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
CONNECT_READERS = %I(email source_callback_url source_raw_file_list created
|
5
|
+
used expires status_callback_url first_name last_name account
|
6
|
+
resource_url server_label callback_url browser_redirect_url)
|
7
|
+
private
|
8
|
+
attr_reader :parent
|
9
|
+
|
10
|
+
public
|
11
|
+
attr_accessor :api_call_made
|
12
|
+
attr_reader :token, :connection, :success, :status, :resposne, *CONNECT_READERS
|
13
|
+
def initialize(parent:,
|
14
|
+
identifier: nil,
|
15
|
+
response: nil,
|
16
|
+
status: nil,
|
17
|
+
success: nil,
|
18
|
+
api_call_made: nil)
|
19
|
+
@parent = parent
|
20
|
+
@connection = parent.connection
|
21
|
+
@token = identifier
|
22
|
+
@response = response
|
23
|
+
@status = status
|
24
|
+
@success = success
|
25
|
+
@api_call_made = api_call_made
|
26
|
+
if response
|
27
|
+
parse_response(response)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def call_url
|
32
|
+
build_url("connect_tokens", token)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class Discovery
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
DISCOVERY_READERS = %I(email found resource_url type imap documentation)
|
5
|
+
|
6
|
+
private
|
7
|
+
attr_reader :parent
|
8
|
+
|
9
|
+
public
|
10
|
+
attr_accessor :api_call_made
|
11
|
+
attr_reader :status, :success, :connection, :response, *DISCOVERY_READERS
|
12
|
+
def initialize(parent:,
|
13
|
+
email:,
|
14
|
+
response: nil,
|
15
|
+
status: nil,
|
16
|
+
success: nil,
|
17
|
+
api_call_made: nil)
|
18
|
+
@parent = parent
|
19
|
+
@connection = parent.connection
|
20
|
+
@email = email
|
21
|
+
@response = response
|
22
|
+
@status = status
|
23
|
+
@success = success
|
24
|
+
@api_call_made = api_call_made
|
25
|
+
end
|
26
|
+
|
27
|
+
def call_url
|
28
|
+
"#{parent.call_url}/discovery?email=#{email}&source_type=IMAP"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class Folder
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
FOLDER_READERS = %I(symbolic_name attributes delim nb_messages xlist_name
|
5
|
+
nb_unseen_messages resource_url name)
|
6
|
+
|
7
|
+
private
|
8
|
+
attr_reader :parent
|
9
|
+
|
10
|
+
public
|
11
|
+
attr_accessor :api_call_made
|
12
|
+
attr_reader :status, :success, :connection, :response, *FOLDER_READERS
|
13
|
+
def initialize(parent:,
|
14
|
+
identifier: nil,
|
15
|
+
response: nil,
|
16
|
+
status: nil,
|
17
|
+
success: nil,
|
18
|
+
api_call_made: nil)
|
19
|
+
@status = status
|
20
|
+
@success = success
|
21
|
+
@parent = parent
|
22
|
+
@connection = parent.connection
|
23
|
+
@name = identifier
|
24
|
+
@api_call_made = api_call_made
|
25
|
+
if response
|
26
|
+
parse_response(response)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def encoded_name
|
31
|
+
ERB::Util.url_encode(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def call_url
|
35
|
+
build_url("folders", encoded_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def source_parent?
|
39
|
+
parent.class == Sources
|
40
|
+
end
|
41
|
+
|
42
|
+
def get(**kwargs)
|
43
|
+
if source_parent?
|
44
|
+
get_request(given_params: kwargs, valid_params: ValidGetParams::SOURCE_FOLDER)
|
45
|
+
else
|
46
|
+
get_request(given_params: kwargs)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_messages(**kwargs)
|
51
|
+
collection_return(url: "#{call_url}/messages",
|
52
|
+
klass: Message,
|
53
|
+
valid_params: ValidGetParams::SOURCE_FOLDER_MESSAGES,
|
54
|
+
given_params: kwargs)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class Message
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
MESSAGE_READERS = %I(date date_indexed date_received addresses person_info email_message_id
|
5
|
+
message_id gmail_message_id gmail_thread_id files subject
|
6
|
+
folders sources content type charset body_section answered
|
7
|
+
deleted draft flagged seen in_reply_to references resource_url)
|
8
|
+
private
|
9
|
+
attr_reader :parent
|
10
|
+
|
11
|
+
public
|
12
|
+
attr_accessor :api_call_made
|
13
|
+
attr_reader :status, :success, :connection, :message_id, :response, *MESSAGE_READERS
|
14
|
+
def initialize(parent:,
|
15
|
+
identifier: nil,
|
16
|
+
response: nil,
|
17
|
+
status: nil,
|
18
|
+
success: nil,
|
19
|
+
api_call_made: nil)
|
20
|
+
@parent = parent
|
21
|
+
@connection = parent.connection
|
22
|
+
@message_id = identifier
|
23
|
+
@status = status
|
24
|
+
@success = success
|
25
|
+
@api_call_made = api_call_made
|
26
|
+
if response
|
27
|
+
parse_response(response)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def encoded_message_id
|
32
|
+
ERB::Util.url_encode(message_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def call_url
|
36
|
+
build_url("messages", encoded_message_id)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parent_not_account_error
|
40
|
+
raise StandardError, "This method can only be called from '2.0/accounts/:account/message/:message_id'" if parent.class != Account
|
41
|
+
end
|
42
|
+
|
43
|
+
def get(**kwargs)
|
44
|
+
get_request(given_params: kwargs, valid_params: ValidGetParams::MESSAGE)
|
45
|
+
end
|
46
|
+
|
47
|
+
def post(dst_folder:, **kwargs)
|
48
|
+
parent_not_account_error
|
49
|
+
given_params = kwargs.merge(dst_folder: dst_folder)
|
50
|
+
message = call_api_return_updated_object(klass: Message,
|
51
|
+
url: "#{call_url}",
|
52
|
+
identifier: encoded_message_id,
|
53
|
+
method: :post,
|
54
|
+
valid_params: ValidPostParams::MESSAGE_MOVE_20,
|
55
|
+
given_params: given_params)
|
56
|
+
return_post_api_call_made(message)
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_body(**kwargs)
|
60
|
+
parent_not_account_error
|
61
|
+
call_api_return_new_object(klass: Message,
|
62
|
+
url: "#{call_url}/body",
|
63
|
+
valid_params: ValidGetParams::MESSAGE_BODY,
|
64
|
+
given_params: kwargs)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_flags
|
68
|
+
parent_not_account_error
|
69
|
+
call_api_return_new_object(klass: Message,
|
70
|
+
url: "#{call_url}/flags")
|
71
|
+
end
|
72
|
+
|
73
|
+
def post_flags(**kwargs)
|
74
|
+
parent_not_account_error
|
75
|
+
flags = call_api_return_updated_object(klass: Message,
|
76
|
+
url: "#{call_url}/flags",
|
77
|
+
identifier: encoded_message_id,
|
78
|
+
method: :post,
|
79
|
+
valid_params: ValidPostParams::FLAGS,
|
80
|
+
given_params: kwargs)
|
81
|
+
return_post_api_call_made(flags)
|
82
|
+
end
|
83
|
+
|
84
|
+
def get_folders
|
85
|
+
parent_not_account_error
|
86
|
+
call_api_return_new_object(klass: Message,
|
87
|
+
url: "#{call_url}/folders")
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_headers(**kwargs)
|
91
|
+
parent_not_account_error
|
92
|
+
call_api_return_new_object(klass: Message,
|
93
|
+
url: "#{call_url}/headers",
|
94
|
+
valid_params: ValidGetParams::MESSAGE_HEADER,
|
95
|
+
given_params: kwargs)
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_source
|
99
|
+
parent_not_account_error
|
100
|
+
call_api_return_new_object(klass: Message,
|
101
|
+
url: "#{call_url}/source")
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_threads(**kwargs)
|
105
|
+
parent_not_account_error
|
106
|
+
call_api_return_new_object(klass: Message,
|
107
|
+
url: "#{call_url}/thread",
|
108
|
+
valid_params: ValidGetParams::MESSAGE_THREADS,
|
109
|
+
given_params: kwargs)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ContextIO
|
2
|
+
class Webhook
|
3
|
+
include ContextIO::CallHelpers
|
4
|
+
WEBHOOK_READERS = %I(callback_url failure_notif_url active webhook_id resource_url)
|
5
|
+
|
6
|
+
private
|
7
|
+
attr_reader :parent
|
8
|
+
|
9
|
+
public
|
10
|
+
attr_accessor :api_call_made
|
11
|
+
attr_reader :webhook_id, :success, :connection, :status, *WEBHOOK_READERS
|
12
|
+
def initialize(parent:,
|
13
|
+
identifier: nil,
|
14
|
+
response: nil,
|
15
|
+
status: nil,
|
16
|
+
success: nil,
|
17
|
+
api_call_made: nil)
|
18
|
+
@parent = parent
|
19
|
+
@connection = parent.connection
|
20
|
+
@webhook_id = identifier
|
21
|
+
@status = status
|
22
|
+
@success = success
|
23
|
+
@api_call_made = api_call_made
|
24
|
+
if response
|
25
|
+
parse_response(response)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def call_url
|
30
|
+
build_url("webhooks", webhook_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(**kwargs)
|
34
|
+
webhook = call_api_return_updated_object(klass: Webhook,
|
35
|
+
url: call_url,
|
36
|
+
identifier: webhook_id,
|
37
|
+
method: :post,
|
38
|
+
valid_params: ValidPostParams::WEBHOOK,
|
39
|
+
given_params: kwargs)
|
40
|
+
return_post_api_call_made(webhook)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module ContextIO
|
2
|
+
module CallHelpers
|
3
|
+
require_relative './collection_helper.rb'
|
4
|
+
include ContextIO::CollectionHelper
|
5
|
+
def parse_response(response)
|
6
|
+
if [Array, String].include?(response.class)
|
7
|
+
@response = response
|
8
|
+
else
|
9
|
+
response.each do |k,v|
|
10
|
+
key = k.to_s.gsub('-', '_')
|
11
|
+
instance_variable_set("@#{key}", v)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_url(resource, identifier)
|
17
|
+
"#{parent.call_url}/#{resource}/#{identifier}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_request(given_params: nil, valid_params: nil, url: nil)
|
21
|
+
request, api_call_made = call_api(method: :get,
|
22
|
+
url: url || call_url,
|
23
|
+
given_params: given_params,
|
24
|
+
valid_params:valid_params)
|
25
|
+
parse_response(request.response)
|
26
|
+
@status = request.status
|
27
|
+
@success = check_success(status)
|
28
|
+
@api_call_made = api_call_made
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def call_api_return_new_object(klass:,
|
33
|
+
url:,
|
34
|
+
method: :get,
|
35
|
+
parent: nil,
|
36
|
+
valid_params: nil,
|
37
|
+
given_params: nil)
|
38
|
+
request, api_call_made = call_api(method: method,
|
39
|
+
url: url,
|
40
|
+
given_params: given_params,
|
41
|
+
valid_params: valid_params)
|
42
|
+
klass.new(parent: parent || self,
|
43
|
+
response: request.response,
|
44
|
+
status: request.status,
|
45
|
+
success: request.success,
|
46
|
+
api_call_made: api_call_made)
|
47
|
+
end
|
48
|
+
|
49
|
+
def call_api_return_updated_object(klass:,
|
50
|
+
url:,
|
51
|
+
identifier:,
|
52
|
+
method: :post,
|
53
|
+
valid_params: nil,
|
54
|
+
given_params: nil)
|
55
|
+
request, api_call_made = call_api(method: method,
|
56
|
+
url: url,
|
57
|
+
given_params: given_params,
|
58
|
+
valid_params: valid_params)
|
59
|
+
object = klass.new(parent: parent,
|
60
|
+
response: request.response,
|
61
|
+
identifier: identifier,
|
62
|
+
status: request.status,
|
63
|
+
success: request.success,
|
64
|
+
api_call_made: api_call_made)
|
65
|
+
return_post_api_call_made(object)
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_params(inputed_params, valid_params)
|
69
|
+
return [nil, nil] if inputed_params.nil?
|
70
|
+
rejected_params = []
|
71
|
+
params = []
|
72
|
+
inputed_params.map do |key, value|
|
73
|
+
if valid_params.include?(key)
|
74
|
+
params << [key, value]
|
75
|
+
else
|
76
|
+
rejected_params << key
|
77
|
+
end
|
78
|
+
end
|
79
|
+
params = params.compact
|
80
|
+
if !params.empty?
|
81
|
+
params = params.to_h
|
82
|
+
end
|
83
|
+
[params, rejected_params]
|
84
|
+
end
|
85
|
+
|
86
|
+
def get(**kwargs)
|
87
|
+
get_request(given_params: kwargs)
|
88
|
+
end
|
89
|
+
|
90
|
+
def delete
|
91
|
+
request = Request.new(connection, :delete, call_url)
|
92
|
+
raise StandardError, build_error_message(request.status, request.response) if request.success == false
|
93
|
+
api_call_made = build_api_call_made(request.url,
|
94
|
+
:delete,
|
95
|
+
nil,
|
96
|
+
nil)
|
97
|
+
DeletedResource.new(response: request.response,
|
98
|
+
status: request.status,
|
99
|
+
success: request.success,
|
100
|
+
api_call_made: api_call_made)
|
101
|
+
end
|
102
|
+
|
103
|
+
def success?
|
104
|
+
self.success
|
105
|
+
end
|
106
|
+
|
107
|
+
def return_post_api_call_made(object)
|
108
|
+
call_made = object.api_call_made
|
109
|
+
object.get
|
110
|
+
object.api_call_made = call_made
|
111
|
+
object
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def call_api(method:, url:, given_params:, valid_params:)
|
116
|
+
allowed_params, rejected_params = validate_params(given_params, valid_params)
|
117
|
+
request = Request.new(connection, method, url || call_url, allowed_params)
|
118
|
+
raise StandardError, build_error_message(request.status, request.response) if request.success == false
|
119
|
+
api_call_made = build_api_call_made(request.url,
|
120
|
+
method,
|
121
|
+
allowed_params,
|
122
|
+
rejected_params)
|
123
|
+
[request, api_call_made]
|
124
|
+
end
|
125
|
+
|
126
|
+
def check_success(status)
|
127
|
+
status >= 200 && status <= 299
|
128
|
+
end
|
129
|
+
|
130
|
+
def build_api_call_made(url, method, allowed_params, rejected_params)
|
131
|
+
APICallMade::CALL_MADE_STRUCT.new(url,
|
132
|
+
method,
|
133
|
+
allowed_params,
|
134
|
+
rejected_params)
|
135
|
+
end
|
136
|
+
|
137
|
+
def build_error_message(status, body)
|
138
|
+
if body.empty?
|
139
|
+
"HTTP code #{status}. No API error given."
|
140
|
+
else
|
141
|
+
"HTTP code #{status}. Response #{body}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|