qismo 0.13.0 → 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
@@ -7,32 +7,41 @@ module Qismo
7
7
  # List customer rooms
8
8
  #
9
9
  # @see https://s.id/list-customer-rooms
10
- # @param [Hash] options
11
- # @option options [String] :status Filter by room status. Valid values are "resolved", "unresolved", "expired", or "almost_expired"
12
- # @option options [String] :serve_status Filter by room serve status. Valid values are "served" or "unserved"
13
- # @option options [Array<Hash>] :channels Filter by channels. Example: [{ source: "wa", channel_id: 716171 }]
14
- # @option options [TrueClass,FalseClass] :is_handled_by_bot Filter by bot handling status
15
- # @option options [String] :name Filter by customer name
16
- # @option options [Integer] :limit Number of data returned in one page. Default is 50
17
- # @option options [String] :order Order data by timestamp. Can be ordered "asc" or "desc". Default is "desc"
18
- # @option options [String] :cursor_after Next page cursor. If you are on last page, the cursor returned will be nil
19
- # @option options [String] :cursor_before Previous page cursor. If you are on first page, the cursor returned will be nil
20
- # @option options [Array<Integer>] :tag_ids Filter by tags
21
- # @option options [Array<Integer>] :user_ids Filter by agent who handled or assigned to the room
22
- # @return [Qismo::CollectionObject]
10
+ # @param options [Hash]
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>]
23
35
  def rooms(options = {})
24
36
  body = post("/api/v2/customer_rooms", options)
25
- CollectionObject.new(
26
- body.data.customer_rooms,
27
- prev_page: body.meta&.cursor_before,
28
- next_page: body.meta&.cursor_after,
29
- prev_func: -> { rooms(options.merge(cursor_before: body.meta&.cursor_before)) },
30
- 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
31
41
  )
32
42
  end
33
43
 
34
44
  # Get room by id
35
- #
36
45
  # @see https://s.id/get-room-by-room-id
37
46
  # @param room_id [Integer]
38
47
  # @return [Qismo::SingleObject]
@@ -42,16 +51,20 @@ module Qismo
42
51
  raise Qismo::NotFoundError.new("Room not found", status_code: 404, response_body: body.to_json)
43
52
  end
44
53
 
45
- body.data.customer_room
54
+ Qismo::Objects::CustomerRoom.new(body.data.customer_room)
46
55
  end
47
56
 
48
57
  # List tags inside room
49
58
  #
50
59
  # @see https://s.id/list-room-tags
51
60
  # @param room_id [Integer]
52
- # @return [Qismo::CollectionObject]
61
+ # @return [Qismo::Collection<Qismo::Objects::Tag>]
53
62
  def room_tags(room_id)
54
- 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
+ )
55
68
  end
56
69
 
57
70
  # Add room tag
@@ -59,9 +72,11 @@ module Qismo
59
72
  # @see https://s.id/add-room-tag
60
73
  # @param room_id [Integer]
61
74
  # @param tag_name [String]
62
- # @return [Qismo::SingleObject]
75
+ # @return [Qismo::Objects::Tag]
63
76
  def add_room_tag(room_id, tag_name)
64
- 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
+ )
65
80
  end
66
81
 
67
82
  # Delete room tag
@@ -79,13 +94,13 @@ module Qismo
79
94
  #
80
95
  # @see https://s.id/list-room-info
81
96
  # @param room_id [Integer]
82
- # @return [Qismo::CollectionObject]
97
+ # @return [Array<Qismo::Objects::RoomAdditionalInfo>]
83
98
  def room_additional_info(room_id)
84
- CollectionObject.new(
85
- get(
86
- "/api/v1/qiscus/room/#{room_id}/user_info"
87
- ).data&.extras&.user_properties
88
- ) || 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([])
89
104
  end
90
105
 
91
106
  alias_method :room_info, :room_additional_info
@@ -96,14 +111,15 @@ module Qismo
96
111
  # @note This will replace your current room additional info
97
112
  # @param room_id [Integer]
98
113
  # @param additional_info [Array<Hash>]
