Skip to content

Instantly share code, notes, and snippets.

@foeken
Created September 30, 2014 16:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foeken/018bbb5c1e482a9cf95b to your computer and use it in GitHub Desktop.
Save foeken/018bbb5c1e482a9cf95b to your computer and use it in GitHub Desktop.
A crude Github - Zendesk syncer
class Zendesk
ENDPOINT = "https://[DOMAIN].zendesk.com/api/v2"
USER = "[YOUR_USER_NAME]"
USER_ID = 0 #[YOUR_USER_ID]
TARGET_VIEW = 0 #[VIEW_ID]
BODY_FIELD_ID = 0 # [CUSTOM_BODY_FIELD_ID], We use an internal body
REPO_NAME_FIELD_ID = 0 #[REPO_NAME_FIELD_ID], We use a selectbox
GITHUB_FIELD_ID = 0 #[GITHUB_FIELD_ID], We use a checkbox
def self.api
Rails.logger.debug "Initializing Zendesk API client"
ZendeskAPI::Client.new do |config|
config.url = ENDPOINT
config.username = USER
config.token = Rails.application.config.zendesk_secret
end
end
def self.tickets_in_target_view
Rails.logger.debug "Gathering Zendesk tickets in target view"
api.views.find(id: TARGET_VIEW).tickets(include: 'users')
end
def self.sync
Rails.logger.debug "Starting Github - Zendesk sync process"
tickets_in_target_view.each do |ticket|
assignee_name = ticket.assignee.name
subject = ticket.subject
body = ticket.custom_fields.detect{ |cf| cf.id == BODY_FIELD_ID }.value
repo_name = ticket.custom_fields.detect{ |cf| cf.id == REPO_NAME_FIELD_ID }.value
github = ticket.custom_fields.detect{ |cf| cf.id == GITHUB_FIELD_ID }.value
open = ticket.status == "open"
external_id = !!ticket.external_id
repo = "[ORGANISATION]/#{repo_name}"
if external_id
number = ticket.external_id.split('@').first
change_set = changes_from_ticket(ticket)
if any_changes?(change_set)
update_github_issue(repo, number, subject, body, assignee_name, ticket.id) if any_issue_changes?(change_set)
change_set.comments.each { |comment| create_github_comment(comment) }
update_zendesk_external_id(ticket, number)
else
Rails.logger.debug "No changes for ticket ##{ticket.id}"
end
else
issue = create_github_issue(repo, subject, body, assignee_name, ticket.id)
update_zendesk_external_id(ticket, issue.number)
end
end
nil
end
def self.any_changes? change_set
!!change_set.body || !!change_set.subject || !!change_set.assignee || change_set.comments.present?
end
def self.any_issue_changes? change_set
!!change_set.body || !!change_set.subject || !!change_set.assignee
end
def self.changes_from_ticket ticket
Rails.logger.debug "Determining changeset for ticket ##{ticket.id}"
timestamp = DateTime.parse(ticket.external_id.split('@').last)
changes = OpenStruct.new( assignee: nil, subject: nil, body: nil, comments: [])
ticket.audits.each do |audit|
if audit.created_at > timestamp
audit.events.each do |event|
case event.type
when "Comment"
if event.author_id != USER_ID
changes.comments << { body: event.body,
attachments: event.attachments.map{ |a| { file_name: a.file_name,
url: a.content_url } } }
end
when "Change"
case event.field_name
when "subject"
changes.subject = event.value
when body_field_id.to_s
changes.body = event.value
when "assignee_id"
changes.assignee = event.value
end
end
end
end
end
return changes
end
def self.create_github_comment repo, number, comment
Rails.logger.debug "Creating comment on #{repo} ##{number}"
body = comment[:body]
comment[:attachments].each do |a|
body += "\n\n[#{a[:file_name]}](#{a[:url]})"
end
Octokit.add_comment repo, number, body
end
def self.update_zendesk_external_id ticket, number
Rails.logger.debug "Updating Zendesk external id for ticket ##{ticket.id}"
ticket.external_id = "#{number}@#{DateTime.now}"
ticket.save
end
def self.update_github_issue repo, number, subject, body, assignee_name, ticket_id
Rails.logger.debug "Updating Github issue ##{number} on #{repo} with new values"
body = github_issue_body(body, assignee_name, ticket_id)
Octokit.update_issue repo, number, subject, body, labels: ["zendesk"]
end
def self.create_github_issue repo, subject, body, assignee_name, ticket_id
Rails.logger.debug "Creating new Github issue on #{repo}"
body = github_issue_body(body, assignee_name, ticket_id)
Octokit.create_issue repo, subject, body, labels: ["zendesk"]
end
def self.github_issue_body body, assignee_name, ticket_id
body + "\n\n#{assignee_name} (ZD##{ticket.id})"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment