litmus-instant 0.1.0 → 0.2.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 +4 -4
- data/.travis.yml +1 -1
- data/Procfile +1 -0
- data/README.md +15 -0
- data/examples/Gemfile +1 -0
- data/examples/Gemfile.lock +3 -2
- data/examples/README.md +2 -0
- data/examples/config.ru +2 -0
- data/fixtures/vcr_cassettes/Litmus_Instant/Litmus_Instant_Client_provides_Litmus_Instant_class_methods_as_instance_methods.yml +191 -0
- data/fixtures/vcr_cassettes/Litmus_Instant/Litmus_Instant_Client_uses_its_own_config.yml +85 -0
- data/fixtures/vcr_cassettes/Litmus_Instant/client_configurations/returns_a_Hash_of_clients_and_their_available_options.yml +107 -11
- data/fixtures/vcr_cassettes/Litmus_Instant/clients/returns_an_array_of_client_names.yml +15 -4
- data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_invalid_email_Hash_raise_a_request_error.yml +5 -41
- data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_optional_end_user_id_is_relayed.yml +6 -4
- data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_prerequest_configurations_is_relayed.yml +6 -4
- data/fixtures/vcr_cassettes/Litmus_Instant/create_email/authenticated_with_valid_email_Hash_response_.yml +6 -42
- data/fixtures/vcr_cassettes/Litmus_Instant/create_email/unauthenticated_raises_an_authentication_error.yml +5 -5
- data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_NotFound_for_an_expired_email_guid.yml +2 -1630
- data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_client.yml +9 -7
- data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_email_guid.yml +2 -2
- data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/returns_a_Hash_of_the_image_types.yml +13 -11
- data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/supports_optional_capture_configuration.yml +13 -47
- data/fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/raises_RequestError_for_an_invalid_email_guid.yml +2 -2
- data/fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/raises_RequestError_if_any_invalid_configurations_are_present.yml +11 -9
- data/fixtures/vcr_cassettes/Litmus_Instant/prefetch_previews/responds_with_an_array_of_the_requested_configurations.yml +9 -7
- data/lib/litmus/instant.rb +106 -13
- data/lib/litmus/instant/version.rb +2 -2
- metadata +7 -4
data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/raises_RequestError_for_an_invalid_client.yml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https
|
5
|
+
uri: https://instant-api.litmus.com/v1/emails
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: '{"plain_text":"Hej världen! Kärlek, den svenska kocken."}'
|
@@ -11,6 +11,8 @@ http_interactions:
|
|
11
11
|
- application/json
|
12
12
|
Accept:
|
13
13
|
- application/json
|
14
|
+
Authorization:
|
15
|
+
- Basic Y3hkNHR1c3F3b2tnZ2dseGl6ZDl2cDd6bXV4dmo2eG95a2UxOg==
|
14
16
|
response:
|
15
17
|
status:
|
16
18
|
code: 200
|
@@ -19,7 +21,7 @@ http_interactions:
|
|
19
21
|
Server:
|
20
22
|
- nginx
|
21
23
|
Date:
|
22
|
-
-
|
24
|
+
- Mon, 20 Jun 2016 11:43:50 GMT
|
23
25
|
Content-Type:
|
24
26
|
- application/json;charset=utf-8
|
25
27
|
Content-Length:
|
@@ -36,13 +38,13 @@ http_interactions:
|
|
36
38
|
encoding: UTF-8
|
37
39
|
string: |-
|
38
40
|
{
|
39
|
-
"email_guid": "
|
41
|
+
"email_guid": "92d9cb6d-6ea0-4b46-813c-3025214f80fd"
|
40
42
|
}
|
41
43
|
http_version:
|
42
|
-
recorded_at:
|
44
|
+
recorded_at: Mon, 20 Jun 2016 11:43:52 GMT
|
43
45
|
- request:
|
44
46
|
method: get
|
45
|
-
uri: https://instant-api.litmus.com/v1/emails/
|
47
|
+
uri: https://instant-api.litmus.com/v1/emails/92d9cb6d-6ea0-4b46-813c-3025214f80fd/previews/OL2001MYSPACEODYSSEY
|
46
48
|
body:
|
47
49
|
encoding: US-ASCII
|
48
50
|
string: ''
|
@@ -59,7 +61,7 @@ http_interactions:
|
|
59
61
|
Server:
|
60
62
|
- nginx
|
61
63
|
Date:
|
62
|
-
-
|
64
|
+
- Mon, 20 Jun 2016 11:43:50 GMT
|
63
65
|
Content-Type:
|
64
66
|
- application/json;charset=utf-8
|
65
67
|
Content-Length:
|
@@ -75,5 +77,5 @@ http_interactions:
|
|
75
77
|
"description": "'client' must be valid, see /clients"
|
76
78
|
}
|
77
79
|
http_version:
|
78
|
-
recorded_at:
|
80
|
+
recorded_at: Mon, 20 Jun 2016 11:43:53 GMT
|
79
81
|
recorded_with: VCR 2.9.3
|
@@ -19,7 +19,7 @@ http_interactions:
|
|
19
19
|
Server:
|
20
20
|
- nginx
|
21
21
|
Date:
|
22
|
-
-
|
22
|
+
- Mon, 20 Jun 2016 11:43:50 GMT
|
23
23
|
Content-Type:
|
24
24
|
- application/json;charset=utf-8
|
25
25
|
Content-Length:
|
@@ -35,5 +35,5 @@ http_interactions:
|
|
35
35
|
"description": "'email_guid' must match format of a standard GUID"
|
36
36
|
}
|
37
37
|
http_version:
|
38
|
-
recorded_at:
|
38
|
+
recorded_at: Mon, 20 Jun 2016 11:43:52 GMT
|
39
39
|
recorded_with: VCR 2.9.3
|
data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/returns_a_Hash_of_the_image_types.yml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https
|
5
|
+
uri: https://instant-api.litmus.com/v1/emails
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: '{"plain_text":"Hej världen! Kärlek, den svenska kocken."}'
|
@@ -11,6 +11,8 @@ http_interactions:
|
|
11
11
|
- application/json
|
12
12
|
Accept:
|
13
13
|
- application/json
|
14
|
+
Authorization:
|
15
|
+
- Basic Y3hkNHR1c3F3b2tnZ2dseGl6ZDl2cDd6bXV4dmo2eG95a2UxOg==
|
14
16
|
response:
|
15
17
|
status:
|
16
18
|
code: 200
|
@@ -19,7 +21,7 @@ http_interactions:
|
|
19
21
|
Server:
|
20
22
|
- nginx
|
21
23
|
Date:
|
22
|
-
-
|
24
|
+
- Mon, 20 Jun 2016 11:43:52 GMT
|
23
25
|
Content-Type:
|
24
26
|
- application/json;charset=utf-8
|
25
27
|
Content-Length:
|
@@ -36,13 +38,13 @@ http_interactions:
|
|
36
38
|
encoding: UTF-8
|
37
39
|
string: |-
|
38
40
|
{
|
39
|
-
"email_guid": "
|
41
|
+
"email_guid": "92d9cb6d-6ea0-4b46-813c-3025214f80fd"
|
40
42
|
}
|
41
43
|
http_version:
|
42
|
-
recorded_at:
|
44
|
+
recorded_at: Mon, 20 Jun 2016 11:43:54 GMT
|
43
45
|
- request:
|
44
46
|
method: get
|
45
|
-
uri: https://instant-api.litmus.com/v1/emails/
|
47
|
+
uri: https://instant-api.litmus.com/v1/emails/92d9cb6d-6ea0-4b46-813c-3025214f80fd/previews/PLAINTEXT
|
46
48
|
body:
|
47
49
|
encoding: US-ASCII
|
48
50
|
string: ''
|
@@ -59,11 +61,11 @@ http_interactions:
|
|
59
61
|
Server:
|
60
62
|
- nginx
|
61
63
|
Date:
|
62
|
-
-
|
64
|
+
- Mon, 20 Jun 2016 11:43:56 GMT
|
63
65
|
Content-Type:
|
64
66
|
- application/json;charset=utf-8
|
65
67
|
Content-Length:
|
66
|
-
- '
|
68
|
+
- '436'
|
67
69
|
Connection:
|
68
70
|
- keep-alive
|
69
71
|
Strict-Transport-Security:
|
@@ -76,10 +78,10 @@ http_interactions:
|
|
76
78
|
encoding: UTF-8
|
77
79
|
string: |-
|
78
80
|
{
|
79
|
-
"full_url": "https://
|
80
|
-
"thumb_url": "https://
|
81
|
-
"thumb450_url": "https://
|
81
|
+
"full_url": "https://plaintext.capture.litmuscdn.com/92d9cb6d-6ea0-4b46-813c-3025214f80fd/results/plaintext-vertical-allowed-1366.png",
|
82
|
+
"thumb_url": "https://plaintext.capture.litmuscdn.com/92d9cb6d-6ea0-4b46-813c-3025214f80fd/results/plaintext-vertical-allowed-1366-thumb.png",
|
83
|
+
"thumb450_url": "https://plaintext.capture.litmuscdn.com/92d9cb6d-6ea0-4b46-813c-3025214f80fd/results/plaintext-vertical-allowed-1366-thumb450.png"
|
82
84
|
}
|
83
85
|
http_version:
|
84
|
-
recorded_at:
|
86
|
+
recorded_at: Mon, 20 Jun 2016 11:43:58 GMT
|
85
87
|
recorded_with: VCR 2.9.3
|
data/fixtures/vcr_cassettes/Litmus_Instant/get_preview/supports_optional_capture_configuration.yml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https
|
5
|
+
uri: https://instant-api.litmus.com/v1/emails
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: '{"plain_text":"Hej världen! Kärlek, den svenska kocken."}'
|
@@ -11,6 +11,8 @@ http_interactions:
|
|
11
11
|
- application/json
|
12
12
|
Accept:
|
13
13
|
- application/json
|
14
|
+
Authorization:
|
15
|
+
- Basic Y3hkNHR1c3F3b2tnZ2dseGl6ZDl2cDd6bXV4dmo2eG95a2UxOg==
|
14
16
|
response:
|
15
17
|
status:
|
16
18
|
code: 200
|
@@ -19,7 +21,7 @@ http_interactions:
|
|
19
21
|
Server:
|
20
22
|
- nginx
|
21
23
|
Date:
|
22
|
-
-
|
24
|
+
- Mon, 20 Jun 2016 11:43:56 GMT
|
23
25
|
Content-Type:
|
24
26
|
- application/json;charset=utf-8
|
25
27
|
Content-Length:
|
@@ -36,49 +38,13 @@ http_interactions:
|
|
36
38
|
encoding: UTF-8
|
37
39
|
string: |-
|
38
40
|
{
|
39
|
-
"email_guid": "
|
41
|
+
"email_guid": "92d9cb6d-6ea0-4b46-813c-3025214f80fd"
|
40
42
|
}
|
41
43
|
http_version:
|
42
|
-
recorded_at:
|
44
|
+
recorded_at: Mon, 20 Jun 2016 11:43:59 GMT
|
43
45
|
- request:
|
44
46
|
method: get
|
45
|
-
uri: https://instant-api.litmus.com/v1/emails/
|
46
|
-
body:
|
47
|
-
encoding: US-ASCII
|
48
|
-
string: ''
|
49
|
-
headers:
|
50
|
-
Content-Type:
|
51
|
-
- application/json
|
52
|
-
Accept:
|
53
|
-
- application/json
|
54
|
-
response:
|
55
|
-
status:
|
56
|
-
code: 400
|
57
|
-
message: Bad Request
|
58
|
-
headers:
|
59
|
-
Server:
|
60
|
-
- nginx
|
61
|
-
Date:
|
62
|
-
- Thu, 08 Oct 2015 15:55:40 GMT
|
63
|
-
Content-Type:
|
64
|
-
- application/json;charset=utf-8
|
65
|
-
Content-Length:
|
66
|
-
- '170'
|
67
|
-
Connection:
|
68
|
-
- keep-alive
|
69
|
-
body:
|
70
|
-
encoding: UTF-8
|
71
|
-
string: |-
|
72
|
-
{
|
73
|
-
"status": 400,
|
74
|
-
"title": "Bad Request",
|
75
|
-
"description": "Invalid client configuration - 'blocked' images option not valid for 'IPAD', see /clients/configurations"
|
76
|
-
}
|
77
|
-
http_version:
|
78
|
-
recorded_at: Thu, 08 Oct 2015 15:56:15 GMT
|
79
|
-
- request:
|
80
|
-
method: get
|
81
|
-
uri: https://instant-api.litmus.com/v1/emails/93b5954d-c7b5-437d-96d9-9ad6c1717f84/previews/OL2010?images=blocked&orientation=vertical
|
47
|
+
uri: https://instant-api.litmus.com/v1/emails/92d9cb6d-6ea0-4b46-813c-3025214f80fd/previews/OL2010?images=blocked&orientation=vertical
|
82
48
|
body:
|
83
49
|
encoding: US-ASCII
|
84
50
|
string: ''
|
@@ -95,11 +61,11 @@ http_interactions:
|
|
95
61
|
Server:
|
96
62
|
- nginx
|
97
63
|
Date:
|
98
|
-
-
|
64
|
+
- Mon, 20 Jun 2016 11:44:04 GMT
|
99
65
|
Content-Type:
|
100
66
|
- application/json;charset=utf-8
|
101
67
|
Content-Length:
|
102
|
-
- '
|
68
|
+
- '418'
|
103
69
|
Connection:
|
104
70
|
- keep-alive
|
105
71
|
Strict-Transport-Security:
|
@@ -112,10 +78,10 @@ http_interactions:
|
|
112
78
|
encoding: UTF-8
|
113
79
|
string: |-
|
114
80
|
{
|
115
|
-
"full_url": "https://
|
116
|
-
"thumb_url": "https://
|
117
|
-
"thumb450_url": "https://
|
81
|
+
"full_url": "https://ol2010.capture.litmuscdn.com/92d9cb6d-6ea0-4b46-813c-3025214f80fd/results/ol2010-vertical-blocked-1366.png",
|
82
|
+
"thumb_url": "https://ol2010.capture.litmuscdn.com/92d9cb6d-6ea0-4b46-813c-3025214f80fd/results/ol2010-vertical-blocked-1366-thumb.png",
|
83
|
+
"thumb450_url": "https://ol2010.capture.litmuscdn.com/92d9cb6d-6ea0-4b46-813c-3025214f80fd/results/ol2010-vertical-blocked-1366-thumb450.png"
|
118
84
|
}
|
119
85
|
http_version:
|
120
|
-
recorded_at:
|
86
|
+
recorded_at: Mon, 20 Jun 2016 11:44:05 GMT
|
121
87
|
recorded_with: VCR 2.9.3
|
@@ -19,7 +19,7 @@ http_interactions:
|
|
19
19
|
Server:
|
20
20
|
- nginx
|
21
21
|
Date:
|
22
|
-
-
|
22
|
+
- Mon, 20 Jun 2016 11:44:04 GMT
|
23
23
|
Content-Type:
|
24
24
|
- application/json;charset=utf-8
|
25
25
|
Content-Length:
|
@@ -35,5 +35,5 @@ http_interactions:
|
|
35
35
|
"description": "'email_guid' must match format of a standard GUID"
|
36
36
|
}
|
37
37
|
http_version:
|
38
|
-
recorded_at:
|
38
|
+
recorded_at: Mon, 20 Jun 2016 11:44:07 GMT
|
39
39
|
recorded_with: VCR 2.9.3
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https
|
5
|
+
uri: https://instant-api.litmus.com/v1/emails
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: '{"plain_text":"Hej världen! Kärlek, den svenska kocken."}'
|
@@ -11,6 +11,8 @@ http_interactions:
|
|
11
11
|
- application/json
|
12
12
|
Accept:
|
13
13
|
- application/json
|
14
|
+
Authorization:
|
15
|
+
- Basic Y3hkNHR1c3F3b2tnZ2dseGl6ZDl2cDd6bXV4dmo2eG95a2UxOg==
|
14
16
|
response:
|
15
17
|
status:
|
16
18
|
code: 200
|
@@ -19,7 +21,7 @@ http_interactions:
|
|
19
21
|
Server:
|
20
22
|
- nginx
|
21
23
|
Date:
|
22
|
-
-
|
24
|
+
- Mon, 20 Jun 2016 11:44:03 GMT
|
23
25
|
Content-Type:
|
24
26
|
- application/json;charset=utf-8
|
25
27
|
Content-Length:
|
@@ -36,13 +38,13 @@ http_interactions:
|
|
36
38
|
encoding: UTF-8
|
37
39
|
string: |-
|
38
40
|
{
|
39
|
-
"email_guid": "
|
41
|
+
"email_guid": "92d9cb6d-6ea0-4b46-813c-3025214f80fd"
|
40
42
|
}
|
41
43
|
http_version:
|
42
|
-
recorded_at:
|
44
|
+
recorded_at: Mon, 20 Jun 2016 11:44:06 GMT
|
43
45
|
- request:
|
44
46
|
method: post
|
45
|
-
uri: https://instant-api.litmus.com/v1/emails/
|
47
|
+
uri: https://instant-api.litmus.com/v1/emails/92d9cb6d-6ea0-4b46-813c-3025214f80fd/previews/prefetch
|
46
48
|
body:
|
47
49
|
encoding: UTF-8
|
48
50
|
string: '{"configurations":[{"client":"OL2010"},{"client":"OL2001MYSPACEODYSSEY"}]}'
|
@@ -59,11 +61,11 @@ http_interactions:
|
|
59
61
|
Server:
|
60
62
|
- nginx
|
61
63
|
Date:
|
62
|
-
-
|
64
|
+
- Mon, 20 Jun 2016 11:44:04 GMT
|
63
65
|
Content-Type:
|
64
66
|
- application/json;charset=utf-8
|
65
67
|
Content-Length:
|
66
|
-
- '
|
68
|
+
- '126'
|
67
69
|
Connection:
|
68
70
|
- keep-alive
|
69
71
|
body:
|
@@ -72,8 +74,8 @@ http_interactions:
|
|
72
74
|
{
|
73
75
|
"status": 400,
|
74
76
|
"title": "Bad Request",
|
75
|
-
"description": "Each client must be valid, OL2001MYSPACEODYSSEY is unknown"
|
77
|
+
"description": "Each client must be valid, 'OL2001MYSPACEODYSSEY' is unknown"
|
76
78
|
}
|
77
79
|
http_version:
|
78
|
-
recorded_at:
|
80
|
+
recorded_at: Mon, 20 Jun 2016 11:44:06 GMT
|
79
81
|
recorded_with: VCR 2.9.3
|
@@ -2,7 +2,7 @@
|
|
2
2
|
http_interactions:
|
3
3
|
- request:
|
4
4
|
method: post
|
5
|
-
uri: https
|
5
|
+
uri: https://instant-api.litmus.com/v1/emails
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
8
|
string: '{"plain_text":"Hej världen! Kärlek, den svenska kocken."}'
|
@@ -11,6 +11,8 @@ http_interactions:
|
|
11
11
|
- application/json
|
12
12
|
Accept:
|
13
13
|
- application/json
|
14
|
+
Authorization:
|
15
|
+
- Basic Y3hkNHR1c3F3b2tnZ2dseGl6ZDl2cDd6bXV4dmo2eG95a2UxOg==
|
14
16
|
response:
|
15
17
|
status:
|
16
18
|
code: 200
|
@@ -19,7 +21,7 @@ http_interactions:
|
|
19
21
|
Server:
|
20
22
|
- nginx
|
21
23
|
Date:
|
22
|
-
-
|
24
|
+
- Mon, 20 Jun 2016 11:44:05 GMT
|
23
25
|
Content-Type:
|
24
26
|
- application/json;charset=utf-8
|
25
27
|
Content-Length:
|
@@ -36,13 +38,13 @@ http_interactions:
|
|
36
38
|
encoding: UTF-8
|
37
39
|
string: |-
|
38
40
|
{
|
39
|
-
"email_guid": "
|
41
|
+
"email_guid": "92d9cb6d-6ea0-4b46-813c-3025214f80fd"
|
40
42
|
}
|
41
43
|
http_version:
|
42
|
-
recorded_at:
|
44
|
+
recorded_at: Mon, 20 Jun 2016 11:44:08 GMT
|
43
45
|
- request:
|
44
46
|
method: post
|
45
|
-
uri: https://instant-api.litmus.com/v1/emails/
|
47
|
+
uri: https://instant-api.litmus.com/v1/emails/92d9cb6d-6ea0-4b46-813c-3025214f80fd/previews/prefetch
|
46
48
|
body:
|
47
49
|
encoding: UTF-8
|
48
50
|
string: '{"configurations":[{"client":"OL2010","images":"allowed"},{"client":"IPAD","orientation":"vertical"}]}'
|
@@ -59,7 +61,7 @@ http_interactions:
|
|
59
61
|
Server:
|
60
62
|
- nginx
|
61
63
|
Date:
|
62
|
-
-
|
64
|
+
- Mon, 20 Jun 2016 11:44:06 GMT
|
63
65
|
Content-Type:
|
64
66
|
- application/json;charset=utf-8
|
65
67
|
Content-Length:
|
@@ -84,5 +86,5 @@ http_interactions:
|
|
84
86
|
]
|
85
87
|
}
|
86
88
|
http_version:
|
87
|
-
recorded_at:
|
89
|
+
recorded_at: Mon, 20 Jun 2016 11:44:08 GMT
|
88
90
|
recorded_with: VCR 2.9.3
|
data/lib/litmus/instant.rb
CHANGED
@@ -4,7 +4,7 @@ require "uri"
|
|
4
4
|
require "cgi"
|
5
5
|
|
6
6
|
module Litmus
|
7
|
-
|
7
|
+
class Instant
|
8
8
|
include HTTParty
|
9
9
|
|
10
10
|
base_uri "https://instant-api.litmus.com/v1"
|
@@ -16,6 +16,11 @@ module Litmus
|
|
16
16
|
class ApiError < Error; end
|
17
17
|
class RequestError < ApiError; end
|
18
18
|
class AuthenticationError < ApiError; end
|
19
|
+
class AuthorizationError < ApiError; end
|
20
|
+
class InvalidOAuthToken < AuthenticationError; end
|
21
|
+
class InvalidOAuthScope < AuthorizationError; end
|
22
|
+
class InactiveUserError < AuthorizationError; end
|
23
|
+
|
19
24
|
class ServiceError < ApiError; end
|
20
25
|
class TimeoutError < ApiError; end
|
21
26
|
class NotFound < ApiError; end
|
@@ -42,16 +47,64 @@ module Litmus
|
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
50
|
+
# This allows us to create API Client instances, useful primarily with
|
51
|
+
# OAuth, to set a token for each authorized user in a thread safe manner
|
52
|
+
# All the class methods on `Instant` are made available on the instance
|
53
|
+
class Client
|
54
|
+
class << self
|
55
|
+
def new(oauth_token: nil, api_key: nil)
|
56
|
+
Class.new(Instant) do |klass|
|
57
|
+
extend Forwardable
|
58
|
+
|
59
|
+
def_delegators(
|
60
|
+
:"self.class",
|
61
|
+
*(Litmus::Instant.methods - Object.methods)
|
62
|
+
)
|
63
|
+
|
64
|
+
klass.oauth_token = oauth_token if oauth_token
|
65
|
+
klass.api_key = api_key if api_key
|
66
|
+
end.new
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
45
71
|
# Get or set your Instant API key
|
46
72
|
# @return [String]
|
47
|
-
def self.api_key(key=nil)
|
48
|
-
if key
|
49
|
-
@key = key
|
50
|
-
self.basic_auth key, ""
|
51
|
-
end
|
73
|
+
def self.api_key(key = nil)
|
74
|
+
self.api_key = key if key
|
52
75
|
@key
|
53
76
|
end
|
54
|
-
|
77
|
+
|
78
|
+
# Set your Instant API key
|
79
|
+
def self.api_key=(key)
|
80
|
+
self.default_options.delete :basic_auth
|
81
|
+
basic_auth key, "" if key
|
82
|
+
@key = key
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get or set a global OAuth token to use
|
86
|
+
# This is *not* thread safe, if you intend to authorize multiple end users
|
87
|
+
# within the same application use
|
88
|
+
#
|
89
|
+
# Litmus::Instant::Client.new(oauth_token: "XXX")
|
90
|
+
#
|
91
|
+
# @return [String]
|
92
|
+
def self.oauth_token(token = nil)
|
93
|
+
self.api_token = token if token
|
94
|
+
@token
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set an OAuth token to be used globally
|
98
|
+
# This is *not* thread safe, if you intend to authorize multiple end users
|
99
|
+
# within the same application use
|
100
|
+
#
|
101
|
+
# Litmus::Instant::Client.new(oauth_token: "XXX")
|
102
|
+
#
|
103
|
+
def self.oauth_token=(token)
|
104
|
+
self.default_options[:headers].delete "Authorization"
|
105
|
+
self.headers("Authorization" => "Bearer #{token}") if token
|
106
|
+
@token = token
|
107
|
+
end
|
55
108
|
|
56
109
|
# Describe an email’s content and metadata and, in exchange, receive an
|
57
110
|
# +email_guid+ required to capture previews of it
|
@@ -85,6 +138,10 @@ module Litmus
|
|
85
138
|
# possible. This can be a useful performance optimisation.
|
86
139
|
# See +.prefetch_previews+ for further detail on format.
|
87
140
|
#
|
141
|
+
# @param [String] token
|
142
|
+
# optional OAuth authentication token when calling on behalf of a Litmus
|
143
|
+
# user. This will be different for each OAuth connected user.
|
144
|
+
#
|
88
145
|
# @return [Hash] the response containing the +email_guid+ and also
|
89
146
|
# confirmation of +end_user_id+ and +configurations+ if provided
|
90
147
|
def self.create_email(email)
|
@@ -189,22 +246,37 @@ module Litmus
|
|
189
246
|
end
|
190
247
|
end
|
191
248
|
|
192
|
-
|
249
|
+
#
|
250
|
+
# Private ==================================================================
|
251
|
+
#
|
252
|
+
|
253
|
+
# This deliberately allows for multiple authentication challenges within
|
254
|
+
# WWW-Authenticate
|
255
|
+
BEARER_REGEX = /Bearer realm=\"([^\"]*)\"\, error=\"(?<name>[^\"]*)\"\, error_description=\"(?<description>[^\"]*)\"/
|
193
256
|
|
194
257
|
# This avoids browser per domain connection limits
|
195
258
|
def self.sharded_base_uri(client)
|
196
|
-
|
259
|
+
# only shard where it's supported
|
260
|
+
if base_uri =~ /\/\/instant-api/
|
261
|
+
base_uri.gsub("://","://#{client}.")
|
262
|
+
else
|
263
|
+
base_uri
|
264
|
+
end
|
197
265
|
end
|
198
266
|
|
199
267
|
def self.raise_on_failure(response)
|
200
268
|
unless response.success?
|
201
269
|
message = response["description"] || ""
|
202
270
|
|
271
|
+
bearer_error = extract_bearer_error(response.headers)
|
272
|
+
raise bearer_error if bearer_error
|
273
|
+
|
203
274
|
raise AuthenticationError.new(message) if response.code == 401
|
204
|
-
raise
|
205
|
-
raise
|
206
|
-
raise
|
207
|
-
raise
|
275
|
+
raise AuthorizationError.new(message) if response.code == 403
|
276
|
+
raise RequestError.new(message) if response.code == 400
|
277
|
+
raise NotFound.new(message) if response.code == 404
|
278
|
+
raise TimeoutError.new(message) if response.code == 504
|
279
|
+
raise ServiceError.new(message) if response.code == 500
|
208
280
|
|
209
281
|
# For all other errors
|
210
282
|
raise ApiError.new(message)
|
@@ -212,5 +284,26 @@ module Litmus
|
|
212
284
|
|
213
285
|
response
|
214
286
|
end
|
287
|
+
|
288
|
+
def self.extract_bearer_error(headers)
|
289
|
+
matches = headers["WWW-Authenticate"] &&
|
290
|
+
headers["WWW-Authenticate"].match(BEARER_REGEX)
|
291
|
+
|
292
|
+
return unless matches
|
293
|
+
|
294
|
+
name = matches[:name]
|
295
|
+
message = matches[:description]
|
296
|
+
|
297
|
+
klass = case name
|
298
|
+
when "invalid_token" then InvalidOAuthToken
|
299
|
+
when "invalid_scope" then InvalidOAuthScope
|
300
|
+
when "inactive_user" then InactiveUserError
|
301
|
+
end
|
302
|
+
|
303
|
+
klass && klass.new(message)
|
304
|
+
end
|
305
|
+
|
306
|
+
private_constant :BEARER_REGEX
|
307
|
+
private_class_method :sharded_base_uri, :raise_on_failure, :extract_bearer_error
|
215
308
|
end
|
216
309
|
end
|