Completed
Push — master ( 2ff59b...e8011e )
by John
01:15
created

Zendesk.escalated_tickets()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
1
require 'base64'
2
require 'faraday'
3
require 'faraday_middleware'
4
5
require 'pp'
6
7
module Lita
8
  module Handlers
9
    class Zendesk < Handler
10
11
      VERSION_URL = 'api/v2'
12
      QUERY_SEARCH_PREFIX = 'search.json?query='
13
      QUERY_TICKETS_SEARCH = 'search.json?query=type:ticket '
14
      QUERY_TICKETS_ALL = 'tickets'
15
      QUERY_TICKETS_ESCALATED = 'search.json?query=tags:escalated+status:open+status:pending+type:ticket'
16
      QUERY_TICKETS_HOLD = 'search.json?query=status:hold+type:ticket'
17
      QUERY_TICKETS_OPEN = 'search.json?query=status:open+type:ticket'
18
      QUERY_TICKETS_NEW = 'search.json?query=status:new+type:ticket'
19
      QUERY_TICKETS_PENDING = 'search.json?query=status:pending+type:ticket'
20
      QUERY_TICKETS_UNSOLVED = 'search.json?query=status<solved+type:ticket'
21
      QUERY_USERS = 'users'
22
23
      config :use_command, types: [TrueClass, FalseClass], default: true
24
25
      config :subdomain, type: String, required: true
26
      config :auth_type, type: String, default: 'password' # or token
27
      config :user, type: String, required: true
28
      config :token, type: String, default: ''
29
      config :password, type: String, default: ''
30
31
      def check_client(reload = false)
32
        return if @conn && !reload
33
        @base_url = base_url
34
        @version_url = "#{@base_url}/#{VERSION_URL}"
35
        @tickets_url = "#{@base_url}/tickets"
36
37
        if config.auth_type == 'password'
38
          @conn = Faraday.new(url: @version_url) do |faraday|
39
            faraday.headers['Authorization'] = "Basic #{basic_credentials}"
40
            faraday.response :json                    # JSON response
41
            faraday.response :logger                  # log requests to STDOUT
42
            faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
43
          end
44
        else
45
          @conn = Faraday.new(url: @version_url) do |faraday|
46
            faraday.response :json                    # JSON response
47
            faraday.response :logger                  # log requests to STDOUT
48
            faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
49
          end
50
          @conn.basic_auth("#{config.user}/token", config.token) 
51
        end
52
      end
53
54
      def base_url
55
        "https://#{config.subdomain.to_s}.zendesk.com"
56
      end
57
58
      def basic_credentials
59
        Base64.encode64("#{config.user}:#{config.password}").gsub(/\s/,'')
60
      end
61
62
      def zendesk_request(url)
63
        check_client
64
        if url.index('http') != 0
65
          url = "#{@version_url}/#{url}"
66
        end
67
        @conn.get url
68
      end
69
70
      # General
71
72
      route(/^(?:zd|zendesk)\s+connection\s*$/i, :zd_instance_info, command: true, help: { 'zd connection' => 'returns information on the Zendesk connection' })
73
      def zd_instance_info(response)
74
        response.reply "Using Zendesk instance at: #{base_url}"
75
      end
76
77
      route(/^(?:zd|zendesk)\s+search\s+tickets?\s+(\S.*?)\s*$/i, :search_tickets, command: true, help: { 'zd search tickets <QUERY>' => 'returns search results' })
78
      def search_tickets(response)
79
        ticket_search response, QUERY_TICKETS_SEARCH, response.matches[0][0]
80
      end
81
82
      # Ticket Counts
83
84
      route(/^(?:zd|zendesk)(\s+unsolved)?\s+tickets?\s*$/i, :unsolved_tickets, command: true, help: { 'zd tickets' => 'returns the total count of all unsolved tickets' })
85
      def unsolved_tickets(response)
86
        ticket_count response, QUERY_TICKETS_UNSOLVED, 'unsolved'
87
      end