99
- # @return [Qismo::CollectionObject]
114
+ # Key value pair of additional info. Ex: [{ key: "Ticket Link", value: "https://ticket.com" }]
115
+ # @return [Array<Qismo::Objects::RoomAdditionalInfo>]
100
116
  def set_room_additional_info(room_id, additional_info)
101
- CollectionObject.new(
117
+ Qismo::Objects::RoomAdditionalInfo.from_array(
102
118
  post(
103
119
  "/api/v1/qiscus/room/#{room_id}/user_info",
104
120
  user_properties: additional_info
105
- ).data&.extras&.user_properties
106
- ) || CollectionObject.new
121
+ ).data.extras.user_properties
122
+ )
107
123
  end
108
124
 
109
125
  alias_method :set_room_info, :set_room_additional_info
@@ -113,11 +129,12 @@ module Qismo
113
129
  # Update room additional info
114
130
  #
115
131
  # @param room_id [Integer]
116
- # @param additional_info [Array]
117
- # @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>]
118
135
  def update_room_additional_info(room_id, additional_info)
119
- old_additional_info = room_additional_info(room_id)
120
- 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") }
121
138
  set_room_additional_info(room_id, new_additional_info)
122
139
  end
123
140
 
@@ -129,31 +146,49 @@ module Qismo
129
146
  # @param room_id [Integer]
130
147
  # @param options [Hash]
131
148
  # @return [Qismo::CollectionObject]
132
- def room_broadcast_history(room_id, options = {})
133
- body = get("/api/v2/customer_rooms/#{room_id}/broadcast_history", options)
134
-
135
- next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
136
- prev_page = (body.meta.page > 1) ? (body.meta.page - 1) : nil
137
149
 
138
- CollectionObject.new(
139
- body.data.broadcast_logs,
140
- next_page: next_page,
141
- prev_page: prev_page,
142
- next_func: -> { room_broadcast_history(options.merge(page: next_page)) },
143
- 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)
144
166
  )
145
167
  end
146
168
 
147
- # Assign agent to room
169
+ # Assign an agent to a room
148
170
  #
149
- # @see https://s.id/assign-agent
150
171
  # @param room_id [Integer]
151
172
  # @param agent_id [Integer]
152
- # @param options [Hash]
153
- # @return [Qismo::SingleObject]
154
- def assign_agent(room_id, agent_id, options = {})
155
- body = post("/api/v1/admin/service/assign_agent", options.merge(room_id: room_id.to_s, agent_id: agent_id))
156
- 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
+ )
157
192
  end
158
193
 
159
194
  # Remove agent from room
@@ -163,7 +198,13 @@ module Qismo
163
198
  # @param agent_id [Integer]
164
199
  # @return [TrueClass]
165
200
  def remove_agent(room_id, agent_id)
166
- 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
+
167
208
  true
168
209
  end
169
210
 
@@ -172,12 +213,27 @@ module Qismo
172
213
  # @see https://s.id/resolve-room
173
214
  # @param room_id [Integer]
174
215
  # @param last_comment_id [Integer]
175
- # @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
176
226
  # @return [Qismo::SingleObject]
177
- def resolve_room(room_id, last_comment_id, options = {})
178
- body = post("/api/v1/admin/service/mark_as_resolved",
179
- options.merge(room_id: room_id.to_s, last_comment_id: last_comment_id))
180
- 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
+ )
181
237
  end
182
238
 
183
239
  alias_method :resolve, :resolve_room
@@ -186,38 +242,64 @@ module Qismo
186
242
  #
187
243
  # @see https://s.id/allocate-agent
188
244
  # @param source [String]
189
- # @param options [Hash]
190
- # @return [Qismo::SingleObject]
191
- def allocate_agent(source, options = {})
192
- body = post("/api/v1/admin/service/allocate_agent", options.merge(source: source))
193
- 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
+ )
194
262
  end
195
263
 
196
264
  # Get agent that can be allocated to room and automatically assign them
197
265
  #
198
266
  # @see https://s.id/allocate-and-assign-agent
199
267
  # @param room_id [Integer]
