qismo 0.12.1 → 0.14.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.
data/lib/qismo/api.rb CHANGED
@@ -8,20 +8,40 @@ module Qismo
8
8
  #
9
9
  # @see https://s.id/list-customer-rooms
10
10
  # @param options [Hash]
11
- # @return [Qismo::CollectionObject]
11
+ # List room optional filters
12
+ # @option options [String] :status
13
+ # Filter by room status. Valid values are "resolved", "unresolved", "expired", or "almost_expired"
14
+ # @option options [String] :serve_status
15
+ # Filter by room serve status. Valid values are "served" or "unserved"
16
+ # @option options [Array<Hash>] :channels
17
+ # Filter by channels. Example: [{ source: "wa", channel_id: 716171 }]
18
+ # @option options [TrueClass,FalseClass] :is_handled_by_bot
19
+ # Filter by bot handling status
20
+ # @option options [String] :name
21
+ # Filter by customer name
22
+ # @option options [Integer] :limit
23
+ # Number of data returned in one page. Default is 50
24
+ # @option options [String] :order
25
+ # Order data by timestamp. Can be ordered "asc" or "desc". Default is "desc"
26
+ # @option options [String] :cursor_after
27
+ # Next page cursor. If you are on last page, the cursor returned will be nil
28
+ # @option options [String] :cursor_before
29
+ # Previous page cursor. If you are on first page, the cursor returned will be nil
30
+ # @option options [Array<Integer>] :tag_ids
31
+ # Filter by tags
32
+ # @option options [Array<Integer>] :user_ids
33
+ # Filter by agent who handled or assigned to the room
34
+ # @return [Qismo::Collection<Qismo::CustomerRoom>]
12
35
  def rooms(options = {})
13
36
  body = post("/api/v2/customer_rooms", options)
14
- CollectionObject.new(
15
- body.data.customer_rooms,
16
- prev_page: body.meta&.cursor_before,
17
- next_page: body.meta&.cursor_after,
18
- prev_func: -> { rooms(options.merge(cursor_before: body.meta&.cursor_before)) },
19
- next_func: -> { rooms(options.merge(cursor_after: body.meta&.cursor_after)) }
37
+ Collection.new(
38
+ Qismo::Objects::CustomerRoom.from_array(body.data.customer_rooms),
39
+ next_page: body.meta.cursor_after,
40
+ prev_page: body.meta.cursor_before
20
41
  )
21
42
  end
22
43
 
23
44
  # Get room by id
24
- #
25
45
  # @see https://s.id/get-room-by-room-id
26
46
  # @param room_id [Integer]
27
47
  # @return [Qismo::SingleObject]
@@ -31,16 +51,20 @@ module Qismo
31
51
  raise Qismo::NotFoundError.new("Room not found", status_code: 404, response_body: body.to_json)
32
52
  end
33
53
 
34
- body.data.customer_room
54
+ Qismo::Objects::CustomerRoom.new(body.data.customer_room)
35
55
  end
36
56
 
37
57
  # List tags inside room
38
58
  #
39
59
  # @see https://s.id/list-room-tags
40
60
  # @param room_id [Integer]
41
- # @return [Qismo::CollectionObject]
61
+ # @return [Qismo::Collection<Qismo::Objects::Tag>]
42
62
  def room_tags(room_id)
43
- CollectionObject.new(get("/api/v2/room_tags/#{room_id}").data)
63
+ Qismo::Collection.new(
64
+ Qismo::Objects::Tag.from_array(
65
+ get("/api/v2/room_tags/#{room_id}").data
66
+ )
67
+ )
44
68
  end
45
69
 
46
70
  # Add room tag
@@ -48,9 +72,11 @@ module Qismo
48
72
  # @see https://s.id/add-room-tag
49
73
  # @param room_id [Integer]
50
74
  # @param tag_name [String]
51
- # @return [Qismo::SingleObject]
75
+ # @return [Qismo::Objects::Tag]
52
76
  def add_room_tag(room_id, tag_name)
53
- post("/api/v2/room_tags/#{room_id}", tag: tag_name).data
77
+ Qismo::Objects::Tag.new(
78
+ post("/api/v2/room_tags/#{room_id}", tag: tag_name).data
79
+ )
54
80
  end
55
81
 
56
82
  # Delete room tag
@@ -68,13 +94,13 @@ module Qismo
68
94
  #
69
95
  # @see https://s.id/list-room-info
70
96
  # @param room_id [Integer]
71
- # @return [Qismo::CollectionObject]
97
+ # @return [Array<Qismo::Objects::RoomAdditionalInfo>]
72
98
  def room_additional_info(room_id)
73
- CollectionObject.new(
74
- get(
75
- "/api/v1/qiscus/room/#{room_id}/user_info"
76
- ).data&.extras&.user_properties
77
- ) || CollectionObject.new
99
+ Qismo::Objects::RoomAdditionalInfo.from_array(
100
+ get("/api/v1/qiscus/room/#{room_id}/user_info").data.extras.user_properties
101
+ )
102
+ rescue NoMethodError
103
+ Qismo::Objects::RoomAdditionalInfo.from_array([])
78
104
  end
79
105
 
80
106
  alias_method :room_info, :room_additional_info
@@ -85,14 +111,15 @@ module Qismo
85
111
  # @note This will replace your current room additional info
86
112
  # @param room_id [Integer]
87
113
  # @param additional_info [Array<Hash>]
88
- # @return [Qismo::CollectionObject]
114
+ # Key value pair of additional info. Ex: [{ key: "Ticket Link", value: "https://ticket.com" }]
115
+ # @return [Array<Qismo::Objects::RoomAdditionalInfo>]
89
116
  def set_room_additional_info(room_id, additional_info)
90
- CollectionObject.new(
117
+ Qismo::Objects::RoomAdditionalInfo.from_array(
91
118
  post(
92
119
  "/api/v1/qiscus/room/#{room_id}/user_info",
93
120
  user_properties: additional_info
94
- ).data&.extras&.user_properties
95
- ) || CollectionObject.new
121
+ ).data.extras.user_properties
122
+ )
96
123
  end
