notifications-ruby-client 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ FROM ruby:2.3.1-slim
2
+
3
+ ARG HTTP_PROXY
4
+ ARG HTTPS_PROXY
5
+ ARG NO_PROXY
6
+
7
+ RUN \
8
+ echo "Install Debian packages" \
9
+ && ([ -z "$HTTP_PROXY" ] || echo "Acquire::http::Proxy \"${HTTP_PROXY}\";" > /etc/apt/apt.conf.d/99HttpProxy) \
10
+ && apt-get update \
11
+ && apt-get install -y --no-install-recommends \
12
+ gcc \
13
+ make \
14
+ curl \
15
+ git \
16
+
17
+ && echo "Clean up" \
18
+ && rm -rf /var/lib/apt/lists/* /tmp/*
19
+
20
+ ENV PATH=/var/project/vendor/bin:$PATH \
21
+ BUNDLE_PATH="/var/project/vendor/bundle" \
22
+ BUNDLE_BIN="/var/project/vendor/bin" \
23
+ BUNDLE_APP_CONFIG="/var/project/.bundle"
24
+
25
+
26
+ WORKDIR /var/project
@@ -0,0 +1,16 @@
1
+ .DEFAULT_GOAL := help
2
+ SHELL := /bin/bash
3
+
4
+ .PHONY: help
5
+ help:
6
+ @cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
7
+
8
+ .PHONY: build
9
+ build:
10
+ docker pull `grep "FROM " Dockerfile | cut -d ' ' -f 2` || true
11
+ docker build \
12
+ --build-arg HTTP_PROXY="${HTTP_PROXY}" \
13
+ --build-arg HTTPS_PROXY="${HTTP_PROXY}" \
14
+ --build-arg NO_PROXY="${NO_PROXY}" \
15
+ -t govuk/notify-ruby-client-builder \
16
+ .
@@ -0,0 +1,153 @@
1
+ require_relative "client/version"
2
+ require_relative "client/speaker"
3
+ require_relative "client/notification"
4
+ require_relative "client/response_notification"
5
+ require_relative "client/response_precompiled_letter"
6
+ require_relative "client/notifications_collection"
7
+ require_relative "client/received_text"
8
+ require_relative "client/received_text_collection"
9
+ require_relative "client/response_template"
10
+ require_relative "client/template_collection"
11
+ require_relative "client/template_preview"
12
+ require_relative "client/uuid_validator"
13
+ require_relative "client/helper_methods"
14
+ require "forwardable"
15
+
16
+ module Notifications
17
+ class Client
18
+ attr_reader :speaker
19
+
20
+ PRODUCTION_BASE_URL = "https://api.notifications.service.gov.uk".freeze
21
+ MAX_FILE_UPLOAD_SIZE = 2 * 1024 * 1024 # 2MB limit on uploaded documents
22
+
23
+ extend Forwardable
24
+ def_delegators :speaker, :service_id, :secret_token, :base_url, :base_url=
25
+
26
+ ##
27
+ # @see Notifications::Client::Speaker#initialize
28
+ def initialize(*args)
29
+ @speaker = Speaker.new(*args)
30
+ end
31
+
32
+ ##
33
+ # @see Notifications::Client::Speaker#post
34
+ # @return [ResponseNotification]
35
+ def send_email(args)
36
+ ResponseNotification.new(
37
+ speaker.post("email", args)
38
+ )
39
+ end
40
+
41
+ ##
42
+ # @see Notifications::Client::Speaker#post
43
+ # @return [ResponseNotification]
44
+ def send_sms(args)
45
+ ResponseNotification.new(
46
+ speaker.post("sms", args)
47
+ )
48
+ end
49
+
50
+ ##
51
+ # @see Notifications::Client::Speaker#post
52
+ # @return [ResponseNotification]
53
+ def send_letter(args)
54
+ ResponseNotification.new(
55
+ speaker.post("letter", args)
56
+ )
57
+ end
58
+
59
+ ##
60
+ # @param reference [String]
61
+ # @param pdf_file [File]
62
+ # @see Notifications::Client::Speaker#post_precompiled_letter
63
+ # @return [ResponsePrecompiledLetter]
64
+ def send_precompiled_letter(reference, pdf_file, postage = nil)
65
+ ResponsePrecompiledLetter.new(
66
+ speaker.post_precompiled_letter(reference, pdf_file, postage)
67
+ )
68
+ end
69
+
70
+ ##
71
+ # @param id [String]
72
+ # @see Notifications::Client::Speaker#get
73
+ # @return [Notification]
74
+ def get_notification(id)
75
+ Notification.new(
76
+ speaker.get(id)
77
+ )
78
+ end
79
+
80
+ ##
81
+ # @param options [Hash]
82
+ # @option options [String] :template_type
83
+ # sms or email
84
+ # @option options [String] :status
85
+ # sending, delivered, permanently failed,
86
+ # temporarily failed, or technical failure
87
+ # @option options [String] :reference
88
+ # your reference for the notification
89
+ # @option options [String] :older_than
90
+ # notification id to return notificaitons that are older than this id.
91
+ # @see Notifications::Client::Speaker#get
92
+ # @return [NotificationsCollection]
93
+ def get_notifications(options = {})
94
+ NotificationsCollection.new(
95
+ speaker.get(nil, options)
96
+ )
97
+ end
98
+
99
+ ##
100
+ # @param id [String]
101
+ # @return [Template]
102
+ def get_template_by_id(id, options = {})
103
+ path = "/v2/template/" << id
104
+ Template.new(
105
+ speaker.get_with_url(path, options)
106
+ )
107
+ end
108
+
109
+ ##
110
+ # @param id [String]
111
+ # @param version [int]
112
+ # @return [Template]
113
+ def get_template_version(id, version, options = {})
114
+ path = "/v2/template/" << id << "/version/" << version.to_s
115
+ Template.new(
116
+ speaker.get_with_url(path, options)
117
+ )
118
+ end
119
+
120
+ ##
121
+ # @option options [String] :type
122
+ # email, sms, letter
123
+ # @return [TemplateCollection]
124
+ def get_all_templates(options = {})
125
+ path = "/v2/templates"
126
+ TemplateCollection.new(
127
+ speaker.get_with_url(path, options)
128
+ )
129
+ end
130
+
131
+ ##
132
+ # @param options [String]
133
+ # @option personalisation [Hash]
134
+ # @return [TemplatePreview]
135
+ def generate_template_preview(id, options = {})
136
+ path = "/v2/template/" << id << "/preview"
137
+ TemplatePreview.new(
138
+ speaker.post_with_url(path, options)
139
+ )
140
+ end
141
+
142
+ ##
143
+ # @option options [String] :older_than
144
+ # received text id to return received texts that are older than this id.
145
+ # @return [ReceivedTextCollection]
146
+ def get_received_texts(options = {})
147
+ path = "/v2/received-text-messages"
148
+ ReceivedTextCollection.new(
149
+ speaker.get_with_url(path, options)
150
+ )
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,9 @@
1
+ require "base64"
2
+
3
+ module Notifications
4
+ def self.prepare_upload(file)
5
+ raise ArgumentError.new("Document is larger than 2MB") if file.size > Client::MAX_FILE_UPLOAD_SIZE
6
+
7
+ { file: Base64.strict_encode64(file.read) }
8
+ end
9
+ end
@@ -0,0 +1,54 @@
1
+ require 'time'
2
+
3
+ module Notifications
4
+ class Client
5
+ class Notification
6
+ FIELDS = %i(
7
+ id
8
+ reference
9
+ email_address
10
+ phone_number
11
+ line_1
12
+ line_2
13
+ line_3
14
+ line_4
15
+ line_5
16
+ line_6
17
+ postcode
18
+ postage
19
+ type
20
+ status
21
+ template
22
+ body
23
+ subject
24
+ sent_at
25
+ created_at
26
+ completed_at
27
+ created_by_name
28
+ ).freeze
29
+
30
+ attr_reader(*FIELDS)
31
+
32
+ def initialize(notification)
33
+ FIELDS.each do |field|
34
+ instance_variable_set(:"@#{field}", notification.fetch(field.to_s, nil))
35
+ end
36
+ end
37
+
38
+ %i(
39
+ sent_at
40
+ created_at
41
+ completed_at
42
+ ).each do |field|
43
+ define_method field do
44
+ begin
45
+ value = instance_variable_get(:"@#{field}")
46
+ Time.parse value
47
+ rescue StandardError
48
+ value
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,19 @@
1
+ module Notifications
2
+ class Client
3
+ class NotificationsCollection
4
+ attr_reader :links,
5
+ :collection
6
+
7
+ def initialize(response)
8
+ @links = response["links"]
9
+ @collection = collection_from(response["notifications"])
10
+ end
11
+
12
+ def collection_from(notifications)
13
+ notifications.map do |notification|
14
+ Notification.new(notification)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ require 'time'
2
+
3
+ module Notifications
4
+ class Client
5
+ class ReceivedText
6
+ FIELDS = %i(
7
+ id
8
+ created_at
9
+ content
10
+ notify_number
11
+ service_id
12
+ user_number
13
+ ).freeze
14
+
15
+ attr_reader(*FIELDS)
16
+
17
+ def initialize(received_text)
18
+ FIELDS.each do |field|
19
+ instance_variable_set(:"@#{field}", received_text.fetch(field.to_s, nil))
20
+ end
21
+ end
22
+
23
+ def created_at
24
+ value = instance_variable_get(:@created_at)
25
+ Time.parse(value)
26
+ rescue StandardError
27
+ value
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module Notifications
2
+ class Client
3
+ class ReceivedTextCollection
4
+ attr_reader :links, :collection
5
+
6
+ def initialize(response)
7
+ @links = response["links"]
8
+ @collection = collection_from(response["received_text_messages"])
9
+ end
10
+
11
+ def collection_from(received_texts)
12
+ received_texts.map do |received_text|
13
+ ReceivedText.new(received_text)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ module Notifications
2
+ class Client
3
+ class RequestError < StandardError
4
+ attr_reader :code, :body
5
+
6
+ def initialize(response)
7
+ @code = response.code
8
+ @body = parse_body(response.body)
9
+ end
10
+
11
+ def parse_body(body)
12
+ JSON.parse(body)
13
+ rescue JSON::ParserError
14
+ body
15
+ end
16
+
17
+ def message
18
+ return body if body.is_a?(String)
19
+
20
+ error_messages = body.fetch('errors')
21
+ .map { |e| "#{e.fetch('error')}: #{e.fetch('message')}" }
22
+ error_messages.join(", ")
23
+ end
24
+ end
25
+
26
+ class ClientError < RequestError; end
27
+ class BadRequestError < ClientError; end
28
+ class AuthError < ClientError; end
29
+ class NotFoundError < ClientError; end
30
+ class RateLimitError < ClientError; end
31
+
32
+ class ServerError < RequestError; end
33
+
34
+ module ErrorHandling
35
+ def build_error(response)
36
+ error_class_for_code(response.code.to_i).new(response)
37
+ end
38
+
39
+ def error_class_for_code(code)
40
+ case code
41
+ when 400
42
+ BadRequestError
43
+ when 403
44
+ AuthError
45
+ when 404
46
+ NotFoundError
47
+ when 429
48
+ RateLimitError
49
+ when (400..499)
50
+ ClientError
51
+ when (500..599)
52
+ ServerError
53
+ else
54
+ RequestError
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ module Notifications
2
+ class Client
3
+ class ResponseNotification
4
+ FIELDS = %i(
5
+ id
6
+ reference
7
+ content
8
+ template
9
+ uri
10
+ ).freeze
11
+
12
+ attr_reader(*FIELDS)
13
+
14
+ def initialize(notification)
15
+ FIELDS.each do |field|
16
+ instance_variable_set(:"@#{field}", notification.fetch(field.to_s, nil))
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Notifications
2
+ class Client
3
+ class ResponsePrecompiledLetter
4
+ FIELDS = %i(
5
+ id
6
+ reference
7
+ postage
8
+ ).freeze
9
+
10
+ attr_reader(*FIELDS)
11
+
12
+ def initialize(notification)
13
+ FIELDS.each do |field|
14
+ instance_variable_set(:"@#{field}", notification.fetch(field.to_s, nil))
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ require 'time'
2
+
3
+ module Notifications
4
+ class Client
5
+ class Template
6
+ FIELDS = %i(
7
+ id
8
+ type
9
+ name
10
+ created_at
11
+ updated_at
12
+ created_by
13
+ version
14
+ body
15
+ subject
16
+ ).freeze
17
+
18
+ attr_reader(*FIELDS)
19
+
20
+ def initialize(notification)
21
+ FIELDS.each do |field|
22
+ instance_variable_set(:"@#{field}", notification.fetch(field.to_s, nil))
23
+ end
24
+ end
25
+
26
+ %i(
27
+ created_at
28
+ updated_at
29
+ ).each do |field|
30
+ define_method field do
31
+ begin
32
+ value = instance_variable_get(:"@#{field}")
33
+ Time.parse value
34
+ rescue StandardError
35
+ value
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end