Example #1
0
 def create_ticket(self, user, ticket_fields):
     """Create a ticket in Zendesk."""
     ticket = Ticket(
         subject=ticket_fields.get("subject"),
         comment={"body": ticket_fields.get("description")},
         ticket_form_id=settings.ZENDESK_TICKET_FORM_ID,
         custom_fields=[
             {
                 "id": settings.ZENDESK_PRODUCT_FIELD_ID,
                 "value": ticket_fields.get("product")
             },
             {
                 "id": settings.ZENDESK_CATEGORY_FIELD_ID,
                 "value": ticket_fields.get("category")
             },
             {
                 "id": settings.ZENDESK_OS_FIELD_ID,
                 "value": ticket_fields.get("os")
             },
             {
                 "id": settings.ZENDESK_COUNTRY_FIELD_ID,
                 "value": ticket_fields.get("country")
             },
         ],
     )
     if user.profile.zendesk_id:
         # TODO: is this necessary if we're updating users as soon as they're updated locally?
         ticket.requester_id = self.update_user(user).id
     else:
         ticket.requester_id = self.create_user(user).id
     return self.client.tickets.create(ticket)
    def migrate_ticket(self, source, status_to_migrate='all'):

        end_time = 'N/A'
        try:
            end_time = source.generated_timestamp
        except AttributeError:
            pass

        if source.status == 'deleted':
            print('Skipping deleted ticket: %s (timestamp: %s)' % (source.id, end_time))
            return 0

        if (not status_to_migrate == 'all' and not status_to_migrate == 'not_closed' and
            not source.status == status_to_migrate) or \
                (status_to_migrate == 'not_closed' and source.status == 'closed'):
            print('Skipping, ticket status is %s: %s (timestamp: %s)' %
                  (source.status, source.id, end_time))
            return 0

        # Look for an existing ticket
        existing = self.find_target_ticket_for_original_id(source.id)
        if existing:
            # Existing tickets will be updated with the events API
            print('Existing ticket found for %s (timestamp: %s)' % (source.id, end_time))
            return existing.id

        print('Migrating ticket %s - %s' % (source.id, source.subject))

        ticket = Ticket(created_at=source.created_at,
                        updated_at=source.updated_at,
                        subject=source.subject,
                        priority=source.priority,
                        type=source.type,
                        status=source.status,
                        tags=source.tags,
                        recipient=source.recipient,
                        brand_id=self.get_target_brand_id(source.brand_id))

        if source.ticket_form_id:
            ticket.ticket_form_id = self.get_target_ticket_form_id(source.ticket_form_id)

        # Organization
        org_id = source.organization_id
        if org_id:
            new_org_id = self.get_target_org_id(org_id)
            if new_org_id:
                ticket.organization_id = new_org_id

        # Collaborators
        collab_ids = source.collaborator_ids
        new_collab_ids = []
        for collab_id in collab_ids:
            new_collab_ids.append(self.get_target_user_id(collab_id))

        ticket.collaborator_ids = new_collab_ids

        # Custom fields
        source_fields = source.custom_fields
        custom_fields = {}
        for field in source_fields:
            custom_fields[self.get_target_ticket_field_id(field.get('id'))] = field.get('value')
        custom_fields[self.original_id_field] = source.id
        ticket.custom_fields = custom_fields

        # Comments
        comments = self.source_client.tickets.comments(source)
        new_comments = []

        for comment in comments:
            new_comment = Comment(created_at=comment.created_at,
                                  html_body=comment.html_body,
                                  public=comment.public,
                                  metadata=comment.metadata)

            # Author
            author_id = comment.author_id
            new_comment.author_id = self.get_target_user_id(author_id)

            # Inline Attachments
            comment_body = comment.html_body
            uploads = []
            matches = re.findall(self.HTML_IMG_TAG_PATTERN, comment_body)
            if len(matches) > 0:

                for match in matches:
                    img_tag = match[0]
                    url = match[1]

                    print('- Found src url in comment: %s' % url)

                    do_upload = False
                    source_domain = '%s.zendesk.com' % self.SOURCE_INSTANCE
                    source_alt_domain = '%s.zendesk.com' % self.SOURCE_ALT_INSTANCE
                    if source_domain in url or source_alt_domain in url:
                        do_upload = True
                        url = url.replace(source_alt_domain, source_domain)
                    elif self.SOURCE_HELPCENTER_DOMAIN in url:
                        do_upload = True

                    if do_upload:
                        response = requests.get(url, auth=self.source_auth)

                        if not response.status_code == 200:
                            print('- ERROR getting attachment %s: %s' % (url, response.status_code))
                            continue

                        file_name = 'attachment'
                        content_disp = response.headers.get('content-disposition')
                        if content_disp:
                            file_name_match = re.search('inline; filename=\"(.*)\"', content_disp)
                            if file_name_match:
                                file_name = file_name_match.group(1)
                            else:
                                continue
                        content_type = response.headers.get('content-type')

                        if self.DEBUG:
                            print('- DEBUG Attachment created - %s' % file_name)
                            comment_body = comment_body.replace(img_tag, '<See Attachment>')
                        else:
                            with tempfile.TemporaryFile() as tmp_file:
                                tmp_file.write(response.content)
                                tmp_file.seek(0)
                                try:
                                    upload = self.target_client.attachments.upload(fp=tmp_file,
                                                                                   target_name=file_name,
                                                                                   content_type=content_type)

                                    print('- Attachment created - %s' % file_name)
                                    comment_body = comment_body.replace(img_tag, '[See Attachment]')
                                    uploads.append(upload.token)

                                except Exception as e:
                                    print('WARN Exception creating attachment %s - %s' % (file_name, e))

                new_comment.html_body = comment_body

            # Non-inline Attachments
            attachments = comment.attachments
            if attachments and len(attachments) > 0:
                for attachment in attachments:
                    url = attachment.content_url
                    file_name = attachment.file_name
                    content_type = attachment.content_type
                    response = requests.get(url)

                    if self.DEBUG:
                        print('- DEBUG Attachment created - %s' % file_name)
                    else:
                        with tempfile.TemporaryFile() as tmp_file:
                            tmp_file.write(response.content)
                            tmp_file.seek(0)
                            try:
                                upload = self.target_client.attachments.upload(fp=tmp_file,
                                                                               target_name=file_name,
                                                                               content_type=content_type)

                                print('- Attachment created - %s' % file_name)
                                uploads.append(upload.token)

                            except Exception as e:
                                print('WARN Exception creating attachment %s - %s' % (file_name, e))

            new_comment.uploads = uploads

            new_comments.append(new_comment)

        ticket.comments = new_comments

        # Submitter
        ticket.submitter_id = self.get_target_user_id(source.submitter_id)

        # Requestor
        requester_id = source.requester_id
        if requester_id:
            requester = self.get_target_user(requester_id)
            if requester:
                if requester.suspended:
                    # End-users can't be assigned tickets
                    comment = Comment(body='Requester was %s (suspended)' % requester.name,
                                      public=False)
                    ticket.comments.append(comment)
                else:
                    ticket.requester_id = requester.id

        # Assignee
        assignee_id = source.assignee_id
        group_id = source.group_id
        if assignee_id:
            assignee = self.get_target_user(assignee_id)
            if assignee:
                if assignee.role == 'end-user':
                    # End-users can't be assigned tickets
                    comment = Comment(body='Assignee was %s (suspended)' % assignee.name,
                                      public=False)
                    ticket.comments.append(comment)
                else:
                    ticket.assignee_id = assignee.id
        elif group_id:
            ticket.group_id = self.get_target_group_id(group_id)

        # Linked source/problem_id
        source_problem_id = source.problem_id
        if source_problem_id:
            problem_ticket = self.find_target_ticket_for_original_id(source_problem_id)
            if problem_ticket:
                if problem_ticket.type == 'problem':
                    print('- Linking existing problem ticket for %s' % source_problem_id)
                    ticket.problem_id = problem_ticket.id
                else:
                    # Can't link them
                    comment = Comment(body='Linked ticket %s is not a problem, could not link' % problem_ticket.id,
                                      public=False)
                    ticket.comments.append(comment)
            else:
                # Migrate the problem ticket
                if self.DEBUG:
                    print('- DEBUG Problem ticket not found, creating for %s' % source_problem_id)
                else:
                    print('- Problem ticket not found, creating for %s' % source_problem_id)
                    source_problem = self.source_client.tickets(id=source_problem_id)
                    ticket.problem_id = self.migrate_ticket(source_problem)
                    # Wait 60 sec for this to show up
                    time.sleep(60)

        new_ticket_id = None
        if self.DEBUG:
            print('- DEBUG Successfully migrated ticket %s to %s (timestamp: %s)' %
                  (source.id, new_ticket_id, end_time))
        else:
            new_ticket_id = self.target_client.ticket_import.create(ticket)
            print('- Successfully migrated ticket %s to %s (timestamp: %s)' % (source.id, new_ticket_id, end_time))

        return new_ticket_id