litmus-instant 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|