gitlab-customer-support-operations_zendesk 1.0.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/lib/support_ops_zendesk/packages.rb +89 -0
  3. data/lib/support_ops_zendesk/zendesk/app_installations.rb +62 -0
  4. data/lib/support_ops_zendesk/zendesk/app_job_statuses.rb +157 -0
  5. data/lib/support_ops_zendesk/zendesk/apps.rb +476 -0
  6. data/lib/support_ops_zendesk/zendesk/articles.rb +362 -0
  7. data/lib/support_ops_zendesk/zendesk/audit_logs.rb +166 -0
  8. data/lib/support_ops_zendesk/zendesk/automations.rb +390 -0
  9. data/lib/support_ops_zendesk/zendesk/base.rb +472 -0
  10. data/lib/support_ops_zendesk/zendesk/brands.rb +172 -0
  11. data/lib/support_ops_zendesk/zendesk/client.rb +91 -0
  12. data/lib/support_ops_zendesk/zendesk/comments.rb +37 -0
  13. data/lib/support_ops_zendesk/zendesk/configuration.rb +138 -0
  14. data/lib/support_ops_zendesk/zendesk/custom_roles.rb +224 -0
  15. data/lib/support_ops_zendesk/zendesk/dynamic_content.rb +297 -0
  16. data/lib/support_ops_zendesk/zendesk/dynamic_content_variants.rb +309 -0
  17. data/lib/support_ops_zendesk/zendesk/group_memberships.rb +337 -0
  18. data/lib/support_ops_zendesk/zendesk/groups.rb +385 -0
  19. data/lib/support_ops_zendesk/zendesk/help_center_categories.rb +332 -0
  20. data/lib/support_ops_zendesk/zendesk/help_center_content_tags.rb +237 -0
  21. data/lib/support_ops_zendesk/zendesk/help_center_management_permission_groups.rb +271 -0
  22. data/lib/support_ops_zendesk/zendesk/help_center_sections.rb +378 -0
  23. data/lib/support_ops_zendesk/zendesk/help_center_topics.rb +274 -0
  24. data/lib/support_ops_zendesk/zendesk/help_center_user_segments.rb +279 -0
  25. data/lib/support_ops_zendesk/zendesk/job_statuses.rb +231 -0
  26. data/lib/support_ops_zendesk/zendesk/locales.rb +326 -0
  27. data/lib/support_ops_zendesk/zendesk/macros.rb +407 -0
  28. data/lib/support_ops_zendesk/zendesk/oauth_clients.rb +186 -0
  29. data/lib/support_ops_zendesk/zendesk/oauth_tokens.rb +114 -0
  30. data/lib/support_ops_zendesk/zendesk/organization_fields.rb +282 -0
  31. data/lib/support_ops_zendesk/zendesk/organization_memberships.rb +336 -0
  32. data/lib/support_ops_zendesk/zendesk/organizations.rb +568 -0
  33. data/lib/support_ops_zendesk/zendesk/requester_roles.rb +58 -0
  34. data/lib/support_ops_zendesk/zendesk/satisfaction_reasons.rb +161 -0
  35. data/lib/support_ops_zendesk/zendesk/schedule_holidays.rb +27 -0
  36. data/lib/support_ops_zendesk/zendesk/schedules.rb +192 -0
  37. data/lib/support_ops_zendesk/zendesk/search.rb +185 -0
  38. data/lib/support_ops_zendesk/zendesk/sla_policies.rb +302 -0
  39. data/lib/support_ops_zendesk/zendesk/targets.rb +96 -0
  40. data/lib/support_ops_zendesk/zendesk/theme_job_statuses.rb +154 -0
  41. data/lib/support_ops_zendesk/zendesk/themes.rb +328 -0
  42. data/lib/support_ops_zendesk/zendesk/ticket_field_options.rb +154 -0
  43. data/lib/support_ops_zendesk/zendesk/ticket_fields.rb +357 -0
  44. data/lib/support_ops_zendesk/zendesk/ticket_forms.rb +370 -0
  45. data/lib/support_ops_zendesk/zendesk/ticket_user_types.rb +67 -0
  46. data/lib/support_ops_zendesk/zendesk/tickets.rb +837 -0
  47. data/lib/support_ops_zendesk/zendesk/translations.rb +310 -0
  48. data/lib/support_ops_zendesk/zendesk/trigger_categories.rb +275 -0
  49. data/lib/support_ops_zendesk/zendesk/triggers.rb +427 -0
  50. data/lib/support_ops_zendesk/zendesk/user_field_options.rb +153 -0
  51. data/lib/support_ops_zendesk/zendesk/user_fields.rb +312 -0
  52. data/lib/support_ops_zendesk/zendesk/users.rb +889 -0
  53. data/lib/support_ops_zendesk/zendesk/via_types.rb +137 -0
  54. data/lib/support_ops_zendesk/zendesk/views.rb +636 -0
  55. data/lib/support_ops_zendesk/zendesk/webhooks.rb +206 -0
  56. data/lib/support_ops_zendesk/zendesk.rb +66 -0
  57. data/lib/support_ops_zendesk.rb +29 -0
  58. metadata +274 -0