200
- # @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
201
271
  # @return [Qismo::SingleObject]
202
- def allocate_and_assign_agent(room_id, options = {})
203
- body = post("/api/v1/admin/service/allocate_assign_agent", options.merge(room_id: room_id))
204
- 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
+ )
205
279
  end
206
280
 
207
281
  # List agents that are not in room and can be assigned to room
208
282
  #
209
283
  # @see https://s.id/list-other-agents
210
284
  # @param room_id [Integer]
211
- # @param options [Hash]
212
- # @return [Qismo::CollectionObject]
213
- def other_agents(room_id, options = {})
214
- body = get("/api/v2/admin/service/other_agents", options.merge(room_id: room_id))
215
- CollectionObject.new(
216
- body.data.agents,
217
- prev_page: body.meta&.cursor_before,
218
- next_page: body.meta&.cursor_after,
219
- prev_func: -> { other_agents(options.merge(cursor_before: body.meta&.cursor_before)) },
220
- 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
221
303
  )
222
304
  end
223
305
 
@@ -225,100 +307,132 @@ module Qismo
225
307
  #
226
308
  # @see https://s.id/list-available-agents
227
309
  # @param room_id [Integer]
228
- # @param options [Hash]
229
- # @return [Qismo::CollectionObject]
230
- def available_agents(room_id, options = {})
231
- body = get("/api/v2/admin/service/available_agents", options.merge(room_id: room_id))
232
- CollectionObject.new(
233
- body.data.agents,
234
- prev_page: body.meta&.cursor_before,
235
- next_page: body.meta&.cursor_after,
236
- prev_func: -> { available_agents(options.merge(cursor_before: body.meta&.cursor_before)) },
237
- 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
238
330
  )
239
331
  end
240
332
 
241
333
  # Get new session webhook config
242
334
  #
243
- # @return [Qismo::SingleObject]
335
+ # @return [Qismo::Objects::Webhook]
244
336
  def new_session_webhook
245
- 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
+ )
246
342
  end
247
343
 
248
344
  # Set new session webhook
249
345
  #
250
346
  # @param url [String]
251
- # @param options [Hash]
252
- # @return [Qismo::SingleObject]
253
- def set_new_session_webhook(url, options = {})
254
- 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
+ )
255
355
  end
256
356
 
257
357
  # Get auth webhook config
258
358
  #
259
359
  # @return [Qismo::SingleObject]
260
360
  def auth_webhook
261
- 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
+ )
262
366
  end
263
367
 
264
368
  # Set auth webhook
265
369
  #
266
370
  # @param url [String]
267
371
  # @param enabled [TrueClass, FalseClass]
268
- # @param options [Hash]
269
372
  # @return [Qismo::SingleObject]
270
- def set_auth_webhook(url, enabled = true, options = {})
271
- 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
+ )
272
379
  end
273
380
 
274
381
  # Get resolve webhook config
275
382
  #
276
- # @return [Qismo::SingleObject]
383
+ # @return [Qismo::Objects::Webhook]
277
384
  def resolve_webhook
278
- 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
+ )
279
390
  end
280
391
 
281
392
  # Set resolve webhook
282
393
  #
283
394
  # @param url [String]
284
395
  # @param options [Hash]
285
- # @return [Qismo::SingleObject]
286
- def set_resolve_webhook(url, options = {})
287
- 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
+ )
288
403
  end
289
404
 
290
405
  # List agents
291
406
  #
292
407
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#849205ca-00d9-4356-9fdd-f05bff777b4e
293
408
  # @param options [Hash]
294
- # @return [Qismo::CollectionObject]
295
- def agents(options = {})
296
- if options[:page].nil? || options[:page].empty?
297
- options[:page] = 1
298
- end
299
-
300
- 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
+ })
301
417
 
302
418
  total_page = (body.meta.total_count.to_f / body.meta.per_page.to_f).ceil
303
- next_page = (options[:page] < total_page) ? (options[:page] + 1) : nil
304
- prev_page = (options[:page] > 1) ? (options[:page] - 1) : nil
305
419
 
