cpaas-sdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CHANGELOG.md +11 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +1 -0
  8. data/README.md +25 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/cpaas-sdk.gemspec +32 -0
  13. data/docs/Cpaas.html +446 -0
  14. data/docs/Cpaas/Conversation.html +1742 -0
  15. data/docs/Cpaas/Notification.html +301 -0
  16. data/docs/Cpaas/TwoFactor.html +908 -0
  17. data/docs/_index.html +146 -0
  18. data/docs/_index.md +21 -0
  19. data/docs/class_list.html +51 -0
  20. data/docs/css/common.css +1 -0
  21. data/docs/css/full_list.css +58 -0
  22. data/docs/css/style.css +496 -0
  23. data/docs/file.README.html +102 -0
  24. data/docs/file._index.html +94 -0
  25. data/docs/file_list.html +56 -0
  26. data/docs/frames.html +17 -0
  27. data/docs/index.html +94 -0
  28. data/docs/js/app.js +303 -0
  29. data/docs/js/full_list.js +216 -0
  30. data/docs/js/jquery.js +4 -0
  31. data/docs/method_list.html +251 -0
  32. data/docs/mv_index.html +102 -0
  33. data/docs/top-level-namespace.html +663 -0
  34. data/examples/2fa/.env.example +6 -0
  35. data/examples/2fa/.gitignore +159 -0
  36. data/examples/2fa/.ruby-gemset +1 -0
  37. data/examples/2fa/.ruby-version +1 -0
  38. data/examples/2fa/Gemfile +8 -0
  39. data/examples/2fa/README.md +34 -0
  40. data/examples/2fa/app.rb +134 -0
  41. data/examples/2fa/config.ru +10 -0
  42. data/examples/2fa/helper.rb +37 -0
  43. data/examples/2fa/public/stylesheets/forms.css +28 -0
  44. data/examples/2fa/public/stylesheets/global.css +7 -0
  45. data/examples/2fa/public/stylesheets/layout.css +45 -0
  46. data/examples/2fa/public/stylesheets/main.css +3 -0
  47. data/examples/2fa/views/alert.erb +5 -0
  48. data/examples/2fa/views/dashboard.erb +4 -0
  49. data/examples/2fa/views/index.erb +17 -0
  50. data/examples/2fa/views/login.erb +13 -0
  51. data/examples/2fa/views/verify.erb +8 -0
  52. data/examples/sms/.env.example +4 -0
  53. data/examples/sms/.gitignore +159 -0
  54. data/examples/sms/.ruby-gemset +1 -0
  55. data/examples/sms/.ruby-version +1 -0
  56. data/examples/sms/Gemfile +8 -0
  57. data/examples/sms/README.md +80 -0
  58. data/examples/sms/app.rb +87 -0
  59. data/examples/sms/config.ru +10 -0
  60. data/examples/sms/helper.rb +33 -0
  61. data/examples/sms/public/scripts/notification.js +46 -0
  62. data/examples/sms/public/stylesheets/forms.css +28 -0
  63. data/examples/sms/public/stylesheets/global.css +7 -0
  64. data/examples/sms/public/stylesheets/layout.css +74 -0
  65. data/examples/sms/public/stylesheets/main.css +3 -0
  66. data/examples/sms/views/alert.erb +5 -0
  67. data/examples/sms/views/index.erb +48 -0
  68. data/lib/cpaas-sdk.rb +30 -0
  69. data/lib/cpaas-sdk/api.rb +139 -0
  70. data/lib/cpaas-sdk/config.rb +9 -0
  71. data/lib/cpaas-sdk/resources.rb +4 -0
  72. data/lib/cpaas-sdk/resources/conversation.rb +268 -0
  73. data/lib/cpaas-sdk/resources/notification.rb +62 -0
  74. data/lib/cpaas-sdk/resources/notification_channel.rb +39 -0
  75. data/lib/cpaas-sdk/resources/twofactor.rb +136 -0
  76. data/lib/cpaas-sdk/util.rb +93 -0
  77. data/lib/cpaas-sdk/version.rb +3 -0
  78. data/tutorials/2FA.md +109 -0
  79. data/tutorials/2fa-flow.png +0 -0
  80. data/tutorials/GetStarted.md +86 -0
  81. data/tutorials/SMSMessaging.md +132 -0
  82. data/tutorials/index.html +86 -0
  83. data/tutorials/quickstarts.yml +15 -0
  84. metadata +238 -0