88
89
      route(/^(?:zd|zendesk)\s+(all|total)\s+tickets?\s*$/i, :total_tickets, command: true, help: { 'zd all tickets' => 'returns the count of all tickets' })
90
      def total_tickets(response)
91
        ticket_count response, QUERY_TICKETS_ALL, 'total'
92
      end
93
94
      route(/^(?:zd|zendesk)\s+pending\s+tickets?\s*$/i, :pending_tickets, command: true, help: { 'zd pending tickets' => 'returns a count of tickets that are pending' })
95
      def pending_tickets(response)
96
        ticket_count response, QUERY_TICKETS_PENDING, 'pending'
97
      end
98
99
      route(/^(?:zd|zendesk)\s+new\s+tickets?\s*$/i, :new_tickets, command: true, help: { 'zd new tickets' => 'returns the count of all new (unassigned) tickets' })
100
      def new_tickets(response)
101
        ticket_count response, QUERY_TICKETS_NEW, 'new'
102
      end
103
104
      route(/^(?:zd|zendesk)\s+escalated\s+tickets?\s*$/i, :escalated_tickets, command: true, help: { 'zd escalated tickets' => 'returns a count of tickets with escalated tag that are open or pending' })
105
      def escalated_tickets(response)
106
        ticket_count response, QUERY_TICKETS_ESCALATED, 'escalated'
107
      end
108
109
      route(/^(?:zd|zendesk)\s+open\s+tickets?\s*$/i, :open_tickets, command: true, help: { 'zd open tickets' => 'returns the count of all open tickets' })
110
      def open_tickets(response)
111
        ticket_count response, QUERY_TICKETS_OPEN, 'open'
112
      end
113
114
      route(/^(?:zd|zendesk)\s+on\s+hold\s+tickets?\s*$/i, :onhold_tickets, command: true, help: { 'zd on hold tickets' => 'returns the count of all on hold tickets' })
115
      def onhold_tickets(response)
116
        ticket_count response, QUERY_TICKETS_HOLD, 'on hold'
117
      end
118
119
      # Ticket Lists
120
121
      route(/^(?:zd|zendesk)\s+list(\s+unsolved)?\s+tickets?\s*$/i, :unsolved_tickets_list, command: true, help: { 'zd list tickets' => 'returns a list of unsolved tickets' })
122
      def unsolved_tickets_list(response)
123
        ticket_list response, QUERY_TICKETS_UNSOLVED, 'unsolved'
124
      end
125
126
      route(/^(?:zd|zendesk)\s+list\s+(all|total)\s+tickets?\s*$/i, :total_tickets_list, command: true, help: { 'zd list all tickets' => 'returns a list of all tickets' })
127
      def total_tickets_list(response)
128
        ticket_list response, QUERY_TICKETS_ALL, 'total'
129
      end
130
131
      route(/^(?:zd|zendesk)\s+list\s+pending\s+tickets?\s*$/i, :pending_tickets_list, command: true, help: { 'zd list pending tickets' => 'returns a list of pending tickets' })
132
      def pending_tickets_list(response)
133
        ticket_list response, QUERY_TICKETS_PENDING, 'pending'
134
      end
135
136
      route(/^(?:zd|zendesk)\s+list\s+new\s+tickets?\s*$/i, :new_tickets_list, command: true, help: { 'zd list new tickets' => 'returns a list of new tickets' })
137
      def new_tickets_list(response)
138
        ticket_list response, QUERY_TICKETS_NEW, 'new'
139
      end
140
141
      route(/^(?:zd|zendesk)\s+list\s+escalated\s+tickets?\s*$/i, :escalated_tickets_list, command: true, help: { 'zd list esclated tickets' => 'returns a list of escalated tickets' })
142
      def escalated_tickets_list(response)
143
        ticket_list response, QUERY_TICKETS_ESCALATED, 'escalated'
144
      end
145
146
      route(/^(?:zd|zendesk)\s+list\s+open\s+tickets?\s*$/i, :open_tickets_list, command: true, help: { 'zd list open tickets' => 'returns a list of open tickets' })