306
- CollectionObject.new(
307
- body.data.agents,
308
- next_page: next_page,
309
- prev_page: prev_page,
310
- next_func: -> { agents(options.merge(page: next_page)) },
311
- 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)
312
424
  )
313
425
  end
314
426
 
315
- # List agents by id
427
+ # List agents by ids
316
428
  #
317
429
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#3db6c8c8-8ffe-4a88-b630-41f9d5b62298
318
430
  # @param ids [Array<Integer>]
319
- # @return [Qismo::CollectionObject]
431
+ # @return [Qismo::Collection<Qismo::Objects::User>]
320
432
  def agents_by_ids(ids)
321
- 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
+ )
322
436
  end
323
437
 
324
438
  # List agents by divisions
@@ -326,19 +440,20 @@ module Qismo
326
440
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#94eeb9cb-dd70-4baf-9f63-361e7922299a
327
441
  # @param division_ids [Array<Integer>]
328
442
  # @param options [Hash]
329
- # @return [Qismo::CollectionObject]
330
- def agents_by_divisions(division_ids, options = {})
331
- body = get("/api/v2/admin/agents/by_division", options.merge({"division_ids[]": division_ids}))
332
-
333
- next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
334
- prev_page = (body.meta.page > 1) ? (body.meta.page - 1) : nil
335
-
336
- CollectionObject.new(
337
- body.data,
338
- next_page: next_page,
339
- prev_page: prev_page,
340
- next_func: -> { agents_by_divisions(options.merge(page: next_page)) },
341
- 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)
342
457
  )
343
458
  end
344
459
 
@@ -346,21 +461,19 @@ module Qismo
346
461
  #
347
462
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#c6184a6b-ba4d-4f3e-a4da-c6d0fa4597af
348
463
  # @param agent_id [Integer]
349
- # @return [Qismo::SingleObject]
464
+ # @return [Qismo::Objects::User]
350
465
  def agent(agent_id)
351
- get("/api/v2/admin/agent/#{agent_id}").data.agent
466
+ Qismo::Objects::User.new(get("/api/v2/admin/agent/#{agent_id}").data.agent)
352
467
  end
353
468
 
354
469
  # Get office hour config
355
470
  #
356
471
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#6f3f0cb0-a391-4945-b01a-95ce81138913
357
- # @return [Qismo::SingleObject]
472
+ # @return [Qismo::Objects::OfficeHour]
358
473
  def office_hours
359
- data = get("/api/v1/admin/office_hours").data
360
- data_hash = data.as_json
361
- data_hash["is_in_office_hour"] = Util.in_office_hour?(data)
362
-
363
- SingleObject.new(data_hash)
474
+ Qismo::Objects::OfficeHour.new(
475
+ get("/api/v1/admin/office_hours").data
476
+ )
364
477
  end
365
478
 
366
479
  # List WA broadcast templates
@@ -368,32 +481,76 @@ module Qismo
368
481
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#e38d2244-9559-4015-99d5-8c707f6c01bd
369
482
  # @param options [Hash]
370
483
  # @return [Qismo::CollectionObject]
371
- def wa_broadcast_templates(options = {})
372
- body = get("/api/v3/admin/hsm", options)
373
-
374
- meta = body.meta
375
- next_page = (meta.page < meta.total_page) ? (meta.page + 1) : nil
376
- prev_page = (meta.page > 1) ? (meta.page - 1) : nil
377
-
378
- CollectionObject.new(
379
- body.data.hsm_templates,
380
- next_page: next_page,
381
- prev_page: prev_page,
382
- next_func: -> { wa_broadcast_templates(options.merge(page: next_page)) },
383
- 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)
384
495
  )
385
496
  end
386
497
 
387
498
  alias_method :wa_message_templates, :wa_broadcast_templates
388
499
  alias_method :wa_outbound_templates, :wa_broadcast_templates
389
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
+
390
510
  # Send WA outbound message
391
511
  #
392
512
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#d0183cf6-deca-439b-aff3-2e2f007c15a9
393
- # @param options [Hash]
394
- # @return [Qismo::SingleObject]
395
- def send_wa_outbound(options = {})
396
- 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)
397
554
  end