@@ -0,0 +1,837 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module SupportOps.
4
+ module SupportOps
5
+ # Defines the module Zendesk
6
+ module Zendesk
7
+ ##
8
+ # Defines the class Tickets within the module {SupportOps::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ # @attr [Integer] assignee_id The agent currently assigned to the ticket
13
+ # @attr [Array] additional_tags An array of tags to add in an update
14
+ # @attr [Integer] brand_id The id of the brand this ticket is associated with
15
+ # @attr [Array] collaborator_ids The ids of users currently CC'ed on the ticket
16
+ # @attr [Hash] comment An object that adds a comment to the ticket
17
+ # @attr [String] created_at When this record was created
18
+ # @attr [Array] custom_fields Custom fields for the ticket
19
+ # @attr [Integer] custom_status_id The custom ticket status id of the ticket
20
+ # @attr [String] description Read-only first comment on the ticket
21
+ # @attr [String] due_at If this is a ticket of type "task" it has a due date
22
+ # @attr [Array] email_cc_ids he ids of agents or end users currently CC'ed on the ticket
23
+ # @attr [Array] email_ccs An array of objects that represent agent or end users email CCs to add or delete from the ticket
24
+ # @attr [Array] fields Custom fields for the ticket
25
+ # @attr [Array] follower_ids The ids of agents currently following the ticket
26
+ # @attr [Array] followup_ids The ids of the followups created from this ticket
27
+ # @attr [Integer] group_id The group this ticket is assigned to
28
+ # @attr [Boolean] has_incidents Is true if a ticket is a problem type and has one or more incidents linked to it. Otherwise, the value is false.
29
+ # @attr [Integer] id Automatically assigned when the ticket is created
30
+ # @attr [Boolean] is_public Is true if any comments are public, false otherwise
31
+ # @attr [Integer] organization_id The organization of the requester. You can only specify the ID of an organization associated with the requester.
32
+ # @attr [String] priority The urgency with which the ticket should be addressed. Allowed values are "urgent", "high", "normal", or "low".
33
+ # @attr [Integer] problem_id For tickets of type "incident", the ID of the problem the incident is linked to
34
+ # @attr [Array] remove_tags An array of tags to remove in an update
35
+ # @attr [Hash] requester An object used to set the request on a ticket during creation
36
+ # @attr [Integer] requester_id The user who requested this ticket
37
+ # @attr [String] satisfaction_rating The satisfaction rating of the ticket, if it exists, or the state of satisfaction, "offered" or "unoffered". The value is null for plan types that don't support CSAT
38
+ # @attr [String] status The state of the ticket. If your account has activated custom ticket statuses, this is the ticket's status category. Allowed values are "new", "open", "pending", "hold", "solved", or "closed".
39
+ # @attr [String] subject The value of the subject field for this ticket
40
+ # @attr [Integer] submitter_id The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket
41
+ # @attr [Array] tags The array of tags applied to this ticket
42
+ # @attr [Integer] ticket_form_id The id of the ticket form to render for the ticket
43
+ # @attr [String] type The type of this ticket. Allowed values are "problem", "incident", "question", or "task".
44
+ # @attr [String] updated_at When this record last got updated
45
+ # @attr [String] via Tells you how or why an action or event was created
46
+ # @attr [Integer] via_followup_source_id The id of a closed ticket when creating a follow-up ticket
47
+ # @todo Merge Tickets into Target Ticket => https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#merge-tickets-into-target-ticket
48
+ # @todo Ticket Related Information => https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#ticket-related-information
49
+ # @todo Autocomplete Problems => https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#autocomplete-problems
50
+ class Tickets < SupportOps::Zendesk::Base
51
+ # @!parse
52
+ # # Creates/updates a ticket
53
+ # #
54
+ # # @author Jason Colyer
55
+ # # @since 1.0.0
56
+ # # @return [Object] Instance of {SupportOps::Zendesk::Tickets}
57
+ # # @note This is inherited from {SupportOps::Zendesk::Base#save!}
58
+ # # @see
59
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#create-ticket
60
+ # # Zendesk API > Tickets > Create Ticket
61
+ # # @see
62
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-ticket
63
+ # # Zendesk API > Tickets > Update Ticket
64
+ # # @example
65
+ # # require 'support_ops_zendesk'
66
+ # #
67
+ # # SupportOps::Zendesk::Configuration.configure do |config|
68
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
69
+ # # config.username = 'jason@example.com'
70
+ # # config.token = 'abc123'
71
+ # # end
72
+ # #
73
+ # # new_ticket = SupportOps::Zendesk::Tickets.new
74
+ # # new_ticket.comment = { body: 'The smoke is very colorful'}
75
+ # # new_ticket.priority = 'urgent'
76
+ # # new_ticket.subject = 'My printer is on fire!'
77
+ # #
78
+ # # new_ticket.save!
79
+ # #
80
+ # # pp new_ticket.id
81
+ # # # => 35436
82
+ # # @example
83
+ # # require 'support_ops_zendesk'
84
+ # #
85
+ # # SupportOps::Zendesk::Configuration.configure do |config|
86
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
87
+ # # config.username = 'jason@example.com'
88
+ # # config.token = 'abc123'
89
+ # # end
90
+ # #
91
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(35436)
92
+ # # existing_ticket.status = 'open'
93
+ # # existing_ticket.comment = { body: '"The smoke is very colorful', author_id: 494820284 }
94
+ # #
95
+ # # existing_ticket.save!
96
+ # #
97
+ # # pp existing_ticket.status
98
+ # # # => "open"
99
+ # def save!; end
100
+ # @!parse
101
+ # # Deletes a ticket
102
+ # #
103
+ # # @author Jason Colyer
104
+ # # @since 1.0.0
105
+ # # @return [Boolean]
106
+ # # @note This is inherited from {SupportOps::Zendesk::Base#delete!}
107
+ # # @see
108
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#delete-ticket
109
+ # # Zendesk API > Tickets > Delete Ticket
110
+ # # @example
111
+ # # require 'support_ops_zendesk'
112
+ # #
113
+ # # SupportOps::Zendesk::Configuration.configure do |config|
114
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
115
+ # # config.username = 'jason@example.com'
116
+ # # config.token = 'abc123'
117
+ # # end
118
+ # #
119
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(35436)
120
+ # #
121
+ # # existing_ticket.delete!
122
+ # def delete!; end
123
+ # @!parse
124
+ # # Lists the collaborators on a ticket
125
+ # #
126
+ # # @author Jason Colyer
127
+ # # @since 1.0.0
128
+ # # @return [Boolean]
129
+ # # @note This is inherited from {SupportOps::Zendesk::Base#collaborators}
130
+ # # @see
131
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-collaborators-for-a-ticket
132
+ # # Zendesk API > Tickets > List Collaborators for a Ticket
133
+ # # @example
134
+ # # require 'support_ops_zendesk'
135
+ # #
136
+ # # SupportOps::Zendesk::Configuration.configure do |config|
137
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
138
+ # # config.username = 'jason@example.com'
139
+ # # config.token = 'abc123'
140
+ # # end
141
+ # #
142
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(35436)
143
+ # # collaborators = existing_ticket.collaborators
144
+ # #
145
+ # # pp collaborators.first.name
146
+ # # # => "Johnny Agent"
147
+ # def collaborators; end
148
+ # @!parse
149
+ # # Lists the followers on a ticket
150
+ # #
151
+ # # @author Jason Colyer
152
+ # # @since 1.0.0
153
+ # # @return [Boolean]
154
+ # # @note This is inherited from {SupportOps::Zendesk::Base#followers}
155
+ # # @note If not using the followers system, you should use {#collaborators} instead
156
+ # # @see
157
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-followers-for-a-ticket
158
+ # # Zendesk API > Tickets > List Followers for a Ticket
159
+ # # @example
160
+ # # require 'support_ops_zendesk'
161
+ # #
162
+ # # SupportOps::Zendesk::Configuration.configure do |config|
163
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
164
+ # # config.username = 'jason@example.com'
165
+ # # config.token = 'abc123'
166
+ # # end
167
+ # #
168
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(35436)
169
+ # # followers = existing_ticket.followers
170
+ # #
171
+ # # pp followers.last.name
172
+ # # # => "Peter Admin"
173
+ # def followers; end
174
+ # @!parse
175
+ # # Lists the CCs on a ticket
176
+ # #
177
+ # # @author Jason Colyer
178
+ # # @since 1.0.0
179
+ # # @return [Boolean]
180
+ # # @note This is inherited from {SupportOps::Zendesk::Base#ccs}
181
+ # # @note If not using the followers system, you should use {#collaborators} instead
182
+ # # @see
183
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-email-ccs-for-a-ticket
184
+ # # Zendesk API > Tickets > List Email CCs for a Ticket
185
+ # # @example
186
+ # # require 'support_ops_zendesk'
187
+ # #
188
+ # # SupportOps::Zendesk::Configuration.configure do |config|
189
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
190
+ # # config.username = 'jason@example.com'
191
+ # # config.token = 'abc123'
192
+ # # end
193
+ # #
194
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(35436)
195
+ # # ccs = existing_ticket.ccs
196
+ # #
197
+ # # pp ccs.last.name
198
+ # # # => "Jane End User"
199
+ # def ccs; end
200
+ # @!parse
201
+ # # List comments on a ticket
202
+ # #
203
+ # # @author Jason Colyer
204
+ # # @since 1.0.0
205
+ # # @return [Array]
206
+ # # @note This is inherited from {SupportOps::Zendesk::Base#comments}
207
+ # # @see
208
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/#list-comments
209
+ # # Zendesk API > Ticket comments > List Comments
210
+ # # @example
211
+ # # require 'support_ops_zendesk'
212
+ # #
213
+ # # SupportOps::Zendesk::Configuration.configure do |config|
214
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
215
+ # # config.username = 'jason@example.com'
216
+ # # config.token = 'abc123'
217
+ # # end
218
+ # #
219
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(123456)
220
+ # # comments = existing_ticket.comments
221
+ # #
222
+ # # pp comments.select { |c| c['public'] == false }.count
223
+ # # # => 12
224
+ # def comments; end
225
+ # @!parse
226
+ # # Marks a ticket as spam (and suspends the requester)
227
+ # #
228
+ # # @author Jason Colyer
229
+ # # @since 1.0.0
230
+ # # @return [Array]
231
+ # # @note This is inherited from {SupportOps::Zendesk::Base#mark_as_spam}
232
+ # # @see
233
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#mark-ticket-as-spam-and-suspend-requester
234
+ # # Zendesk API > Tickets > Mark Ticket as Spam and Suspend Requester
235
+ # # @example
236
+ # # require 'support_ops_zendesk'
237
+ # #
238
+ # # SupportOps::Zendesk::Configuration.configure do |config|
239
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
240
+ # # config.username = 'jason@example.com'
241
+ # # config.token = 'abc123'
242
+ # # end
243
+ # #
244
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(123456)
245
+ # # existing_ticket.mark_as_spam!
246
+ # def mark_as_spam!; end
247
+ # @!parse
248
+ # # Lists incidents attached to the ticket
249
+ # #
250
+ # # @author Jason Colyer
251
+ # # @since 1.0.0
252
+ # # @return [Array]
253
+ # # @note This is inherited from {SupportOps::Zendesk::Base#incidents}
254
+ # # @see
255
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-ticket-incidents
256
+ # # Zendesk API > Tickets > List Ticket Incidents
257
+ # # @example
258
+ # # require 'support_ops_zendesk'
259
+ # #
260
+ # # SupportOps::Zendesk::Configuration.configure do |config|
261
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
262
+ # # config.username = 'jason@example.com'
263
+ # # config.token = 'abc123'
264
+ # # end
265
+ # #
266
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(123456)
267
+ # # incidents = existing_ticket.incidents
268
+ # #
269
+ # # pp incidents.map { |i| i.id }
270
+ # # # => [33, 34]
271
+ # def incidents; end
272
+ # @!parse
273
+ # # Redacts all attachments (inline and external) within a ticket.
274
+ # #
275
+ # # @author Jason Colyer
276
+ # # @since 1.0.0
277
+ # # @return [Array]
278
+ # # @note This is inherited from {SupportOps::Zendesk::Base#redact_attachments!}
279
+ # # @see
280
+ # # https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/#redact-ticket-comment-in-agent-workspace
281
+ # # Zendesk API > Ticket Comments > Redact Ticket Comment In Agent Workspace
282
+ # # @example
283
+ # # require 'support_ops_zendesk'
284
+ # #
285
+ # # SupportOps::Zendesk::Configuration.configure do |config|
286
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
287
+ # # config.username = 'jason@example.com'
288
+ # # config.token = 'abc123'
289
+ # # end
290
+ # #
291
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(123456)
292
+ # # existing_ticket.redact_attachments!
293
+ # def redact_attachments!; end
294
+ # @!parse
295
+ # # List the organization details of a ticket.
296
+ # #
297
+ # # @author Jason Colyer
298
+ # # @since 1.0.0
299
+ # # @return [Various]
300
+ # # - If there is no organization, it returns nil
301
+ # # - If there is an organization, a {SupportOps::Zendesk::Organizations} instance
302
+ # # @note This is inherited from {SupportOps::Zendesk::Base#organization}
303
+ # # @example
304
+ # # require 'support_ops_zendesk'
305
+ # #
306
+ # # SupportOps::Zendesk::Configuration.configure do |config|
307
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
308
+ # # config.username = 'jason@example.com'
309
+ # # config.token = 'abc123'
310
+ # # end
311
+ # #
312
+ # # existing_ticket = SupportOps::Zendesk::Tickets.get!(123456)
313
+ # # org = existing_ticket.organization
314
+ # #
315
+ # # pp org.name
316
+ # # # => "Bob's Burgers"
317
+ # def organization; end
318
+ # @!parse
319
+ # # Add a satisfaction rating to a ticket (must be done via impersonation).
320
+ # #
321
+ # # @author Jason Colyer
322
+ # # @since 1.0.0
323
+ # # @overload create_satisfaction_score!(key: value)
324
+ # # @param score [String required] The score to use, only supports
325
+ # # 'good' and 'bad'
326
+ # # @param comment [String required] The comment to use
327
+ # # @see
328
+ # # https://developer.zendesk.com/api-reference/ticketing/ticket-management/satisfaction_ratings/#create-a-satisfaction-rating
329
+ # # Zendesk API > Satisfaction Ratings > Create a Satisfaction Rating
330
+ # # @example
331
+ # # require 'support_ops_zendesk'
332
+ # #
333
+ # # SupportOps::Zendesk::Configuration.configure do |config|
334
+ # # config.url = 'https://gitlab.zendesk.com/api/v2'
335
+ # # config.auth_type = 'OAuth'
336
+ # # config.connection_type = 'impersonation'
337
+ # # config.token = 'abc123'
338
+ # # config.on_behalf_of = 'jason@example.com'
339
+ # # end
340
+ # #
341
+ # # ticket = SupportOps::Zendesk::Tickets.get!(1)
342
+ # # rating = ticket.create_satisfaction_score!(score: 'good', comment: 'You are the best!')
343
+ # # pp rating['score']
344
+ # # # => "good"
345
+ # def create_satisfaction_score!; end
346
+ define_attributes :assignee_id, :additional_tags, :brand_id,
347
+ :collaborator_ids, :comment, :created_at,
348
+ :custom_fields, :custom_status_id, :description,
349
+ :due_at, :email_cc_ids, :email_ccs, :fields,
350
+ :follower_ids, :followup_ids, :group_id, :has_incidents,
351
+ :id, :is_public, :organization_id, :priority,
352
+ :problem_id, :remove_tags, :requester, :requester_id,
353
+ :satisfaction_rating, :status, :subject, :submitter_id,
354
+ :tags, :ticket_form_id, :type, :updated_at, :via,
355
+ :via_followup_source_id
356
+ readonly_attributes :id, :created_at, :updated_at
357
+
358
+ ##
359
+ # Returns an approximate count of tickets in the account. If the count exceeds 100,000, it is updated every 24 hours.
360
+ #
361
+ # @author Jason Colyer
362
+ # @since 1.0.0
363
+ # @return [Hash]
364
+ # @see
365
+ # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#count-tickets
366
+ # Zendesk API > Tickets > Count Tickets
367
+ # @see SupportOps::Zendesk::Configuration Setting up a client
368
+ # @example
369
+ # require 'support_ops_zendesk'
370
+ #
371
+ # SupportOps::Zendesk::Configuration.configure do |config|
372
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
373
+ # config.username = 'jason@example.com'
374
+ # config.token = 'abc123'
375
+ # end
376
+ #
377
+ # tickets = SupportOps::Zendesk::Tickets.count
378
+ # pp tickets['value']
379
+ # # => 102
380
+ def self.count
381
+ response = client.connection.get('tickets/count')
382
+ Oj.load(response.body)['count']
383
+ end
384
+
385
+ ##
386
+ # Lists tickets in the Zendesk system
387
+ #
388
+ # @author Jason Colyer
389
+ # @since 1.0.0
390
+ # @overload list(key: value)
391
+ # @param sort [String optional] The sorting method to use for the list
392
+ # ("updated_at", "id", "status", "-updated_at", "-id", "-status").
393
+ # Defaults to "id"
394
+ # @param limit [Integer optional] The limit to the number of tickets
395
+ # returned. Default to 0 (i.e. no limit)
396
+ # @return [Array]
397
+ # @see
398
+ # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-tickets
399
+ # Zendesk API > Tickets > List Tickets
400
+ # @see SupportOps::Zendesk::Configuration Setting up a client
401
+ # @example
402
+ # require 'support_ops_zendesk'
403
+ #
404
+ # SupportOps::Zendesk::Configuration.configure do |config|
405
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
406
+ # config.username = 'jason@example.com'
407
+ # config.token = 'abc123'
408
+ # end
409
+ #
410
+ # tickets = SupportOps::Zendesk::Tickets.list(sort: '-id', limit: 250)
411
+ # pp tickets.count
412
+ # # => 250
413
+ # pp tickets.last.subject
414
+ # # => "I'm the 250th ticket!"
415
+ def self.list(**args)
416
+ args[:sort] = 'id' unless args[:sort]
417
+ args[:limit] = 0 unless args[:limit]
418
+ tickets = []
419
+ opts = "page[size]=100&sort=#{args[:sort]}"
420
+ loop do
421
+ response = client.connection.get("tickets?#{opts}")
422
+ body = Oj.load(response.body)
423
+ tickets += body['tickets'].map { |t| Tickets.new(t) }
424
+ break if args[:limit].to_i.positive? && tickets.count >= args[:limit].to_i
425
+ break unless body['meta']['has_more']
426
+
427
+ opts = body['links']['next'].split('?').last
428
+ end
429
+ return tickets if args[:limit].to_i.zero?
430
+
431
+ tickets.first(args[:limit].to_i)
432
+ end
433
+
434
+ ##
435
+ # Locates a specific ticket in the Zendesk system
436
+ #
437
+ # @author Jason Colyer
438
+ # @since 1.0.0
439
+ # @see
440
+ # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#show-ticket
441
+ # Zendesk API > Tickets > Show Ticket
442
+ # @see SupportOps::Zendesk::Configuration Setting up a client
443
+ # @example
444
+ # require 'support_ops_zendesk'
445
+ #
446
+ # SupportOps::Zendesk::Configuration.configure do |config|
447
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
448
+ # config.username = 'jason@example.com'
449
+ # config.token = 'abc123'
450
+ # end
451
+ #
452
+ # ticket = SupportOps::Zendesk::Tickets.get(250)
453
+ # pp ticket.subject
454
+ # # => "I'm the 250th ticket!"
455
+ def self.get(object)
456
+ if object.is_a? Tickets
457
+ Tickets.new(id: id).find
458
+ else
459
+ Tickets.new(id: object).find
460
+ end
461
+ end
462
+
463
+ ##
464
+ # Locates a specific ticket in the Zendesk system
465
+ #
466
+ # @author Jason Colyer
467
+ # @since 1.0.0
468
+ # @see
469
+ # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#show-ticket
470
+ # Zendesk API > Tickets > Show Ticket
471
+ # @see SupportOps::Zendesk::Configuration Setting up a client
472
+ # @note This will hard exit if no ticket is found
473
+ # @example
474
+ # require 'support_ops_zendesk'
475
+ #
476
+ # SupportOps::Zendesk::Configuration.configure do |config|
477
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
478
+ # config.username = 'jason@example.com'
479
+ # config.token = 'abc123'
480
+ # end
481
+ #
482
+ # ticket = SupportOps::Zendesk::Tickets.get!(250)
483
+ # pp ticket.subject
484
+ # # => "I'm the 250th ticket!"
485
+ def self.get!(object)
486
+ if object.is_a? Tickets
487
+ Tickets.new(id: id).find!
488
+ else
489
+ Tickets.new(id: object).find!
490
+ end
491
+ end
492
+
493
+ ##
494
+ # Deletes multiple tickets via a batch job
495
+ #
496
+ # @author Jason Colyer
497
+ # @since 1.0.0
498
+ # @param ticket_ids [Array] An array of ticket IDs
499
+ # @return [object] A {SupportOps::Zendesk::JobStatuses} instance
500
+ # @see https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#bulk-delete-tickets Zendesk API > Tickets > Bulk Delete Tickets
501
+ # @example
502
+ # require 'support_ops_zendesk'
503
+ #
504
+ # SupportOps::Zendesk::Configuration.configure do |config|
505
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
506
+ # config.username = 'jason@example.com'
507
+ # config.token = 'abc123'
508
+ # end
509
+ #
510
+ # delete = SupportOps::Zendesk::Tickets.delete_many!([35436, 35437])
511
+ # pp delete.id
512
+ # # => "82de0b044094f0c67893ac9fe64f1a99"
513
+ def self.delete_many!(ticket_ids)
514
+ raise 'The parameter must be an Array' unless ticket_ids.is_a? Array
515
+ raise 'You can only delete a maximum of 100 tickets at a time' if ticket_ids.count > 100
516
+
517
+ response = client.connection.delete("tickets/destroy_many?ids=#{ticket_ids.join(',')}")
518
+ raise "Failed to delete tickets => #{body['details']}" if response.status != 200
519
+ JobStatuses.new(Oj.load(response.body)['job_status'])
520
+ end
521
+
522
+ ##
523
+ # Creates multiple tickets via a batch job
524
+ #
525
+ # @author Jason Colyer
526
+ # @since 1.0.0
527
+ # @param tickets [Array] An array of {SupportOps::Zendesk::Tickets} instances
528
+ # @return [object] A {SupportOps::Zendesk::JobStatuses} instance
529
+ # @see https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#create-many-tickets Zendesk API > Tickets > Create Many Tickets
530
+ # @example
531
+ # require 'support_ops_zendesk'
532
+ #
533
+ # SupportOps::Zendesk::Configuration.configure do |config|
534
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
535
+ # config.username = 'jason@example.com'
536
+ # config.token = 'abc123'
537
+ # end
538
+ #
539
+ # ticket1 = SupportOps::Zendesk::Tickets.new
540
+ # ticket1.comment = { body: 'The smoke is very colorful'}
541
+ # ticket1.priority = 'urgent'
542
+ # ticket1.subject = 'My printer is on fire!'
543
+ # ticket2 = SupportOps::Zendesk::Tickets.new
544
+ # ticket2.comment = { body: 'This is a comment'}
545
+ # ticket2.priority = 'normal'
546
+ # ticket2.subject = 'Help'
547
+ #
548
+ # creates = SupportOps::Zendesk::Tickets.create_many!([ticket1, ticket2])
549
+ # pp creates.id
550
+ # # => "82de0b044094f0c67893ac9fe64f1a99"
551
+ def self.create_many!(tickets)
552
+ raise 'The parameter must be an Array' unless tickets.is_a? Array
553
+ raise 'You can only create a maximum of 100 tickets at a time' if tickets.count > 100
554
+ raise 'You can only use SupportOps::Zendesk::Tickets instances in the Array' unless tickets.reject { |t| t.is_a? SupportOps::Zendesk::Tickets }.count.zero?
555
+
556
+ data = { tickets: tickets.map { |t| to_hash(t).compact } }.to_json
557
+ response = client.connection.post('tickets/create_many', data)
558
+ raise "Failed to create tickets => #{body['details']}" if response.status != 200
559
+ JobStatuses.new(Oj.load(response.body)['job_status'])
560
+ end
561
+
562
+ ##
563
+ # Updates multiple tickets via a batch job
564
+ #
565
+ # @author Jason Colyer
566
+ # @since 1.0.0
567
+ # @param tickets [Array] An array of {SupportOps::Zendesk::Tickets} instances
568
+ # @return [object] A {SupportOps::Zendesk::JobStatuses} instance
569
+ # @see https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-many-tickets Zendesk API > Tickets > Update Many Tickets
570
+ # @example
571
+ # require 'support_ops_zendesk'
572
+ #
573
+ # SupportOps::Zendesk::Configuration.configure do |config|
574
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
575
+ # config.username = 'jason@example.com'
576
+ # config.token = 'abc123'
577
+ # end
578
+ #
579
+ # ticket1 = SupportOps::Zendesk::Tickets.get!(255)
580
+ # ticket1.subject = 'My printer is on fire!'
581
+ # ticket2 = SupportOps::Zendesk::Tickets.get!(256)
582
+ # ticket2.subject = 'Help'
583
+ #
584
+ # updates = SupportOps::Zendesk::Tickets.update_many!([ticket1, ticket2])
585
+ # pp updates.id
586
+ # # => "82de0b044094f0c67893ac9fe64f1a99"
587
+ def self.update_many!(tickets)
588
+ raise 'The parameter must be an Array' unless tickets.is_a? Array
589
+ raise 'You can only update a maximum of 100 tickets at a time' if tickets.count > 100
590
+ raise 'You can only use SupportOps::Zendesk::Tickets instances in the Array' unless tickets.reject { |t| t.is_a? SupportOps::Zendesk::Tickets }.count.zero?
591
+
592
+ data = { tickets: tickets.map { |t| to_hash(t).compact } }.to_json
593
+ response = client.connection.put('tickets/update_many', data)
594
+ raise "Failed to update tickets => #{body['details']}" if response.status != 200
595
+ JobStatuses.new(Oj.load(response.body)['job_status'])
596
+ end
597
+
598
+ ##
599
+ # Locates up to 100 tickets within Zendesk.
600
+ #
601
+ # @author Jason Colyer
602
+ # @since 1.0.0
603
+ # @param ticket_ids [Array] The ticket IDs to find
604
+ # @return [Array]
605
+ # @see https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#show-multiple-tickets Zendesk API > Tickets > Show Multiple Tickets
606
+ # @example
607
+ # require 'support_ops_zendesk'
608
+ #
609
+ # SupportOps::Zendesk::Configuration.configure do |config|
610
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
611
+ # config.username = 'jason@example.com'
612
+ # config.token = 'abc123'
613
+ # end
614
+ #
615
+ # tickets = SupportOps::Zendesk::Tickets.get_many([255, 256])
616
+ # pp tickets.map { |t| t.subject }
617
+ # # => ["My printer is on fire!", "Help"]
618
+ def self.get_many(ticket_ids)
619
+ raise 'The parameter must be an Array' unless ticket_ids.is_a? Array
620
+ raise 'You can only get a maximum of 100 tickets at a time' if ticket_ids.count > 100
621
+
622
+ response = client.connection.get("tickets/show_many?ids=#{ticket_ids.join(',')}")
623
+ Oj.load(response.body)['tickets'].map { |t| Tickets.new(t) }
624
+ end
625
+
626
+ ##
627
+ # Lists all non-solved problem tickets
628
+ #
629
+ # @author Jason Colyer
630
+ # @since 1.0.0
631
+ # @return [Array]
632
+ # @see https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-ticket-problems Zendesk API > Tickets > List Ticket Problems
633
+ # @example
634
+ # require 'support_ops_zendesk'
635
+ #
636
+ # SupportOps::Zendesk::Configuration.configure do |config|
637
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
638
+ # config.username = 'jason@example.com'
639
+ # config.token = 'abc123'
640
+ # end
641
+ #
642
+ # problems = SupportOps::Zendesk::Tickets.problem_tickets
643
+ # pp problems.map { |p| p.id }
644
+ # # => [33, 34]
645
+ def self.problem_tickets
646
+ problems = []
647
+ opts = 'page[size]=100'
648
+ loop do
649
+ response = client.connection.get("problems?#{opts}")
650
+ body = Oj.load(response.body)
651
+ problems += body['tickets'].map { |t| Tickets.new(t) }
652
+ break unless body['meta']['has_more']
653
+
654
+ opts = body['links']['next'].split('?').last
655
+ end
656
+ problems
657
+ end
658
+
659
+ ##
660
+ # Marks up to 100 tickets as spam (and suspends the requesters)
661
+ #
662
+ # @author Jason Colyer
663
+ # @since 1.0.0
664
+ # @param ticket_ids [Array] The ticket IDs to find
665
+ # @return [Object]
666
+ # @see
667
+ # https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#bulk-mark-tickets-as-spam
668
+ # Zendesk API > Tickets > Bulk Mark Tickets as Spam
669
+ # @example
670
+ # require 'support_ops_zendesk'
671
+ #
672
+ # SupportOps::Zendesk::Configuration.configure do |config|
673
+ # config.url = 'https://gitlab.zendesk.com/api/v2'
674
+ # config.username = 'jason@example.com'
675
+ # config.token = 'abc123'
676
+ # end
677
+ #
678
+ # spam_tickets = SupportOps::Zendesk::Tickets.mark_many_as_spam!([255, 256])
679
+ # pp spam_tickets.id
680
+ # # => "82de0b044094f0c67893ac9fe64f1a99"
681
+ def self.mark_many_as_spam!(ticket_ids)
682
+ raise 'The parameter must be an Array' unless ticket_ids.is_a? Array
683
+ raise 'You can only mark a maximum of 100 tickets as spam at a time' if ticket_ids.count > 100
684
+
685
+ response = client.connection.put("tickets/mark_many_as_spam?ids=#{ticket_ids.join(',')}")
686
+ raise "Failed to mark many tickets as spam => #{body['details']}" if response.status != 200
687
+ JobStatuses.new(Oj.load(response.body)['job_status'])
688
+ end
689
+
690
+ private
691
+
692
+ ##
693
+ # @private
694
+ def get_record
695
+ response = self.client.connection.get("tickets/#{self.id}")
696
+ return nil if response.status != 200
697
+
698
+ Oj.load(response.body)['ticket']
699
+ end
700
+
701
+ ##
702
+ # @private
703
+ def create_record
704
+ response = self.client.connection.post("tickets", { ticket: attributes_for_save }.to_json)
705
+ body = Oj.load(response.body)
706
+ raise "Failed to create ticket => #{body['details']}" if response.status != 201
707
+ body['ticket']
708
+ end
709
+
710
+ ##
711
+ # @private
712
+ def update_record
713
+ raise "Failed to update ticket => You didn't change anything in the object" if attributes_for_save.keys == [:id]
714
+ response = self.client.connection.put("tickets/#{self.id}", { ticket: attributes_for_save }.to_json)
715
+ body = Oj.load(response.body)
716
+ raise "Failed to update ticket #{self.id} => #{body['details']}" if response.status != 200
717
+ body['ticket']
718
+ end
719
+
720
+ ##
721
+ # @private
722
+ def delete_record
723
+ response = self.client.connection.delete("tickets/#{self.id}")
724
+ raise "Failed to delete ticket => #{body['details']}" if response.status != 204
725
+ true
726
+ end
727
+
728
+ ##
729
+ # @private
730
+ def collaborators_record
731
+ response = self.client.connection.get("tickets/#{self.id}/collaborators")
732
+ Oj.load(response.body)['users'].map { |u| Users.new(u) }
733
+ end
734
+
735
+ ##
736
+ # @private
737
+ def followers_record
738
+ response = self.client.connection.get("tickets/#{self.id}/followers")
739
+ Oj.load(response.body)['users'].map { |u| Users.new(u) }
740
+ end
741
+
742
+ ##
743
+ # @private
744
+ def ccs_record
745
+ response = self.client.connection.get("tickets/#{self.id}/email_ccs")
746
+ Oj.load(response.body)['users'].map { |u| Users.new(u) }
747
+ end
748
+
749
+ ##
750
+ # @private
751
+ def comments_record
752
+ comments = []
753
+ opts = 'page[size]=100'
754
+ loop do
755
+ response = client.connection.get("tickets/#{self.id}/comments?#{opts}")
756
+ body = Oj.load(response.body)
757
+ comments += body['comments'].map { |c| Comments.new(c) }
758
+ break unless body['meta']['has_more']
759
+
760
+ opts = body['links']['next'].split('?').last
761
+ end
762
+ comments
763
+ end
764
+
765
+ ##
766
+ # @private
767
+ def mark_as_spam_record
768
+ response = client.connection.put "tickets/#{self.id}/mark_as_spam"
769
+ raise "Failed to mark ticket #{self.id} as spam => #{body['details']}" if response.status != 200
770
+ true
771
+ end
772
+
773
+ ##
774
+ # @private
775
+ def incidents_record
776
+ tickets = []
777
+ opts = 'page[size]=100'
778
+ loop do
779
+ response = client.connection.get("tickets/#{self.id}/incidents?#{opts}")
780
+ body = Oj.load(response.body)
781
+ tickets += body['tickets'].map { |c| Tickets.new(c) }
782
+ break unless body['meta']['has_more']
783
+
784
+ opts = body['links']['next'].split('?').last
785
+ end
786
+ tickets
787
+ end
788
+
789
+ ##
790
+ # @private
791
+ def redact_attachments_record
792
+ redactions = []
793
+ self.comments.each do |c|
794
+ object = {
795
+ id: c.id,
796
+ redaction: { ticket_id: self.id }
797
+ }
798
+ object[:redaction][:external_attachment_urls] = c.attachments.map { |a| a['content_url'] } unless c.attachments.count.zero?
799
+ object[:redaction][:html_body] = c.html_body.gsub('<img', '<img redact') if c.html_body =~ /<img/
800
+ redactions.push(object) unless object[:redaction][:external_attachment_urls].nil? && object[:redaction][:html_body].nil?
801
+ end
802
+ redactions.each do |r|
803
+ client.connection.put "comment_redactions/#{r[:id]}", r[:redaction].to_json
804
+ end
805
+ true
806
+ end
807
+
808
+ ##
809
+ # @private
810
+ def organization_record
811
+ return nil if self.organization_id.nil?
812
+
813
+ Organizations.get(self.organization_id)
814
+ end
815
+
816
+ ##
817
+ # @private
818
+ def create_satisfaction_score_record(**args)
819
+ raise 'You have to provide a score' unless args[:score]
820
+ raise "Invalid score provided: #{args[:score]}" unless %w[good bad].include?(args[:score])
821
+ raise 'You have to provide a comment' unless args[:comment]
822
+ data = { satisfaction_rating: { score: args[:score], comment: args[:comment] }}.to_json
823
+ response = client.connection.post("tickets/#{self.id}/satisfaction_rating", data)
824
+ body = Oj.load(response.body)
825
+ raise "Unable to add satisfaction score to ticket #{self.id} => #{body}" if response.status != 200
826
+ body['satisfaction_rating']
827
+ end
828
+
829
+ ##
830
+ # @private
831
+ def web_url_record
832
+ raise 'You cannot have a web URL for a non-existant ticket' if self.id.nil?
833
+ self.client.connection.url_prefix.to_s.gsub('api/v2', 'agent/tickets/') + self.id.to_s
834
+ end
835
+ end
836
+ end
837
+ end