Расширяем Zendesk с помощью Zendesk App, API на Ruby on Rails и технологии CORS

В одном из наших проектов используется сервис Zendesk, обрабатывающий пользовательские отзывы. С его помощью пользователи сообщают о проблемах, предлагают новый функционал, отзываются о работе проекта. Вся база тикетов хранится на стороне Zendesk, в нём же продублирована основная информация о пользователях (email, name, user_id). Сотрудники нашей техподдержки имеют доступ ко всем тикетам и пользователям на страничке our-subdomain.zendesk.com.

Zendesk access to tickets and users

После подключения сервиса Zendesk к проекту и получения первых отзывов, у сотрудников нашей техподдержки появились пожелания по усовершенствованию данного сервиса. А именно – неплохо было бы видеть на странице пользователя актуальную информацию о нём из нашей базы и иметь ссылки для быстрого перехода к его профилю в нашем приложении. Также, на страничке тикета хотелось бы видеть информацию о его создателе (в таком же виде как и на страничке пользователя).

Для реализации задуманного было решено написать собственное Zendesk App. Это приложение отображает на пользовательской странице (и на странице тикета) в Zendesk информацию о том, чем за последний год пользователь интересовался, какими услугами пользовался. Отображаются и различные ссылки на наш сайт для быстрого доступа к профилю этого пользователя и т.п. Все эти данные Zendesk не позволяет хранить на его стороне. Поэтому было решено создать API действие (action), которое будет отдавать эти данные в JSON формате. Zendesk App будет ходить на этот action, получать информацию о пользователе и отображать её в Zendesk на страничках пользователя и его тикетов.

После реализации API action'a у нас появился URL вида https://our-domain/api/admin/zendesk/:id.json, по которому можно получить данные о интересующем нас пользователе (предварительно войдя в систему администратором). Примерный ответ сервера:

{"user":{"id":123, name:John Doe, link:https://our-domain/user/profile/link, ...}}

Теперь создаем Zendesk App пользуясь инструкцией. В app.js настраиваем запрос, который будет ходить на наше API и получать данные о пользователе:

    requests: {
      getUserData: function() {
        var id = this.user().externalId(); # this.user() - объект открытого пользователя на Zendesk, externalId - его id в нашей базе
        return {
          url: 'https://our-domain/api/admin/zendesk/' + id,
          type: 'GET',
          dataType: 'json'
        };
      }
    }

После всех настроек появилось базовое Zendesk App, которое можно загрузить на Zendesk, пользуясь инструкцией. После загрузки открываем страничку пользователя на Zendesk и видим, что информация о пользователе в Zendesk App не отображается. Открываем консоль браузера и обнаруживаем там ошибку:

XMLHttpRequest cannot load https://our-domain/api/admin/zendesk/123. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://our-subdomain.zendesk.com' is therefore not allowed access.

Эта ошибка говорит о том, что мы пытаемся послать XHR-запрос не на тот домен, на котором находимся в данный момент. Поэтому браузер блокирует этот запрос по соображениям безопасности. Для решения этой проблемы мы использовали технологию CORS. Чтобы использовать эту технологию, необходимо настроить клиент Zendesk App и наш сервер, написанный на Ruby on Rails. Zendesk App настраивается добавлением таких строчек в конфигурацию запроса:

    requests: {
      getUserData: function() {
        var id = this.user().externalId();
        return {
          url: 'https://our-domain/api/admin/zendesk/' + id,
          type: 'GET',
          dataType: 'json',
          cors: true,
          xhrFields: { withCredentials: true }
        };
      }
    }

Теперь настроим наш сервер. Для этого добавим в контроллер before_action:

  before_action :set_cors_headers

  private

  def set_cors_headers
    headers['Access-Control-Allow-Origin'] = 'https://our-subdomain.zendesk.com'
    headers['Access-Control-Allow-Credentials'] = 'true'
  end

В этих двух строчках происходит следующее:

  • HTTP-заголовок Access-Control-Allow-Origin указывает нашему серверу на XHR запросы с каких доменов он уполномочен отвечать. Мы прописали там наш домен на Zendesk. На XHR запросы с других доменов сервер будет отвечать ошибкой, которую мы видели в консоли своего браузера.
  • Второй HTTP-заголовок Access-Control-Allow-Credentials разрешает перечисленным выше доменам пользоваться cookies из браузера пользователя. Т.е. теперь когда Zendesk App будет посылать запрос на наше API и в заголовке указывать свой Origin, сервер будет корректно отвечать на такие запросы.

Разворачиваем наши изменения на production-сервер, выгружаем новую версию Zendesk App и снова проверяем страничку пользователя на Zendesk. Та-дам! Справа на боковой панели видим результат своего труда – появилась вся дополнительная информация о пользователе, полученная из нашего API.

Our Zendesk App

Таким образом, мы расширили возможности Zendesk, реализовав Zendesk App. И сотрудники техподдержки были весьма признательны за столь удобное и полезное дополнение к сервису Zendesk.

Связаться