398
555
 
399
556
  # Upload wa broadcast file that want to be sent in broadcast
@@ -401,20 +558,58 @@ module Qismo
401
558
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#030acde2-21cf-4373-8d11-075206053c1d
402
559
  # @param file [HTTP::FormData]
403
560
  # @param template_detail_id [Integer]
404
- # @return [Qismo::SingleObject]
405
- def upload_wa_broadcast_csv(file, template_detail_id)
561
+ # @return [Integer]
562
+ def upload_wa_broadcast_csv(file, template_detail_id, separator: ",")
406
563
  raise ArgumentError, "Invalid file" unless file.is_a?(HTTP::FormData::File)
407
564
 
408
- 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
409
572
  end
410
573
 
411
- # Send wa broadcast
574
+ # Send WA broadcast
412
575
  #
413
576
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#717c1a12-facb-4945-aed5-04557696b873
414
- # @param options [Hash]
415
- # @return [Qismo::SingleObject]
416
- def send_wa_broadcast(options = {})
417
- 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
+ )
418
613
  end
419
614
 
420
615
  alias_method :create_wa_broadcast, :send_wa_broadcast
@@ -424,18 +619,27 @@ module Qismo
424
619
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#3a4caa8b-eef4-427f-adcb-d065989899c9
425
620
  # @param options [Hash]
426
621
  # @return [Qismo::CollectionObject]
427
- def wa_broadcast_jobs(options = {})
428
- body = get("/api/v2/admin/broadcast_jobs", options)
429
-
430
- prev_page = (body.meta.page > 1) ? (body.meta.meta - 1) : nil
431
- next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
432
622
 
433
- CollectionObject.new(
434
- body.data.broadcast_jobs,
435
- next_page: next_page,
436
- prev_page: prev_page,
437
- next_func: -> { wa_broadcast_jobs(options.merge(page: next_page)) },
438
- 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
439
643
  )
440
644
  end
441
645
 
@@ -443,9 +647,11 @@ module Qismo
443
647
  #
444
648
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#ed0806c8-2e4a-4ea4-8acb-45c84c63c2da
445
649
  # @param broadcast_job_id [Integer]
446
- # @return [Qismo::SingleObject]
650
+ # @return [Qismo::Objects::BroadcastJob]
447
651
  def wa_broadcast_job(broadcast_job_id)
448
- 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
+ )
449
655
  end
450
656
 
451
657
  # List wa broadcast logs
@@ -454,29 +660,45 @@ module Qismo
454
660
  # @param broadcast_job_id [Integer]
455
661
  # @param options [Hash]
456
662
  # @return [Qismo::CollectionObject]
457
- def wa_broadcast_logs(broadcast_job_id, options = {})
458
- 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
+ })
459
668
 
460
669
  prev_page = (body.meta.page > 1) ? (body.meta.meta - 1) : nil
461
670
  next_page = (body.meta.page < body.meta.total_page) ? (body.meta.page + 1) : nil
462
671
 
