flow_chat 0.4.0 → 0.4.2

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.
@@ -16,7 +16,7 @@ module FlowChat
16
16
  type: "template",
17
17
  template: {
18
18
  name: template_name,
19
- language: { code: language },
19
+ language: {code: language},
20
20
  components: components
21
21
  }
22
22
  }
@@ -27,7 +27,7 @@ module FlowChat
27
27
  # Common template structures
28
28
  def send_welcome_template(to:, name: nil)
29
29
  components = []
30
-
30
+
31
31
  if name
32
32
  components << {
33
33
  type: "header",
@@ -87,7 +87,7 @@ module FlowChat
87
87
  def create_template(name:, category:, language: "en_US", components: [])
88
88
  business_account_id = @config.business_account_id
89
89
  uri = URI("https://graph.facebook.com/v18.0/#{business_account_id}/message_templates")
90
-
90
+
91
91
  template_data = {
92
92
  name: name,
93
93
  category: category, # AUTHENTICATION, MARKETING, UTILITY
@@ -111,7 +111,7 @@ module FlowChat
111
111
  def list_templates
112
112
  business_account_id = @config.business_account_id
113
113
  uri = URI("https://graph.facebook.com/v18.0/#{business_account_id}/message_templates")
114
-
114
+
115
115
  http = Net::HTTP.new(uri.host, uri.port)
116
116
  http.use_ssl = true
117
117
 
@@ -125,7 +125,7 @@ module FlowChat
125
125
  # Get template status
126
126
  def template_status(template_id)
127
127
  uri = URI("https://graph.facebook.com/v18.0/#{template_id}")
128
-
128
+
129
129
  http = Net::HTTP.new(uri.host, uri.port)
130
130
  http.use_ssl = true
131
131
 
@@ -149,7 +149,7 @@ module FlowChat
149
149
  request.body = message_data.to_json
150
150
 
151
151
  response = http.request(request)
152
-
152
+
153
153
  unless response.is_a?(Net::HTTPSuccess)
154
154
  Rails.logger.error "WhatsApp Template API error: #{response.body}"
155
155
  return nil
@@ -159,4 +159,4 @@ module FlowChat
159
159
  end
160
160
  end
161
161
  end
162
- end
162
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flow_chat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
@@ -98,9 +98,12 @@ files:
98
98
  - bin/console
99
99
  - bin/setup
100
100
  - examples/initializer.rb
101
+ - examples/media_prompts_examples.rb
101
102
  - examples/multi_tenant_whatsapp_controller.rb
102
103
  - examples/ussd_controller.rb
103
104
  - examples/whatsapp_controller.rb
105
+ - examples/whatsapp_media_examples.rb
106
+ - examples/whatsapp_message_job.rb
104
107
  - flow_chat.gemspec
105
108
  - images/ussd_simulator.png
106
109
  - lib/flow_chat.rb
@@ -112,6 +115,8 @@ files:
112
115
  - lib/flow_chat/session/cache_session_store.rb
113
116
  - lib/flow_chat/session/middleware.rb
114
117
  - lib/flow_chat/session/rails_session_store.rb
118
+ - lib/flow_chat/simulator/controller.rb
119
+ - lib/flow_chat/simulator/views/simulator.html.erb
115
120
  - lib/flow_chat/ussd/app.rb
116
121
  - lib/flow_chat/ussd/gateway/nalo.rb
117
122
  - lib/flow_chat/ussd/gateway/nsano.rb
@@ -121,15 +126,15 @@ files:
121
126
  - lib/flow_chat/ussd/processor.rb
122
127
  - lib/flow_chat/ussd/prompt.rb
123
128
  - lib/flow_chat/ussd/renderer.rb
124
- - lib/flow_chat/ussd/simulator/controller.rb
125
- - lib/flow_chat/ussd/simulator/views/simulator.html.erb
126
129
  - lib/flow_chat/version.rb
127
130
  - lib/flow_chat/whatsapp/app.rb
131
+ - lib/flow_chat/whatsapp/client.rb
128
132
  - lib/flow_chat/whatsapp/configuration.rb
129
133
  - lib/flow_chat/whatsapp/gateway/cloud_api.rb
130
134
  - lib/flow_chat/whatsapp/middleware/executor.rb
131
135
  - lib/flow_chat/whatsapp/processor.rb
132
136
  - lib/flow_chat/whatsapp/prompt.rb
137
+ - lib/flow_chat/whatsapp/send_job_support.rb
133
138
  - lib/flow_chat/whatsapp/template_manager.rb
134
139
  homepage: https://github.com/radioactive-labs/flow_chat
135
140
  licenses:
@@ -1,51 +0,0 @@
1
- module FlowChat
2
- module Ussd
3
- module Simulator
4
- module Controller
5
- def ussd_simulator
6
- respond_to do |format|
7
- format.html do
8
- render inline: simulator_view_template, layout: false, locals: simulator_locals
9
- end
10
- end
11
- end
12
-
13
- protected
14
-
15
- def show_options
16
- true
17
- end
18
-
19
- def default_msisdn
20
- "233200123456"
21
- end
22
-
23
- def default_endpoint
24
- "/ussd"
25
- end
26
-
27
- def default_provider
28
- :nalo
29
- end
30
-
31
- def simulator_view_template
32
- File.read simulator_view_path
33
- end
34
-
35
- def simulator_view_path
36
- File.join FlowChat.root.join("flow_chat", "ussd", "simulator", "views", "simulator.html.erb")
37
- end
38
-
39
- def simulator_locals
40
- {
41
- pagesize: FlowChat::Config.ussd.pagination_page_size,
42
- show_options: show_options,
43
- default_msisdn: default_msisdn,
44
- default_endpoint: default_endpoint,
45
- default_provider: default_provider
46
- }
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,239 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>FlowChat Ussd Simulator</title>
5
- <style>
6
- .content {
7
- width: 320px;
8
- margin: 100px auto;
9
- }
10
- .label {
11
- display: inline-block;
12
- width: 80px;
13
- font-weight: bold;
14
- }
15
- .value {
16
- display: inline;
17
- }
18
- .value select, input {
19
- width: 200px;
20
- }
21
- .field {
22
- margin: 5px;
23
- }
24
- #screen {
25
- border: 1px black solid;
26
- height:400px;
27
- width:300px;
28
- margin-top: 10px;
29
- margin-bottom: 10px;
30
- padding: 10px 5px;
31
- }
32
- #char-count {
33
- text-align: center;
34
- font-size: 10px;
35
- }
36
- .hidden {
37
- display: none;
38
- }
39
- </style>
40
- </head>
41
- <body>
42
- <div class="content">
43
- <div class="field <%= show_options ? '' : 'hidden' %>">
44
- <div class="label">Provider </div>
45
- <div class="value">
46
- <select id="provider">
47
- <option <%= default_provider == :nalo ? 'selected' : '' %> value="nalo">Nalo</option>
48
- <option <%= default_provider == :nsano ? 'selected' : '' %> value="nsano">Nsano</option>
49
- </select>
50
- </div>
51
- </div>
52
- <div class="field <%= show_options ? '' : 'hidden' %>">
53
- <div class="label">Endpoint </div>
54
- <div class="value">
55
- <input id="endpoint" value="<%= default_endpoint %>" />
56
- </div>
57
- </div>
58
- <div class="field <%= show_options ? '' : 'hidden' %>">
59
- <div class="label">MSISDN </div>
60
- <div class="value">
61
- <input id="msisdn" value="<%= default_msisdn %>" />
62
- </div>
63
- </div>
64
- <div id="screen"></div>
65
- <div id="char-count"></div>
66
- <div class="field">
67
- <input id="data" disabled> <button id="respond" disabled>Respond</button>
68
- </div>
69
- <div class="field">
70
- <button id="initiate" disabled>Initiate</button>
71
- <button id="reset" disabled>Reset</button>
72
- </div>
73
- </div>
74
- <script>
75
- // Config
76
- const pagesize = <%= pagesize %>
77
-
78
- // View
79
- const $screen = document.getElementById('screen')
80
- const $charCount = document.getElementById('char-count')
81
-
82
- const $provider = document.getElementById('provider')
83
- const $endpoint = document.getElementById('endpoint')
84
- const $msisdn = document.getElementById('msisdn')
85
-
86
- const $data = document.getElementById('data')
87
- const $respondBtn = document.getElementById('respond')
88
- const $initiateBtn = document.getElementById('initiate')
89
- const $resetBtn = document.getElementById('reset')
90
-
91
- $provider.addEventListener('change', function (e) {
92
- state.provider = $provider.value
93
- render()
94
- }, false)
95
-
96
- $endpoint.addEventListener('keyup', function (e) {
97
- state.endpoint = $endpoint.value
98
- render()
99
- }, false)
100
-
101
- $msisdn.addEventListener('keyup', function (e) {
102
- state.msisdn = $msisdn.value
103
- render()
104
- }, false)
105
-
106
- $initiateBtn.addEventListener('click', function (e) {
107
- makeRequest()
108
- }, false)
109
-
110
- $resetBtn.addEventListener('click',function(e){
111
- reset()
112
- }, false)
113
-
114
- $respondBtn.addEventListener('click', function (e) {
115
- makeRequest()
116
- }, false)
117
-
118
- function disableInputs() {
119
- $data.disabled = 'disabled'
120
- $respondBtn.disabled = 'disabled'
121
- $initiateBtn.disabled = 'disabled'
122
- $resetBtn.disabled = 'disabled'
123
- $data.disabled = 'disabled'
124
- }
125
-
126
- function enableResponse() {
127
- $data.disabled = false
128
- $respondBtn.disabled = false
129
- $resetBtn.disabled = false
130
- }
131
-
132
- function display(text) {
133
- $screen.innerText = text.substr(0, pagesize)
134
- if(text.length > 0)
135
- $charCount.innerText = `${text.length} chars`
136
- else
137
- $charCount.innerText = ''
138
- }
139
-
140
- function render() {
141
- disableInputs()
142
-
143
- if(!state.isRunning){
144
- if(state.provider && state.endpoint && state.msisdn)
145
- $initiateBtn.disabled = false
146
- else
147
- $initiateBtn.disabled = 'disabled'
148
- }
149
- else {
150
- enableResponse()
151
- }
152
- }
153
-
154
- // State
155
- const state = {}
156
-
157
- function reset(shouldRender) {
158
- state.isRunning = false
159
- state.request_id = btoa(Math.random().toString()).substr(10, 10)
160
- state.provider = $provider.value
161
- state.endpoint = $endpoint.value
162
- state.msisdn = $msisdn.value
163
-
164
- $data.value = null
165
-
166
- display("")
167
- if(shouldRender !== false) render()
168
- }
169
-
170
-
171
- // API
172
-
173
- function makeRequest() {
174
- var data = {}
175
-
176
- switch (state.provider) {
177
- case "nalo":
178
- data = {
179
- USERID: state.request_id,
180
- MSISDN: state.msisdn,
181
- USERDATA: $data.value,
182
- MSGTYPE: !state.isRunning,
183
- }
184
- break;
185
- case "nsano":
186
- data = {
187
- network: 'MTN',
188
- msisdn: state.msisdn,
189
- msg: $data.value,
190
- UserSessionID: state.request_id,
191
- }
192
- break;
193
-
194
- default:
195
- alert(`Unhandled provider request: ${state.provider}`)
196
- return
197
- }
198
-
199
- disableInputs()
200
- fetch(state.endpoint, {
201
- method: 'POST',
202
- headers: {
203
- 'Content-Type': 'application/json'
204
- },
205
- redirect: 'error',
206
- body: JSON.stringify(data)
207
- })
208
- .then(response => {
209
- if (!response.ok) {
210
- throw Error(`${response.status}: ${response.statusText}`);
211
- }
212
- return response.json()
213
- })
214
- .then(data => {
215
- switch (state.provider) {
216
- case "nalo":
217
- display(data.MSG)
218
- state.isRunning = data.MSGTYPE
219
- break;
220
- case "nsano":
221
- display(data.USSDResp.title)
222
- state.isRunning = data.USSDResp.action == "input"
223
- break;
224
-
225
- default:
226
- alert(`Unhandled provider response: ${state.provider}`)
227
- return
228
- }
229
- $data.value = null
230
- })
231
- .catch(error => alert(error.message))
232
- .finally(render);
233
- }
234
-
235
- // run the app
236
- reset()
237
- </script>
238
- </body>
239
- </html>