Created
September 30, 2014 16:38
-
-
Save foeken/018bbb5c1e482a9cf95b to your computer and use it in GitHub Desktop.
A crude Github - Zendesk syncer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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