463
- CollectionObject.new(
464
- body.data.broadcast_logs,
672
+ Qismo::Collection.new(
673
+ Qismo::Objects::BroadcastLog.from_array(body.data.broadcast_logs),
465
674
  next_page: next_page,
466
- prev_page: prev_page,
467
- next_func: -> { wa_broadcast_logs(options.merge(page: next_page)) },
468
- prev_func: -> { wa_broadcast_jobs(options.merge(page: prev_page)) }
675
+ prev_page: prev_page
469
676
  )
470
677
  end
471
678
 
472
679
  # Send message as bot
473
680
  #
474
681
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#bb77c653-5daa-4e1c-a866-43bca7c494fc
475
- # @param options [Hash]
682
+ # @param room_id [Integer]
683
+ # @param message [String]
684
+ # @param type [String]
685
+ # @param payload [Hash]
686
+ # @param extras [Hash]
476
687
  # @return [TrueClass]
477
- def send_bot_message(room_id, options = {})
478
- options = options.merge(room_id: room_id.to_s, sender_email: admin_email)
479
- 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
+
480
702
  true
481
703
  end
482
704
 
@@ -506,7 +728,10 @@ module Qismo
506
728
  # @param room_id [Integer]
507
729
  # @return [TrueClass]
508
730
  def handover_room_from_bot(room_id)
509
- 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
+
510
735
  true
511
736
  end
512
737
 
@@ -517,8 +742,33 @@ module Qismo
517
742
  # @param roles [Array<Integer>]
518
743
  # @param options [Hash]
519
744
  # @return [TrueClass]
520
- def handover_room_from_bot_to_division(room_id, roles, options = {})
521
- 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
+
522
772
  true
523
773
  end
524
774
 
@@ -531,7 +781,7 @@ module Qismo
531
781
  # @return [Qismo::SingleObject]
532
782
  def initiate_widget_chat(user_id, name, options = {})
533
783
  options = options.merge(app_id: app_id, user_id: user_id, name: name)
534
- 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)
535
785
  end
536
786
 
537
787
  alias_method :initiate_chat, :initiate_widget_chat
@@ -544,78 +794,49 @@ module Qismo
544
794
  # @param name [String]
545
795
  # @param options [Hash]
546
796
  # @return [Qismo::SingleObject]
547
- def send_message_to_custom_channel(identifier_key, user_id, name, options = {})
548
- post("/#{app_id}/api/v2/custom_channel/send",
549
- options.merge(identifier_key: identifier_key, user_id: user_id, name: name)).data
550
- end
551
797
 
552
- # List integrated channels
798
+ # Send messsage to custom channel
553
799
  #
554
800
  # @see https://documenter.getpostman.com/view/8259884/TVsuCSeT#aee54b21-68f1-4d31-9d81-d3c73b3e125b
555
- # @return [Qismo::SingleObject]
556
- def channels
557
- get("/api/v2/channels").data
558
- end
559
-
560
- # Create customchannel
561
- #
562
801
  # @param identifier_key [String]
802
+ # @param user_id [String]
563
803
  # @param name [String]
564
- # @param webhook_url [String]
565
- # @param options [Hash]
566
- # @return [Qismo::SingleObject]
567
- def create_custom_channel(identifier_key, name, webhook_url, options = {})
568
- options = options.merge(
569
- identifier_key: identifier_key,
570
- name: name,
571
- 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
572
831
  )
573
-
574
- options[:is_active] = true unless options[:is_active].nil?
575
-
576
- post("/api/v1/custom_channel/connect", options.merge).data
577
- end
578
-
579
- # Update custom channel
580
- #
581
- # @param id [Integer]
582
- # @param options [Hash]
583
- # @return [Qismo::SingleObject]
584
- def update_custom_channel(id, options = {})
585
- channel = channels.custom_channels.find { |cc| cc.id == id }
586
- if channel.nil?
587
- raise Qismo::NotFoundError.new("Channel not found", status_code: 404, response_body: nil)
588
- end
589
-
590
- channel_hash = JSON.parse(channel.to_json, symbolize_names: true)
591
- new_channel_config = channel_hash.merge(options)
592
-
593
- post("/api/v1/custom_channel/connect/update", new_channel_config).data
594
- end
595
-
596
- # Activate custom channel
597
- #
598
- # @param id [Integer]
599
- # @return [Qismo::SingleObject]
600
- def activate_custom_channel(id)
601
- update_custom_channel(id, is_active: true)
602
- end
603
-
604
- # Deactivate custom channel
605
- #
606
- # @param id [Integer]
607
- # @return [Qismo::SingleObject]
608
- def deactivate_custom_channel(id)
609
- update_custom_channel(id, is_active: false)
610
832
  end
611
833
 
612
- # Delete custom channel
834
+ # List integrated channels
613
835
  #
614
- # @param id [Integer]
615
- # @return [TrueClass]
616
- def delete_custom_channel(id)
617
- post("/api/v2/custom_channel/connect/#{id}/delete")
618
- 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
619
840
  end
620
841
  end
621
842
  end