147
      def open_tickets_list(response)
148
        ticket_list response, QUERY_TICKETS_OPEN, 'open'
149
      end
150
151
      route(/^(?:zd|zendesk)\s+list\s+on\s+hold\s+tickets?\s*$/i, :onhold_tickets_list, command: true, help: { 'zd list onhold tickets' => 'returns a list of on hold tickets' })
152
      def onhold_tickets_list(response)
153
        ticket_list response, QUERY_TICKETS_HOLD, 'on hold'
154
      end
155
156
      # Ticket Details
157
158
      route(/^(?:zd|zendesk)\s+ticket\s+(\d+)\s*$/i, :ticket_details, command: true, help: { 'zd ticket <ID>' => 'returns information about the specified ticket' })
159
      def ticket_details(response)
160
        Lita.logger.info "#{logger_prefix}Processing Zendesk Ticket Details"
161
        ticket_id = response.matches[0][0]
162
        url = "#{QUERY_TICKETS_ALL}/#{ticket_id}.json"
163
        res = zendesk_request url
164
        data = res.body
165
166
        message = "Ticket #{data['ticket']['id']}: #{@tickets_url}/#{data['ticket']['id']}"
167
        message += "\nStatus: #{data['ticket']['status'].upcase}"
168
        message += "\nUpdated: " + data['ticket']['updated_at']
169
        message += "\nAdded: #{data['ticket']['created_at']}"
170
        message += "\nSubject: #{data['ticket']['subject']}"
171
        message += "\nDescription:\n-----\n#{data['ticket']['description']}\n-----\n"
172
        response.reply message
173
      end
174
175
      private
176
177
      def ticket_count(response, url, ticket_type = '')
178
        Lita.logger.info "#{logger_prefix}Processing Zendesk Ticket Count"
179
        res = zendesk_request url
180
        ticket_count = res.body['count']
181
        ticket_word  = ticket_count == 1 ? 'ticket' : 'tickets'
182
        ticket_desc  = ticket_type == '' ? '' : "#{ticket_type} "
183
        response.reply "#{ticket_count} #{ticket_desc}#{ticket_word}."
184
      end
185
186
      def ticket_search(response, url, query)
187
        Lita.logger.info "#{logger_prefix}Processing Zendesk Ticket Search"
188
        url += query
189
        res = zendesk_request url
190
        tickets = res.body['results']
191
        tickets.each do |ticket|
192
          response.reply "Ticket #{ticket['id']} is #{ticket['status']}: #{@tickets_url}/#{ticket['id']} - #{ticket['subject']}"
193
        end
194
        ticket_length = tickets.length
195
        ticket_count = res.body['count']
196
        ticket_word  = ticket_count == 1 ? 'result' : 'results'
197
        response.reply "Listing #{ticket_length} of #{ticket_count} matching #{ticket_word}."
198
      end
199
200
      def ticket_list(response, url, ticket_type = '')
201
        Lita.logger.info "#{logger_prefix}Processing Zendesk Ticket List"
202
        res = zendesk_request url
203
        tickets = res.body['results']
204
        tickets.each do |ticket|
205
          response.reply "Ticket #{ticket['id']} is #{ticket['status']}: #{@tickets_url}/#{ticket['id']} - #{ticket['subject']}"
206
        end
207
        ticket_length = tickets.length
208
        ticket_count = res.body['count']
209
        ticket_word  = ticket_count == 1 ? 'ticket' : 'tickets'
210
        ticket_desc  = ticket_type == '' ? '' : "#{ticket_type} "
211
        response.reply "Listing #{ticket_length} of #{ticket_count} #{ticket_desc}#{ticket_word}."
212
      end
213
214
      def tickets(count)
215
        count == 1 ? 'ticket' : 'tickets'
216
      end
217
218
      def logger_prefix
219
        " -- #{self.class.name}: "
220
      end
221
    end
222
223
    Lita.register_handler(Zendesk)
224
  end
225
end