context_io 1.0.0.pre.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|