97
124
 
98
125
  alias_method :set_room_info, :set_room_additional_info
@@ -102,11 +129,12 @@ module Qismo
102
129
  # Update room additional info
103
130
  #
104
131
  # @param room_id [Integer]
105
- # @param additional_info [Array]
106
- # @return [Qismo::CollectionObject]
132
+ # @param additional_info [Array<Hash>]
133
+ # Key value pair of additional info. Ex: [{ key: "Ticket Link", value: "https://ticket.com" }]
134
+ # @return [Array<Qismo::Objects::RoomAdditionalInfo>]
107
135
  def update_room_additional_info(room_id, additional_info)
108
- old_additional_info = room_additional_info(room_id)
109
- new_additional_info = (additional_info + old_additional_info).uniq { |h| h.values_at("key") }
136
+ old_additional_info = room_additional_info(room_id).as_json
137
+ new_additional_info = (additional_info.as_json + old_additional_info).uniq { |h| h.values_at("key") }
110
138
  set_room_additional_info(room_id, new_additional_info)
111
139
  end
112
140
 
@@ -118,31 +146,49 @@ module Qismo
118
146
  # @param room_id [Integer]
119
147
  # @param options [Hash]
120
148
  # @return [Qismo::CollectionObject]
121
- def room_broadcast_history(room_id, options = {})
122
- body = get("/api/v2/customer_rooms/#{room_id}/broadcast_history", options)
123
-
124
- next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
125
- prev_page = (body.meta.page > 1) ? (body.meta.page - 1) : nil
126
149
 
127
- CollectionObject.new(
128
- body.data.broadcast_logs,
129
- next_page: next_page,
130
- prev_page: prev_page,
131
- next_func: -> { room_broadcast_history(options.merge(page: next_page)) },
132
- prev_func: -> { room_broadcast_history(options.merge(page: prev_page)) }
150
+ # List broadcast history inside room
151
+ #
152
+ # @param room_id [Integer]
153
+ # @param page [Integer]
154
+ # @param limit [Integer]
155
+ # @return [Qismo::Collection<Qismo::Objects::BroadcastLog>]
156
+ def room_broadcast_history(room_id, page: 1, limit: 25)
157
+ body = get("/api/v2/customer_rooms/#{room_id}/broadcast_history", {
158
+ page: page,
159
+ limit: limit
160
+ })
161
+
162
+ Qismo::Collection.new(
163
+ Qismo::Objects::BroadcastLog.from_array(body.data.broadcast_logs),
164
+ next_page: ((body.meta.page < body.dig("meta", "total_page")) ? (body.meta.page + 1) : nil),
165
+ prev_page: ((body.meta.page > 1) ? (body.meta.page - 1) : nil)
133
166
  )
134
167
  end
135
168
 
136
- # Assign agent to room
169
+ # Assign an agent to a room
137
170
  #
138
- # @see https://s.id/assign-agent
139
171
  # @param room_id [Integer]
140
172
  # @param agent_id [Integer]
141
- # @param options [Hash]
142
- # @return [Qismo::SingleObject]
143
- def assign_agent(room_id, agent_id, options = {})
144
- body = post("/api/v1/admin/service/assign_agent", options.merge(room_id: room_id.to_s, agent_id: agent_id))
145
- body.data.added_agent
173
+ # @param replace_agents [TrueClass,FalseClass]
174
+ # Replace agents in room or not. Don't combine this param
175
+ # with :max_agent param
176
+ # @param max_agent [Integer]
177
+ # Specify max agent that can be assigned to a room. For
178
+ # example, if there are 1 agent in a room and you specific
179
+ # max_agent to 1, you will get bad request error. If you set
180
+ # param :relpace_agents to true, this param will be forced
181
+ # to nil, which no be sent on http request
182
+ # @return [Qismo::Objects::User]
183
+ def assign_agent(room_id, agent_id, replace_agents: false, max_agent: nil)
184
+ Qismo::Objects::User.new(
185
+ post("/api/v1/admin/service/assign_agent", {
186
+ room_id: room_id.to_s,
187
+ agent_id: agent_id,
188
+ replace_latest_agent: replace_agents,
189
+ max_agent: (replace_agents == true) ? nil : max_agent
190
+ }).data.assign_agent
191
+ )
146
192
  end
147
193
 
148
194
  # Remove agent from room
@@ -152,7 +198,13 @@ module Qismo
152
198
  # @param agent_id [Integer]
153
199
  # @return [TrueClass]
154
200
  def remove_agent(room_id, agent_id)
155
- post("/api/v1/admin/service/remove_agent", room_id: room_id.to_s, agent_id: agent_id)
201
+ post(
202
+ "/api/v1/admin/service/remove_agent", {
203
+ room_id: room_id.to_s,
204
+ agent_id: agent_id
205
+ }
206
+ )
207
+
156
208
  true
157
209
  end
158
210
 
@@ -161,12 +213,27 @@ module Qismo
161
213
  # @see https://s.id/resolve-room
162
214
  # @param room_id [Integer]
163
215
  # @param last_comment_id [Integer]
164
- # @param options [Hash]
216
+ # Id of last message in the room. If you dont specify this param,
217
+ # we will use current epoc timestamp
218
+ # @param notes [String]
219
+ # Specify room notes. You can also use simple markdown markup
220
+ # for this param
221
+ # @param send_email [TrueClass,FalseClass]
222
+ # Send email to customer or no. This param will only worked if
223
+ # you are using valid email as customer identifier
224
+ # @param extras [Hash]
225
+ # Room extras in valid hash
165
226
  # @return [Qismo::SingleObject]
166
- def resolve_room(room_id, last_comment_id, options = {})
167
- body = post("/api/v1/admin/service/mark_as_resolved",
168
- options.merge(room_id: room_id.to_s, last_comment_id: last_comment_id))
169
- body.data.service
227
+ def resolve_room(room_id, last_comment_id: Time.now.to_i, notes: nil, send_email: false, extras: nil)
228
+ Qismo::Objects::AgentService.new(
229
+ post("/api/v1/admin/service/mark_as_resolved", {
230
+ room_id: room_id.to_s,
231
+ last_comment_id: last_comment_id,
232
+ notes: notes,
233
+ is_send_email: send_email,
234
+ extras: extras
235
+ }).data.service
236
+ )
170
237
  end
171
238
 
172
239
  alias_method :resolve, :resolve_room
@@ -175,38 +242,64 @@ module Qismo
175
242
  #
176
243
  # @see https://s.id/allocate-agent
177
244
  # @param source [String]
178
- # @param options [Hash]
179
- # @return [Qismo::SingleObject]
180
- def allocate_agent(source, options = {})
181
- body = post("/api/v1/admin/service/allocate_agent", options.merge(source: source))
182
- body.data.agent
245
+ # Channel source. Available sources are `wa`, `line`, `telegram`,
246
+ # `qiscus`, `ig`, or `fb`. For custom channel, use that channel's
247
+ # identifier_key as source
248
+ # @param channel_id [Integer]
249
+ # The channel id you want to allocate
250
+ # @param ignore_availability [TrueClass,FalseClass]
251
+ # Ignore agent availability. If you set this param to true, agent
252
+ # that are unavailable will be considered as allocatable too
253
+ # @return [Qismo::Objects::User]
254
+ def allocate_agent(source, channel_id, ignore_availability: false)
255
+ Qismo::Objects::User.new(
256
+ post("/api/v1/admin/service/allocate_agent", {
257
+ source: source,
258
+ channel_id: channel_id,
259
+ ignore_availability: ignore_availability
260
+ }).data.agent
261
+ )
183
262
  end
184
263
 
185
264
  # Get agent that can be allocated to room and automatically assign them
186
265
  #
187
266
  # @see https://s.id/allocate-and-assign-agent
188
267
  # @param room_id [Integer]
189
- # @param options [Hash]
268
+ # @param ignore_availability [TrueClass,FalseClass]
269
+ # Ignore agent availability. If you set this param to true, agent
270
+ # that are unavailable will be considered as allocatable too
190
271
  # @return [Qismo::SingleObject]
191
- def allocate_and_assign_agent(room_id, options = {})
192
- body = post("/api/v1/admin/service/allocate_assign_agent", options.merge(room_id: room_id))
193
- body.data.agent
272
+ def allocate_and_assign_agent(room_id, ignore_availability: false)
273
+ Qismo::Objects::User.new(
274
+ post("/api/v1/admin/service/allocate_assign_agent", {
275
+ room_id: room_id.to_s,
276
+ ignore_availability: ignore_availability
277
+ }).data.agent
278
+ )
194
279
  end
195
280
 
196
281
  # List agents that are not in room and can be assigned to room
197
282
  #
198
283
  # @see https://s.id/list-other-agents
199
284
  # @param room_id [Integer]
200
- # @param options [Hash]
201
- # @return [Qismo::CollectionObject]
202
- def other_agents(room_id, options = {})
203
- body = get("/api/v2/admin/service/other_agents", options.merge(room_id: room_id))
204
- CollectionObject.new(
205
- body.data.agents,
206
- prev_page: body.meta&.cursor_before,
207
- next_page: body.meta&.cursor_after,
208
- prev_func: -> { other_agents(options.merge(cursor_before: body.meta&.cursor_before)) },
209
- next_func: -> { other_agents(options.merge(cursor_after: body.meta&.cursor_after)) }
285
+ # @param search [String]
286
+ # @param limit [Integer]
287
+ # @param cursor_after [String]
288
+ # @param cursor_before [String]
289
+ # @return [Qismo::Collection<Qismo::Objects::User>]
290
+ def other_agents(room_id, search: nil, limit: 15, cursor_after: nil, cursor_before: nil)
291
+ body = get("/api/v2/admin/service/other_agents", {
292
+ room_id: room_id.to_s,
293
+ search: search,
294
+ limit: limit,
295
+ cursor_after: cursor_after,
296
+ cursor_before: cursor_before
297
+ })
298
+
299
+ Collection.new(
300
+ Qismo::Objects::User.from_array(body.data.agents),
301
+ next_page: body.meta.cursor_after,
302
+ prev_page: body.meta.cursor_before
210
303
  )
211
304
  end
212
305
 
@@ -214,100 +307,132 @@ module Qismo
214
307
  #
215
308
  # @see https://s.id/list-available-agents
216
309
  # @param room_id [Integer]
217
- # @param options [Hash]
218
- # @return [Qismo::CollectionObject]
219
- def available_agents(room_id, options = {})
220
- body = get("/api/v2/admin/service/available_agents", options.merge(room_id: room_id))
221
- CollectionObject.new(
222
- body.data.agents,
223
- prev_page: body.meta&.cursor_before,
224
- next_page: body.meta&.cursor_after,
225
- prev_func: -> { available_agents(options.merge(cursor_before: body.meta&.cursor_before)) },
226
- next_func: -> { available_agents(options.merge(cursor_after: body.meta&.cursor_after)) }
310
+ # @param available_in_room [TrueClass,FalseClass]
311
+ # @param search [String]
312
+ # @param limit [Integer]
313
+ # @param cursor_after [String]
314
+ # @param cursor_before [String]
315
+ # @return [Qismo::Collection<Qismo::Objects::User>]
316
+ def available_agents(room_id, available_in_room: true, search: nil, limit: 15, cursor_after: nil, cursor_before: nil)
317
+ body = get("/api/v2/admin/service/available_agents", {
318
+ room_id: room_id.to_s,
319
+ is_available_in_room: available_in_room,
320
+ search: search,
321
+ limit: limit,
322
+ cursor_after: cursor_after,
323
+ cursor_before: cursor_before
324
+ })
325
+
326
+ Collection.new(
327
+ Qismo::Objects::User.from_array(body.data.agents),
328
+ next_page: body.meta.cursor_after,
329
+ prev_page: body.meta.cursor_before
227
330
  )
228
331
  end
229
332
 
230
333
  # Get new session webhook config
231
334
  #
232
- # @return [Qismo::SingleObject]
335
+ # @return [Qismo::Objects::Webhook]
233
336
  def new_session_webhook
234
- get("/api/v2/app/config/new_session_webhook").data.configs
337
+ config = get("/api/v2/app/config/new_session_webhook").data.configs
338
+ Qismo::Objects::Webhook.new(
339
+ enabled: config.is_new_session_webhook_enabled,
340
+ url: config.new_session_webhook_url
341
+ )
235
342
  end
236
343
 
237
344
  # Set new session webhook
238
345
  #
239
346
  # @param url [String]
240
- # @param options [Hash]
241
- # @return [Qismo::SingleObject]
242
- def set_new_session_webhook(url, options = {})
243
- post("/api/v2/app/config/new_session_webhook", options.merge(url: url)).data.configs
347
+ # @param enabled [TrueClass,FalseClass]
348
+ # @return [Qismo::Objects::Webhook]
349
+ def set_new_session_webhook(url, enabled: true)
350
+ config = post("/api/v2/app/config/new_session_webhook", url: url, enabled: enabled).data.configs
351
+ Qismo::Objects::Webhook.new(
352
+ enabled: config.is_new_session_webhook_enabled,
353
+ url: config.new_session_webhook_url
354
+ )
244
355
  end
245
356
 
246
357
  # Get auth webhook config
247
358
  #
248
359
  # @return [Qismo::SingleObject]
249
360
  def auth_webhook
250
- get("/api/v2/app/config/auth_webhook").data.configs
361
+ config = get("/api/v2/app/config/auth_webhook").data.configs
362
+ Qismo::Objects::Webhook.new(
363
+ enabled: config.is_auth_webhook_enabled,
364
+ url: config.auth_webhook_url
365
+ )
251
366
  end
252
367
 
253
368
  # Set auth webhook
254
369
  #
255
370
  # @param url [String]
256
371
  # @param enabled [TrueClass, FalseClass]
257
- # @param options [Hash]
258
372
  # @return [Qismo::SingleObject]
259
- def set_auth_webhook(url, enabled = true, options = {})
260
- post("/api/v2/app/config/auth_webhook", options.merge(url: url, enabled: enabled)).data.configs
373
+ def set_auth_webhook(url, enabled: true)
374
+ config = post("/api/v2/app/config/auth_webhook", url: url, enabled: enabled).data.configs
375
+ Qismo::Objects::Webhook.new(
376
+ enabled: config.is_auth_webhook_enabled,
377
+ url: config.auth_webhook_url
378
+ )
261
379
  end
262
380
 
263
381
  # Get resolve webhook config
264
382
  #
265
- # @return [Qismo::SingleObject]
383
+ # @return [Qismo::Objects::Webhook]
266
384
  def resolve_webhook
267
- get("/api/v1/app/webhook/mark_as_resolved").data
385
+ config = get("/api/v1/app/webhook/mark_as_resolved").data
386
+ Qismo::Objects::Webhook.new(
387
+ enabled: config.is_mark_as_resolved_webhook_enabled,
388
+ url: config.mark_as_resolved_webhook_url
389
+ )
268
390
  end
269
391
 
270
392
  # Set resolve webhook
271
393
  #
272
394
  # @param url [String]
273
395
  # @param options [Hash]
274
- # @return [Qismo::SingleObject]
275
- def set_resolve_webhook(url, options = {})
276
- post("/api/v1/app/webhook/mark_as_resolved", options.merge(url: url)).data
396
+ # @return [Qismo::Objects::Webhook]
397
+ def set_resolve_webhook(url, enabled: true)
398
+ config = post("/api/v1/app/webhook/mark_as_resolved", webhook_url: url, is_webhook_enabled: enabled).data
399
+ Qismo::Objects::Webhook.new(
400
+ enabled: config.is_mark_as_resolved_webhook_enabled,
401
+ url: config.mark_as_resolved_webhook_url
402
+ )
277
403
  end
278
404
 
279
405
  # List agents
280
406
  #
281
407
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#849205ca-00d9-4356-9fdd-f05bff777b4e
282
408
  # @param options [Hash]
283
- # @return [Qismo::CollectionObject]
284
- def agents(options = {})
285
- if options[:page].nil? || options[:page].empty?
286
- options[:page] = 1
287
- end
288
-
289
- body = get("/api/v2/admin/agents", options)
409
+ # @return [Qismo::Collection<Qismo::Objects::User>]
410
+ def agents(page: 1, limit: 10, search: nil, scope: nil)
411
+ body = get("/api/v2/admin/agents", {
412
+ page: page,
413
+ limit: limit,
414
+ search: search,
415
+ scope: scope
416
+ })
290
417
 
291
418
  total_page = (body.meta.total_count.to_f / body.meta.per_page.to_f).ceil
292
- next_page = (options[:page] < total_page) ? (options[:page] + 1) : nil
293
- prev_page = (options[:page] > 1) ? (options[:page] - 1) : nil
294
419
 
295
- CollectionObject.new(
296
- body.data.agents,
297
- next_page: next_page,
298
- prev_page: prev_page,
299
- next_func: -> { agents(options.merge(page: next_page)) },
300
- prev_func: -> { agents(options.merge(page: prev_page)) }
420
+ Qismo::Collection.new(
421
+ Qismo::Objects::User.from_array(body.data.agents),
422
+ next_page: ((page < total_page) ? (page + 1) : nil),
423
+ prev_page: ((page > 1) ? (page - 1) : nil)
301
424
  )
302
425
  end
303
426
 
304
- # List agents by id
427
+ # List agents by ids
305
428
  #
306
429
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#3db6c8c8-8ffe-4a88-b630-41f9d5b62298
307
430
  # @param ids [Array<Integer>]
308
- # @return [Qismo::CollectionObject]
431
+ # @return [Qismo::Collection<Qismo::Objects::User>]
309
432
  def agents_by_ids(ids)
310
- CollectionObject.new(get("/api/v1/admin/agents/get_by_ids", {"ids[]": ids}).data) || CollectionObject.new
433
+ Qismo::Collection.new(
434
+ Qismo::Objects::User.from_array(get("/api/v1/admin/agents/get_by_ids", {"ids[]": ids}).data)
435
+ )
311
436
  end
312
437
 
313
438
  # List agents by divisions
@@ -315,19 +440,20 @@ module Qismo
315
440
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#94eeb9cb-dd70-4baf-9f63-361e7922299a
316
441
  # @param division_ids [Array<Integer>]
317
442
  # @param options [Hash]
318
- # @return [Qismo::CollectionObject]
319
- def agents_by_divisions(division_ids, options = {})
320
- body = get("/api/v2/admin/agents/by_division", options.merge({"division_ids[]": division_ids}))
321
-
322
- next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
323
- prev_page = (body.meta.page > 1) ? (body.meta.page - 1) : nil
324
-
325
- CollectionObject.new(
326
- body.data,
327
- next_page: next_page,
328
- prev_page: prev_page,
329
- next_func: -> { agents_by_divisions(options.merge(page: next_page)) },
330
- prev_func: -> { agents_by_divisions(options.merge(page: prev_page)) }
443
+ # @return [Qismo::Collection<Qismo::Objects::User>]
444
+ def agents_by_divisions(division_ids, page: 1, limit: 10, available: nil, sort: "asc")
445
+ body = get("/api/v2/admin/agents/by_division", {
446
+ "division_ids[]": division_ids,
447
+ page: page,
448
+ limit: limit,
449
+ is_available: available,
450
+ sort: sort
451
+ })
452
+
453
+ Qismo::Collection.new(
454
+ Qismo::Objects::User.from_array(body.data),
455
+ next_page: ((body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil),
456
+ prev_page: ((body.meta.page > 1) ? (body.meta.page - 1) : nil)
331
457
  )
332
458
  end
333
459
 
@@ -335,21 +461,19 @@ module Qismo
335
461
  #
336
462
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#c6184a6b-ba4d-4f3e-a4da-c6d0fa4597af
337
463
  # @param agent_id [Integer]
338
- # @return [Qismo::SingleObject]
464
+ # @return [Qismo::Objects::User]
339
465
  def agent(agent_id)
340
- get("/api/v2/admin/agent/#{agent_id}").data.agent
466
+ Qismo::Objects::User.new(get("/api/v2/admin/agent/#{agent_id}").data.agent)
341
467
  end
342
468
 
343
469
  # Get office hour config
344
470
  #
345
471
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#6f3f0cb0-a391-4945-b01a-95ce81138913
346
- # @return [Qismo::SingleObject]
472
+ # @return [Qismo::Objects::OfficeHour]
347
473
  def office_hours
348
- data = get("/api/v1/admin/office_hours").data
349
- data_hash = data.as_json
350
- data_hash["is_in_office_hour"] = Util.in_office_hour?(data)
351
-
352
- SingleObject.new(data_hash)
474
+ Qismo::Objects::OfficeHour.new(
475
+ get("/api/v1/admin/office_hours").data
476
+ )
353
477
  end
354
478
 
355
479
  # List WA broadcast templates
@@ -357,32 +481,76 @@ module Qismo
357
481
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#e38d2244-9559-4015-99d5-8c707f6c01bd
358
482
  # @param options [Hash]
359
483
  # @return [Qismo::CollectionObject]
360
- def wa_broadcast_templates(options = {})
361
- body = get("/api/v3/admin/hsm", options)
362
-
363
- meta = body.meta
364
- next_page = (meta.page < meta.total_page) ? (meta.page + 1) : nil
365
- prev_page = (meta.page > 1) ? (meta.page - 1) : nil
366
-
367
- CollectionObject.new(
368
- body.data.hsm_templates,
369
- next_page: next_page,
370
- prev_page: prev_page,
371
- next_func: -> { wa_broadcast_templates(options.merge(page: next_page)) },
372
- prev_func: -> { wa_broadcast_templates(options.merge(page: prev_page)) }
484
+ def wa_broadcast_templates(page: 1, limit: 10, approved: nil)
485
+ body = get("/api/v3/admin/hsm", {
486
+ page: page,
487
+ limit: limit,
488
+ approved: approved
489
+ })
490
+
491
+ Qismo::Collection.new(
492
+ Qismo::Objects::HsmTemplate.from_array(body.data.hsm_templates),
493
+ next_page: ((body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil),
494
+ prev_page: ((body.meta.page > 1) ? (body.meta.page - 1) : nil)
373
495
  )
374
496
  end
375
497
 
376
498
  alias_method :wa_message_templates, :wa_broadcast_templates
377
499
  alias_method :wa_outbound_templates, :wa_broadcast_templates
378
500
 
501
+ # Get Whatsapp channel credit info
502
+ #
503
+ # @return [Qismo::Objects::WaCreditInfo]
504
+ def wa_credit
505
+ Qismo::Objects::WaCreditInfo.new(
506
+ get("/api/v2/admin/wa_pricing/balance").data
507
+ )
508
+ end
509
+
379
510
  # Send WA outbound message
380
511
  #
381
512
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#d0183cf6-deca-439b-aff3-2e2f007c15a9
382
- # @param options [Hash]
383
- # @return [Qismo::SingleObject]
384
- def send_wa_outbound(options = {})
385
- post("/api/v3/admin/broadcast/client", options).data
513
+ # @param phone_number [String]
514
+ # @param channel_id [Integer]
515
+ # @param template_name [String]
516
+ # @param namespace [String]
517
+ # @param language [String]
518
+ # @param template_detail_id [Integer]
519
+ # @param variables [Array<String>]
520
+ # @param button_params [Array<Hash>]
521
+ # @param header_value [Hash]
522
+ # @return [Qismo::Objects::BroadcastJob]
523
+ def send_wa_outbound(
524
+ phone_number:,
525
+ template_detail_id: nil,
526
+ channel_id: nil,
527
+ template_name: nil,
528
+ namespace: nil,
529
+ language: nil,
530
+ variables: [],
531
+ button_params: nil,
532
+ header_value: nil
533
+ )
534
+ if template_detail_id.nil?
535
+ raise ArgumentError, ":channel_id is required if you dont use :template_detail_id" if channel_id.nil?
536
+ raise ArgumentError, ":template_name is required if you dont use :template_detail_id" if template_name.nil?
537
+ raise ArgumentError, ":namespace is required if you dont use :template_detail_id" if namespace.nil?
538
+ raise ArgumentError, ":language is required if you dont use :template_detail_id" if language.nil?
539
+ end
540
+
541
+ body = post("/api/v3/admin/broadcast/client", {
542
+ phone_number: phone_number,
543
+ template_detail_id: template_detail_id,
544
+ channel_id: channel_id,
545
+ template_name: template_name,
546
+ namespace: namespace,
547
+ language: language,
548
+ variables: variables,
549
+ button_params: button_params,
550
+ header_value: header_value
551
+ })
552
+
553
+ Qismo::Objects::BroadcastJob.new(body.data)
386
554
  end
387
555
 
388
556
  # Upload wa broadcast file that want to be sent in broadcast
@@ -390,20 +558,58 @@ module Qismo
390
558
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#030acde2-21cf-4373-8d11-075206053c1d
391
559
  # @param file [HTTP::FormData]
392
560
  # @param template_detail_id [Integer]
393
- # @return [Qismo::SingleObject]
394
- def upload_wa_broadcast_csv(file, template_detail_id)
561
+ # @return [Integer]
562
+ def upload_wa_broadcast_csv(file, template_detail_id, separator: ",")
395
563
  raise ArgumentError, "Invalid file" unless file.is_a?(HTTP::FormData::File)
396
564
 
397
- post_upload("/api/v3/admin/broadcast/upload_csv", file: file, template_detail_id: template_detail_id)
565
+ body = post_upload("/api/v3/admin/broadcast/upload_csv", {
566
+ file: file,
567
+ template_detail_id: template_detail_id,
568
+ separator: separator
569
+ })
570
+
571
+ body.broadcast_file_id
398
572
  end
399
573
 
400
- # Send wa broadcast
574
+ # Send WA broadcast
401
575
  #
402
576
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#717c1a12-facb-4945-aed5-04557696b873
403
- # @param options [Hash]
404
- # @return [Qismo::SingleObject]
405
- def send_wa_broadcast(options = {})
406
- post("/api/v3/admin/broadcast/send_broadcast", options).data.broadcast_job
577
+ # @param file [HTTP::FormData::File,Integer]
578
+ # @param template_detail_id [Integer]
579
+ # @param name [String]
580
+ # @param separator [String]
581
+ # @param started_at [Time]
582
+ # @return [Qismo::Objects::BroadcastJob]
583
+ def send_wa_broadcast(file, template_detail_id, name: nil, separator: ",", started_at: nil)
584
+ if name.blank?
585
+ name = default_broadcast_name
586
+ end
587
+
588
+ if started_at.present? && !started_at.is_a?(Time)
589
+ unless started_at.is_a?(Time)
590
+ raise ArgumentError, "You must past :Time class for this parameter"
591
+ end
592
+
593
+ unless started_at.utc_offset == 0
594
+ raise ArgumentError, "You must set your timezone to UTC"
595
+ end
596
+ end
597
+
598
+ file_id = if file.is_a?(HTTP::FormData::File)
599
+ upload_wa_broadcast_csv(file, template_detail_id, separator: separator)
600
+ else
601
+ file.to_i
602
+ end
603
+
604
+ Qismo::Objects::BroadcastJob.new(
605
+ post("/api/v3/admin/broadcast/send_broadcast", {
606
+ broadcast_file_id: file_id,
607
+ name: name,
608
+ separator: separator,
609
+ started_at: started_at,
610
+ template_detail_id: template_detail_id
611
+ }).data.broadcast_job
612
+ )
407
613
  end
408
614
 
409
615
  alias_method :create_wa_broadcast, :send_wa_broadcast
@@ -413,18 +619,27 @@ module Qismo
413
619
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#3a4caa8b-eef4-427f-adcb-d065989899c9
414
620
  # @param options [Hash]
415
621
  # @return [Qismo::CollectionObject]
416
- def wa_broadcast_jobs(options = {})
417
- body = get("/api/v2/admin/broadcast_jobs", options)
418
-
419
- prev_page = (body.meta.page > 1) ? (body.meta.meta - 1) : nil
420
- next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
421
622
 
422
- CollectionObject.new(
423
- body.data.broadcast_jobs,
424
- next_page: next_page,
425
- prev_page: prev_page,
426
- next_func: -> { wa_broadcast_jobs(options.merge(page: next_page)) },
427
- prev_func: -> { wa_broadcast_jobs(options.merge(page: prev_page)) }
623
+ # List WA broadcast jobs
624
+ #
625
+ # @param page [Integer]
626
+ # @param limit [Integer]
627
+ # @param cursor_after [Integer]
628
+ # @param cursor_before [Integer]
629
+ # @param name [String]
630
+ # @return [Qismo::Collection<Qismo::Objects::BroadcastJob>]
631
+ def wa_broadcast_jobs(limit: 10, cursor_after: nil, cursor_before: nil, name: nil)
632
+ body = get("/api/v2/admin/broadcast_jobs", {
633
+ limit: limit,
634
+ cursor_after: cursor_after,
635
+ cursor_before: cursor_before,
636
+ name: name
637
+ })
638
+
639
+ Qismo::Collection.new(
640
+ Qismo::Objects::BroadcastJob.from_array(body.data.broadcast_jobs),
641
+ next_page: body.meta.cursor_after,
642
+ prev_page: body.meta.cursor_before
428
643
  )
429
644
  end
430
645
 
@@ -432,9 +647,11 @@ module Qismo
432
647
  #
433
648
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#ed0806c8-2e4a-4ea4-8acb-45c84c63c2da
434
649
  # @param broadcast_job_id [Integer]
435
- # @return [Qismo::SingleObject]
650
+ # @return [Qismo::Objects::BroadcastJob]
436
651
  def wa_broadcast_job(broadcast_job_id)
437
- get("/api/v2/admin/broadcast_jobs/#{broadcast_job_id}").data.broadcast_job
652
+ Qismo::Objects::BroadcastJob.new(
653
+ get("/api/v2/admin/broadcast_jobs/#{broadcast_job_id}").data.broadcast_job
654
+ )
438
655
  end
439
656
 
440
657
  # List wa broadcast logs
@@ -443,28 +660,45 @@ module Qismo
443
660
  # @param broadcast_job_id [Integer]
444
661
  # @param options [Hash]
445
662
  # @return [Qismo::CollectionObject]
446
- def wa_broadcast_logs(broadcast_job_id, options = {})
447
- body = get("/api/v2/admin/broadcast_logs/#{broadcast_job_id}", options)
663
+ def wa_broadcast_logs(broadcast_job_id, page: 1, limit: 10)
664
+ body = get("/api/v2/admin/broadcast_logs/#{broadcast_job_id}", {
665
+ page: page,
666
+ limit: limit
667
+ })
448
668
 
449
669
  prev_page = (body.meta.page > 1) ? (body.meta.meta - 1) : nil
450
670
  next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
451
671
 
452
- CollectionObject.new(
453
- body.data.broadcast_logs,
672
+ Qismo::Collection.new(
673
+ Qismo::Objects::BroadcastLog.from_array(body.data.broadcast_logs),
454
674
  next_page: next_page,
455
- prev_page: prev_page,
456
- next_func: -> { wa_broadcast_logs(options.merge(page: next_page)) },
457
- prev_func: -> { wa_broadcast_jobs(options.merge(page: prev_page)) }
675
+ prev_page: prev_page
458
676
  )
459
677
  end
460
678
 
461
679
  # Send message as bot
462
680
  #
463
681
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#bb77c653-5daa-4e1c-a866-43bca7c494fc
464
- # @param options [Hash]
682
+ # @param room_id [Integer]
683
+ # @param message [String]
684
+ # @param type [String]
685
+ # @param payload [Hash]
686
+ # @param extras [Hash]
465
687
  # @return [TrueClass]
466
- def send_bot_message(options = {})
467
- post("#{app_id}/bot", options)
688
+ def send_bot_message(room_id, message, type: "text", payload: {}, extras: {})
689
+ body = post("/#{app_id}/bot", {
690
+ sender_email: admin_email,
691
+ room_id: room_id.to_s,
692
+ message: message,
693
+ type: type,
694
+ payload: payload,
695
+ extras: extras
696
+ })
697
+
698
+ if body != "ok"
699
+ raise Qismo::BadRequestError.new(body.to_s, status_code: 400, response_body: body.to_s)
700
+ end
701
+
468
702
  true
469
703
  end
470
704
 
@@ -494,7 +728,10 @@ module Qismo
494
728
  # @param room_id [Integer]
495
729
  # @return [TrueClass]
496
730
  def handover_room_from_bot(room_id)
497
- post("/#{app_id}/bot/#{room_id}/hand_over")
731
+ request(:post, "/#{app_id}/bot/#{room_id}/hand_over", headers: {
732
+ Authorization: secret_key
733
+ })
734
+
498
735
  true
499
736
  end
500
737
 
@@ -505,8 +742,33 @@ module Qismo
505
742
  # @param roles [Array<Integer>]
506
743
  # @param options [Hash]
507
744
  # @return [TrueClass]
508
- def handover_room_from_bot_to_division(room_id, roles, options = {})
509
- post("/#{app_id}/bot/#{room_id}/hand_over_to_role", options.merge(roles: roles))
745
+
746
+ # Handover room from chatbot to human agent in specific divisions
747
+ #
748
+ # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#8218db08-9753-4d74-ae5f-0ee62f8579b9# <Description>
749
+ #
750
+ # @param room_id [Integer]
751
+ # @param role [Integer,Array<Integer>]
752
+ # @param find_online_agent [TrueClass,FalseClass]
753
+ # @return [TrueClass,FalseClass]
754
+ def handover_room_from_bot_to_division(room_id, role, find_online_agent: true)
755
+ options = {}
756
+ options[:room_id] = room_id.to_s
757
+ options[:find_online_agent] = find_online_agent
758
+
759
+ if role.is_a?(Array)
760
+ options[:roles] = role
761
+ else
762
+ options[:role] = role
763
+ end
764
+
765
+ request(
766
+ :post,
767
+ "/#{app_id}/bot/#{room_id}/hand_over_to_role",
768
+ headers: {Authorization: secret_key},
769
+ json: options
770
+ )
771
+
510
772
  true
511
773
  end
512
774
 
@@ -519,7 +781,7 @@ module Qismo
519
781
  # @return [Qismo::SingleObject]
520
782
  def initiate_widget_chat(user_id, name, options = {})
521
783
  options = options.merge(app_id: app_id, user_id: user_id, name: name)
522
- post("/api/v2/qiscus/initiate_chat", options).data.customer_room
784
+ Qismo::Objects::CustomerRoom.new(post("/api/v2/qiscus/initiate_chat", options).data.customer_room)
523
785
  end
524
786
 
525
787
  alias_method :initiate_chat, :initiate_widget_chat
@@ -532,78 +794,49 @@ module Qismo
532
794
  # @param name [String]
533
795
  # @param options [Hash]
534
796
  # @return [Qismo::SingleObject]
535
- def send_message_to_custom_channel(identifier_key, user_id, name, options = {})
536
- post("/#{app_id}/api/v2/custom_channel/send",
537
- options.merge(identifier_key: identifier_key, user_id: user_id, name: name)).data
538
- end
539
797
 
540
- # List integrated channels
798
+ # Send messsage to custom channel
541
799
  #
542
800
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#aee54b21-68f1-4d31-9d81-d3c73b3e125b
543
- # @return [Qismo::SingleObject]
544
- def channels
545
- get("/api/v2/channels").data
546
- end
547
-
548
- # Create customchannel
549
- #
550
801
  # @param identifier_key [String]
802
+ # @param user_id [String]
551
803
  # @param name [String]
552
- # @param webhook_url [String]
553
- # @param options [Hash]
554
- # @return [Qismo::SingleObject]
555
- def create_custom_channel(identifier_key, name, webhook_url, options = {})
556
- options = options.merge(
557
- identifier_key: identifier_key,
558
- name: name,
559
- webhook_url: webhook_url
804
+ # @param message [String]
805
+ # @param avatar [String]
806
+ # @param type [String]
807
+ # @param payload [Hash]
808
+ # @param extras [Hash]
809
+ # @return [Qismo::Objects::CustomChannelMessageResponse]
810
+ def send_message_to_custom_channel(
811
+ identifier_key,
812
+ user_id,
813
+ name,
814
+ message,
815
+ avatar: nil,
816
+ type: "text",
817
+ payload: {},
818
+ extras: {}
819
+ )
820
+ Qismo::Objects::CustomChannelMessageResponse.new(
821
+ post("/#{app_id}/api/v2/custom_channel/send", {
822
+ identifier_key: identifier_key,
823
+ user_id: user_id,
824
+ name: name,
825
+ message: message,
826
+ avatar: avatar,
827
+ type: type,
828
+ payload: payload,
829
+ extras: extras
830
+ }).data
560
831
  )
561
-
562
- options[:is_active] = true unless options[:is_active].nil?
563
-
564
- post("/api/v1/custom_channel/connect", options.merge).data
565
- end
566
-
567
- # Update custom channel
568
- #
569
- # @param id [Integer]
570
- # @param options [Hash]
571
- # @return [Qismo::SingleObject]
572
- def update_custom_channel(id, options = {})
573
- channel = channels.custom_channels.find { |cc| cc.id == id }
574
- if channel.nil?
575
- raise Qismo::NotFoundError.new("Channel not found", status_code: 404, response_body: nil)
576
- end
577
-
578
- channel_hash = JSON.parse(channel.to_json, symbolize_names: true)
579
- new_channel_config = channel_hash.merge(options)
580
-
581
- post("/api/v1/custom_channel/connect/update", new_channel_config).data
582
- end
583
-
584
- # Activate custom channel
585
- #
586
- # @param id [Integer]
587
- # @return [Qismo::SingleObject]
588
- def activate_custom_channel(id)
589
- update_custom_channel(id, is_active: true)
590
- end
591
-
592
- # Deactivate custom channel
593
- #
594
- # @param id [Integer]
595
- # @return [Qismo::SingleObject]
596
- def deactivate_custom_channel(id)
597
- update_custom_channel(id, is_active: false)
598
832
  end
599
833
 
600
- # Delete custom channel
834
+ # List integrated channels
601
835
  #
602
- # @param id [Integer]
603
- # @return [TrueClass]
604
- def delete_custom_channel(id)
605
- post("/api/v2/custom_channel/connect/#{id}/delete")
606
- true
836
+ # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#aee54b21-68f1-4d31-9d81-d3c73b3e125b
837
+ # @return [Qismo::ObjectifiedHash]
838
+ def channels
839
+ get("/api/v2/channels").data
607
840
  end
608
841
  end
609
842
  end