qismo 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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