@@ -0,0 +1,46 @@
1
+ (function (window) {
2
+ function syntaxHighlight (obj) {
3
+ let json = JSON.stringify(obj, undefined, 4)
4
+ json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
5
+
6
+ return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, function (match) {
7
+ var cls = 'number'
8
+ if (/^"/.test(match)) {
9
+ if (/:$/.test(match)) {
10
+ cls = 'key'
11
+ } else {
12
+ cls = 'string'
13
+ }
14
+ } else if (/true|false/.test(match)) {
15
+ cls = 'boolean'
16
+ } else if (/null/.test(match)) {
17
+ cls = 'null'
18
+ }
19
+ return '<span class="' + cls + '">' + match + '</span>'
20
+ })
21
+ }
22
+
23
+ function render () {
24
+ const { host, protocol } = window.location
25
+
26
+ window.fetch(`${protocol}//${host}/notifications`)
27
+ .then(res => res.json().then(data => ({ status: res.status, body: data })))
28
+ .then((res) => {
29
+ if (res.status === 200 && res.body && res.body.length) {
30
+ const notifications = res.body
31
+ const notificationWrapper = document.getElementById('notification')
32
+ let html = ''
33
+
34
+ for (let i in notifications) {
35
+ html += '<pre class="notification">' + syntaxHighlight(notifications[i]) + '</pre>'
36
+ }
37
+
38
+ notificationWrapper.innerHTML = html
39
+ }
40
+ })
41
+ }
42
+
43
+ window.smsNotification = {
44
+ render
45
+ }
46
+ })(window)
@@ -0,0 +1,28 @@
1
+ .input-group {
2
+ display: flex;
3
+ flex-direction: column;
4
+ }
5
+
6
+ input[type=text],
7
+ input[type=password] {
8
+ border-radius: 4px;
9
+ border: 1px solid #ccc;
10
+ box-sizing: border-box;
11
+ display: inline-block;
12
+ font-size: 14px;
13
+ margin: 8px 0;
14
+ padding: 12px 20px;
15
+ width: 100%;
16
+ }
17
+
18
+ button {
19
+ background-color: #4CAF50;
20
+ border-radius: 5px;
21
+ border: none;
22
+ color: white;
23
+ cursor: pointer;
24
+ font-size: 14px;
25
+ margin: 8px 0;
26
+ padding: 14px 20px;
27
+ width: 100%;
28
+ }
@@ -0,0 +1,7 @@
1
+ body {
2
+ font-family: Arial, Helvetica, sans-serif;
3
+ height: 100%;
4
+ margin: 0;
5
+ padding: 0;
6
+ width: 100%;
7
+ }
@@ -0,0 +1,74 @@
1
+ .container {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: space-around;
5
+ height: 100vh;
6
+ }
7
+
8
+ .box {
9
+ border-radius: 5px;
10
+ border: 1px black solid;
11
+ height: 450px;
12
+ padding: 40px;
13
+ width: 350px;
14
+ display: flex;
15
+ flex-direction: column;
16
+ }
17
+
18
+ .vertically-center {
19
+ justify-content: center;
20
+ }
21
+
22
+ .notification-box {
23
+ overflow-y: auto;
24
+ }
25
+
26
+ .solid-background {
27
+ background-color: #f2f2f2;
28
+ }
29
+
30
+ .text-center {
31
+ text-align: center;
32
+ }
33
+
34
+ .alert {
35
+ align-items: center;
36
+ border-radius: 5px;
37
+ border: 1px solid transparent;
38
+ display: flex;
39
+ height: 30px;
40
+ justify-content: center;
41
+ left: 10%;
42
+ padding: 10px 20px;
43
+ position: absolute;
44
+ top: 10px;
45
+ width: 80%;
46
+ }
47
+
48
+ .alert-error {
49
+ color: #721c24;
50
+ background-color: #f8d7da;
51
+ border-color: #f5c6cb;
52
+ }
53
+
54
+ .alert-success {
55
+ color: #155724;
56
+ background-color: #d4edda;
57
+ border-color: #c3e6cb;
58
+ }
59
+
60
+ .notification-box {
61
+ display: flex;
62
+ flex-direction: column;
63
+ }
64
+
65
+ pre {
66
+ outline: 1px solid #ccc;
67
+ padding: 5px;
68
+ margin: 5px auto;
69
+ }
70
+ .string { color: green; }
71
+ .number { color: darkorange; }
72
+ .boolean { color: blue; }
73
+ .null { color: magenta; }
74
+ .key { color: red; }
@@ -0,0 +1,3 @@
1
+ @import './global.css';
2
+ @import './layout.css';
3
+ @import './forms.css';
@@ -0,0 +1,5 @@
1
+ <% if locals.dig(:alert, :message) %>
2
+ <div class="alert alert-<%= alert[:type] %>">
3
+ <p><%= alert[:message] %></p>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,48 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ <title>SMS | Home</title>
8
+
9
+ <link rel="stylesheet" type="text/css" href="stylesheets/main.css">
10
+ <script src="scripts/notification.js"></script>
11
+ </head>
12
+ <body>
13
+ <%= erb :alert, locals: locals %>
14
+ <div class="container">
15
+ <div class="box solid-background vertically-center">
16
+ <h2 class="text-center">Send SMS</h2>
17
+ <form action="/send" method="post">
18
+ <div class="input-group">
19
+ <label for="number">Phone number (E164 format)</label>
20
+ <input type="text" name="number" id="number" placeholder="+12223334444"/>
21
+ </div>
22
+ <div class="input-group">
23
+ <label>Message</label>
24
+ <input type="text" name="message" id="message" />
25
+ </div>
26
+ <button type="submit">Send</button>
27
+ </form>
28
+ </div>
29
+ <div class="box">
30
+ <form action="/subscribe" method="post">
31
+ <div class="input-group">
32
+ <label for="webhook">Webhook host URL(Ref. README for details)</label>
33
+ <input type="text" name="webhook" id="webhook" />
34
+ </div>
35
+ <button type="submit">Subscribe</button>
36
+ </form>
37
+ <h2 class="text-center">SMS Notification</h2>
38
+ <div id="notification" class="notification-box"></div>
39
+ </div>
40
+ </div>
41
+ <script>
42
+ if (window.smsNotification) {
43
+ window.smsNotification.render()
44
+ setInterval(window.smsNotification.render, 5000)
45
+ }
46
+ </script>
47
+ </body>
48
+ </html>
data/lib/cpaas-sdk.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'cpaas-sdk/api'
2
+ require 'cpaas-sdk/config'
3
+ require 'cpaas-sdk/resources'
4
+ require 'cpaas-sdk/version'
5
+
6
+ module Cpaas
7
+ class << self
8
+ attr_accessor :config, :api
9
+ end
10
+
11
+ #
12
+ # Configure the SDK with client_id and client_secret.
13
+ #
14
+ # @param client_id [String] Private project secret
15
+ # @param client_secret [String] Private project secret
16
+ # @param base_url [String] JSON URL of the server to be used.
17
+ #
18
+ # @example
19
+ # Cpaas.configure do |config|
20
+ # config.client_id: '<private project key>',
21
+ # config.client_secret: '<private project secret>',
22
+ # config.base_url: '<base url>'
23
+ # end
24
+ #
25
+ def self.configure
26
+ yield self.config = Cpaas::Config.new
27
+
28
+ self.api = Cpaas::Api.new(config)
29
+ end
30
+ end
@@ -0,0 +1,139 @@
1
+ require 'httparty'
2
+ require 'jwt'
3
+
4
+ require 'cpaas-sdk/util'
5
+
6
+ module Cpaas
7
+ # @private
8
+ class Api
9
+ include HTTParty
10
+ format :json
11
+
12
+ attr_accessor :user_id, :client_correlator
13
+
14
+ def initialize(config)
15
+ @client_id = config.client_id
16
+ @client_secret = config.client_secret
17
+ @id_token_parsed = nil
18
+ @access_token = nil
19
+ self.user_id = nil
20
+ self.client_correlator = "#{config.client_id}-ruby"
21
+
22
+ self.class.base_uri config.base_url
23
+
24
+ auth_token
25
+ end
26
+
27
+ def send_request(url, options = {}, verb = :get, with_token = true)
28
+ body = recursive_compact(options[:body]) if options[:body]
29
+ options[:headers] = headers(options[:headers] || {}, with_token)
30
+ options[:body] = body.to_json if options[:headers]['Content-Type'] == 'application/json'
31
+ options[:query] = options[:query] if options.has_key? :query
32
+
33
+ case verb
34
+ when :get
35
+ response = self.class.get(url, options)
36
+ when :post
37
+ response = self.class.post(url, options)
38
+ when :put
39
+ response = self.class.put(url, options)
40
+ when :delete
41
+ response = self.class.delete(url, options)
42
+ else
43
+ raise 'Invalid Verb'
44
+ end
45
+
46
+ handle_response(response)
47
+ end
48
+
49
+ def handle_response(response)
50
+ @parsed_response = begin
51
+ res = convert_hash_keys(response.parsed_response)
52
+
53
+ if response.code >= 400 && !res.nil?
54
+ compose_error_from(res)
55
+ else
56
+ res || { status_code: response.code, response: response }
57
+ end
58
+ rescue JSON::ParserError => e
59
+ response.success? ? { message: response.body } : { error: response.body }
60
+ end
61
+ end
62
+
63
+ def headers(request_headers = {}, with_token = false)
64
+ base_headers = {
65
+ 'X-Cpaas-Agent' => "ruby-sdk/#{Cpaas::VERSION}",
66
+ 'Content-Type' => 'application/json',
67
+ 'Accept' => '*/*',
68
+ }.merge(request_headers)
69
+
70
+ return base_headers.merge(auth_headers) if with_token
71
+
72
+ base_headers
73
+ end
74
+
75
+ def auth_headers
76
+ {
77
+ 'Authorization' => "Bearer #{auth_token}"
78
+ }
79
+ end
80
+
81
+ def auth_token
82
+ set_tokens(get_auth_token) if token_expired
83
+
84
+ @access_token
85
+ end
86
+
87
+ def get_auth_token
88
+ options = {
89
+ body: {
90
+ grant_type: 'client_credentials',
91
+ client_id: @client_id,
92
+ client_secret: @client_secret,
93
+ scope: 'openid'
94
+ },
95
+ headers: {
96
+ 'Content-Type' => 'application/x-www-form-urlencoded'
97
+ }
98
+ }
99
+
100
+ response = send_request('/cpaas/auth/v1/token', options, :post , false)
101
+
102
+ process_response(response, false)
103
+ end
104
+
105
+ def token_expired
106
+ return true if @access_token.nil?
107
+
108
+ min_buffer = (@token_parsed['exp'] - @token_parsed['iat']) / 2
109
+ expires_in = @token_parsed['exp'] - Time.now.to_i - min_buffer
110
+
111
+ expires_in < 0
112
+ end
113
+
114
+ def set_tokens(tokens)
115
+ if tokens[:access_token].nil?
116
+ @access_token = nil
117
+ @id_token = nil
118
+ @id_token_parsed = nil
119
+ @self.user_id = nil
120
+ else
121
+ @access_token = tokens[:access_token]
122
+ @id_token = tokens[:id_token]
123
+ @id_token_parsed = JWT.decode(tokens[:id_token], nil, false).first
124
+ @token_parsed = JWT.decode(tokens[:access_token], nil, false).first
125
+ self.user_id = @id_token_parsed['preferred_username']
126
+ end
127
+ end
128
+
129
+ def recursive_compact(hash_or_array)
130
+ p = proc do |*args|
131
+ v = args.last
132
+ v.delete_if(&p) if v.respond_to? :delete_if
133
+ v.nil? || v.respond_to?(:"empty?") && v.empty?
134
+ end
135
+
136
+ hash_or_array.delete_if(&p)
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,9 @@
1
+ module Cpaas
2
+ # @private
3
+
4
+ class Config
5
+ attr_accessor :client_id
6
+ attr_accessor :client_secret
7
+ attr_accessor :base_url
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'cpaas-sdk/resources/conversation'
2
+ require 'cpaas-sdk/resources/twofactor'
3
+ require 'cpaas-sdk/resources/notification_channel'
4
+ require 'cpaas-sdk/resources/notification'
@@ -0,0 +1,268 @@
1
+ require 'cpaas-sdk/util'
2
+
3
+ module Cpaas
4
+
5
+ #
6
+ # CPaaS conversation.
7
+ #
8
+ class Conversation
9
+ #
10
+ # Send a new outbound message
11
+ #
12
+ # @param params [Hash]
13
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
14
+ # @option params [String] :sender_address Sender address information, basically the from address. E164 formatted DID number passed as a value, which is owned by the user. If the user wants to let CPaaS uses the default assigned DID number, this field can either has "default" value or the same value as the userId.
15
+ # @option params [Array[string]|String] :destination_address
16
+ # @option params [String] :message text message
17
+ #
18
+ def self.create_message(params)
19
+ if params[:type] == types[:SMS]
20
+ address = (params[:destination_address].is_a? String) ? [ params[:destination_address] ] : params[:destination_address]
21
+
22
+ options = {
23
+ body: {
24
+ outboundSMSMessageRequest: {
25
+ address: address,
26
+ clientCorrelator: Cpaas.api.client_correlator,
27
+ outboundSMSTextMessage: {
28
+ message: params[:message]
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ response = Cpaas.api.send_request("#{base_url}/outbound/#{params[:sender_address]}/requests", options, :post)
35
+ process_response(response) do |res|
36
+ outboundSMS = res.dig(:outbound_sms_message_request)
37
+
38
+ {
39
+ message: outboundSMS.dig(:outbound_sms_text_message, :message),
40
+ senderAddress: outboundSMS.dig(:sender_address),
41
+ deliveryInfo: outboundSMS.dig(:delivery_info_list, :delivery_info)
42
+ }
43
+ end
44
+ end
45
+ end
46
+
47
+ #
48
+ # Gets all messages.
49
+ #
50
+ # @param params [Hash]
51
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
52
+ # @option params [String] :remote_address +optional+ Remote address information while retrieving the conversation history, basically the destination telephone number that user exchanged message before. E164 formatted DID number passed as a value.
53
+ # @option params [String] :local_address +optional+ Local address information while retrieving the conversation history, basically the source telephone number that user exchanged message before.
54
+ # @option params [String] :query[:name] +optional+ - Performs search operation on firstName and lastName fields.
55
+ # @option params [String] :query[:first_name] +optional+ - Performs search for the first_name field of the directory items.
56
+ # @option params [String] :query[:last_name] +optional+ - Performs search for the last_name field of the directory items.
57
+ # @option params [String] :query[:user_name] +optional+ - Performs search for the user_name field of the directory items.
58
+ # @option params [String] :query[:phone_number] +optional+ - Performs search for the fields containing a phone number, like businessPhoneNumber, homePhoneNumber, mobile, pager, fax.
59
+ # @option params [String] :query[:order] +optional+ - Ordering the contact results based on the requested sortBy value, order query parameter should be accompanied by sortBy query parameter.
60
+ # @option params [String] :query[:sort_by] +optional+ - sort_by value is used to detect sorting the contact results based on which attribute. If order is not provided with that, ascending order is used.
61
+ # @option params [Number] :query[:max] +optional+ - Maximum number of contact results that has been requested from CPaaS for this query.
62
+ # @option params [String] :query[:next] +optional+ - Pointer for the next chunk of contacts, should be gathered from the previous query results.
63
+ #
64
+ def self.get_messages(params)
65
+ if params[:type] == types[:SMS]
66
+ options = {
67
+ query: params[:query]
68
+ }
69
+
70
+ url = "#{base_url}/remoteAddresses"
71
+ url += "/#{params[:remote_address]}" if params[:remote_address]
72
+ url += "/localAddresses/#{params[:local_address]}" if params[:local_address]
73
+
74
+ response = Cpaas.api.send_request(url, options)
75
+
76
+ process_response(response) do |res|
77
+ if params[:local_address]
78
+ res.dig(:sms_thread_list, :sms_thread)
79
+ .map { |i| reject(l, :resource_url) }
80
+ else
81
+ message = res.dig(:sms_thread)
82
+ reject(message, :resource_url)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ #
89
+ # Delete conversation message
90
+ #
91
+ # @param params [Hash]
92
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
93
+ # @option params [String] :remote_address Remote address information while retrieving the conversation history, basically the destination telephone number that user exchanged message before. E164 formatted DID number passed as a value.
94
+ # @option params [String] :local_address Local address information while retrieving the conversation history, basically the source telephone number that user exchanged message before.
95
+ # @option params [String] :message_id +optional+ Identification of the message. If messeageId is not passsed then the conversation thread is deleted with all messages.
96
+ #
97
+ def self.delete_message(params)
98
+ if params[:type] == types[:SMS]
99
+ url = "#{base_url}/remoteAddresses/#{params[:remote_address]}/localAddresses/#{params[:local_address]}"
100
+
101
+ url += "/messages/#{params[:message_id]}" if params[:message_id]
102
+
103
+ Cpaas.api.send_request(url, {}, :delete)
104
+ end
105
+ end
106
+
107
+ #
108
+ # Read all messages in a thread
109
+ #
110
+ # @param params [Hash]
111
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
112
+ # @option params [String] :remote_address Remote address information while retrieving the conversation history, basically the destination telephone number that user exchanged message before. E164 formatted DID number passed as a value.
113
+ # @option params [String] :local_address Local address information while retrieving the conversation history, basically the source telephone number that user exchanged message before.
114
+ # @option params [String] :query[:next] +optional+ - Pointer for the next page to retrieve for the messages, provided by CPaaS in previous GET response.
115
+ # @option params [String] :query[:max] +optional+ - Number of messages that is requested from CPaaS.
116
+ # @option params [String] :query[:new] +optional+ - Filters the messages or threads having messages that are not received by the user yet.
117
+ # @option params [String] :query[:last_Message_Time] +optional+ - Filters the messages or threads having messages that are sent/received after provided Epoch time
118
+ #
119
+ def self.get_messages_in_thread(params)
120
+ if params[:type] == types[:SMS]
121
+ options = {
122
+ query: params[:query]
123
+ }
124
+
125
+ response = Cpaas.api.send_request("#{base_url}/remoteAddresses/#{params[:remote_address]}/localAddresses/#{params[:local_address]}/messages", options)
126
+
127
+ process_response(response) do |res|
128
+ res.dig(:sms_message_list, :sms_message)
129
+ .map { |m| reject(m, :resource_url) }
130
+ end
131
+ end
132
+ end
133
+
134
+ #
135
+ # Read a conversation message status
136
+ #
137
+ # @param params [Hash]
138
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
139
+ # @option params [String] :remote_address Remote address information while retrieving the conversation history, basically the destination telephone number that user exchanged message before. E164 formatted DID number passed as a value.
140
+ # @option params [String] :local_address Local address information while retrieving the conversation history, basically the source telephone number that user exchanged message before.
141
+ # @option params [String] :message_id Identification of the message. If messeageId is not passsed then the conversation thread is deleted with all messages.
142
+ #
143
+ def self.get_status(params)
144
+ if params[:type] == types[:SMS]
145
+ Cpaas.api.send_request("#{base_url}/remoteAddresses/#{params[:remote_address]}/localAddresses/#{params[:local_address]}/messages/#{params[:message_id]}/status")
146
+ end
147
+ end
148
+
149
+ #
150
+ # Read all active subscriptions
151
+ #
152
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
153
+ #
154
+
155
+ def self.get_subscriptions(params)
156
+ if params[:type] == types[:SMS]
157
+ response = Cpaas.api.send_request("#{base_url}/inbound/subscriptions")
158
+
159
+ process_response(response) do |res|
160
+ res.dig(:subscription_list, :subscription)
161
+ .map do |subscriptions|
162
+ {
163
+ notify_url: subscription.dig(:callback_reference, :notify_url),
164
+ destination_address: subscription.dig(:destination_address),
165
+ subscription_id: id_from(subscription.dig(:resource_url))
166
+ }
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ #
173
+ # Read active subscription
174
+ #
175
+ # @param params [Hash]
176
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
177
+ # @option params [String] :subscription_id Resource ID of the subscription
178
+ #
179
+ def self.get_subscription(params)
180
+ if params[:type] == types[:SMS]
181
+ response = Cpaas.api.send_request("#{base_url}/inbound/subscriptions/#{params[:subscription_id]}")
182
+
183
+ process_response(response) do |res|
184
+ subscription = res.dig(:subscription)
185
+
186
+ {
187
+ notify_url: subscription.dig(:callback_reference, :notify_url),
188
+ destination_address: subscription.dig(:destination_address),
189
+ subscription_id: id_from(subscription.dig(:resource_url))
190
+ }
191
+ end
192
+ end
193
+ end
194
+
195
+ #
196
+ # Create a new subscription
197
+ #
198
+ # @param params [Hash]
199
+ # @option params [String] :type Type of conversation. Possible values - 'sms'. Check Conversation.types for more options
200
+ # @option params [String] :webhook_url The notification channel ID that has been acquired during /notificationchannel API subscription, either websockets, mobile push or webhooks type, which the incoming notifications supposed to be sent to.
201
+ # @option params [String] :destination_address +optional+ The address that incoming messages are received for this subscription. If does not exist, CPaaS uses the default assigned DID number to subscribe against. It is suggested to provide the intended E164 formatted DID number within this parameter.
202
+ #
203
+
204
+ def self.subscribe(params)
205
+ if params[:type] == types[:SMS]
206
+ channel = Cpaas::NotificationChannel.create_channel(webhook_url: params[:webhook_url])
207
+
208
+ return channel if !channel.dig(:exception_id).nil?
209
+
210
+ options = {
211
+ body: {
212
+ subscription: {
213
+ callbackReference: {
214
+ notifyURL: channel[:channel_id]
215
+ },
216
+ clientCorrelator: Cpaas.api.client_correlator,
217
+ destinationAddress: params[:destination_address]
218
+ }
219
+ }
220
+ }
221
+
222
+ response = Cpaas.api.send_request("#{base_url}/inbound/subscriptions", options, :post)
223
+
224
+ process_response(response) do |res|
225
+ {
226
+ webhook_url: params[:webhook_url],
227
+ destination_address: response.dig(:subscription, :destination_address),
228
+ subscription_id: id_from(response.dig(:subscription, :resource_url))
229
+ }
230
+ end
231
+ end
232
+ end
233
+
234
+ #
235
+ # Unsubscription from conversation notification
236
+ #
237
+ # @param params [Hash]
238
+ # @option params [String] :subscription_id Resource ID of the subscription.
239
+ #
240
+
241
+ def self.unsubscribe(params = {})
242
+ if params[:type] == types[:SMS]
243
+ response = Cpaas.api.send_request("#{base_url}/inbound/subscriptions/#{params[:subscription_id]}", {}, :delete)
244
+
245
+ process_response(response) do |res|
246
+ {
247
+ subscription_id: params[:subscription_id],
248
+ success: true,
249
+ message: "Unsubscribed from #{params[:type]} conversation notification"
250
+ }
251
+ end
252
+ end
253
+ end
254
+
255
+ # @private
256
+ def self.types
257
+ {
258
+ SMS: 'sms'
259
+ }
260
+ end
261
+
262
+ private
263
+
264
+ def self.base_url
265
+ "/cpaas/smsmessaging/v1/#{Cpaas.api.user_id}"
266
+ end
267
+ end
268
+ end