Продуктивность уверенно входит в топ трендов последних лет и является еще более востребованным в 2016ом, причем включая в себя такие направления как Collaborative Software, Smart Virtual Personal Assistants,Bots и многие другие…
В данной статье мы расскажем о том, как компания Wrike расширила свое решение и реализовала Add-In для Office, а так же поделимся опытом его разработки.
Хочу поблагодарить за подготовку статьи Аркадия Рушкевича (Ведущий менеджер продукта) и Владимира Дупелева (Руководитель группы разработки ПО)

Недавно сервис для управления проектами Wrike анонсировал сразу несколько интеграций с продуктами Microsoft. Теперь можно авторизоваться в сервисе с корпоративным логином Azure Active Directory, добавлять в задачи файлы из OneDrive для бизнеса и установить дополнение Wrike в Office 365.

Последнее — пожалуй, самое важное с точки зрения продуктивности на рабочем месте. Мы решили рассказать о том, зачем системе управления проектами понадобилась интеграция с офисными приложениями, и поделиться опытом разработки надстройки для Office.



Продуктивная связка


Wrike на очень конкурентном рынке смог сделать своими клиентами более 10 000 компаний, включая PayPal и HTC. Сервис выделяется, прежде всего, особым вниманием к совместной работе. Он рассчитан не только на менеджеров проектов, но и исполнителей. Пользователи могут вести обсуждения прямо под задачами, одновременно редактировать тексты, «призывать» коллег в дискуссию упоминанием вида @имя_сотрудника, подписываться на ленту новостей отдела, проекта и т. д.

Другая особенность — в отличие от ряда других систем, Wrike не проповедует полного отказа от традиционных рабочих инструментов: email, мессенджеров, файловых хранилищ, онлайн-редакторов и т. д. и переноса всей совместной рабочей активности и контента в новую систему. Это возможно, но не обязательно. Вместо этого пользователи могут использовать многочисленные интеграции и дополнения, предлагаемые Wrike, для комфортной работы с привычными приложениями без лишних переключений между ними. Сам сервис в этом случае выступает как связующий хаб, где ведется планирование и мониторинг проектов, а также координация командной работы над задачами.

Учитывая эти особенности Wrike, интеграция с таким распространенным решением, как Office 365, напрашивалась сама собой. Основная идея заключается в создании прямого «канала связи» между индивидуальными инструментами пользователя, такими как Word и PowerPoint и командным сервисом для планирования работы.

Дополнение для Office 365 позволило пользователям прямо из офисных приложений загружать документы и презентации в Wrike, не переключаясь между окнами, вкладками и поиском файлов. Там в Wrike документ можно добавить к создаваемой или уже существующей задаче. Например, PR-менеджер, получив задачу написать пресс-релиз, может сделать это в Word, сразу приложить готовый документ к задаче в Wrike и назначить следующим исполнителем менеджера по email-маркетингу для рассылки по журналистам.

Также прямо из Office 365 можно изменить описание, статус и сроки задач, просматривать и добавлять комментарии к ним. Это позволяет сэкономить рабочее время, которое тратилось на рутину, и делает коммуникации внутри команды прозрачнее.


Технические подробности


Надстройка (add-in) для Office 365 представляет собой веб-приложение, открываемое в боковой панели офисного приложения, с доступом к документу и функциям через Office 365 JS API. Выглядит заманчиво и просто для реализации, но и сроки ввиду загруженности разработчиков у нас были очень сжатые – на все про все полтора месяца. Впрочем, предварительные оценки показывали, что разработать и запустить приложение в такие сроки с учетом возможностей инфраструктуры Office 365 реально. Дьявол оказался в деталях, но об этом позже.

Надстройка практически полностью расположена в Вебе. Локально (если это слово применимо к Office Online) загружается только манифест, представляющий собой XML-файл с информацией об адресе веб-приложения, а также дополнительные сведения, такие как набор совместимых приложений Office, версия, ссылка на favicon и т.д. Приложение открывается как iframe в Office Online и нативных приложениях Office для iOS и Android, и как независимое окно встроенного браузера в Office 2013/2016.

Такая «архитектура» определила и среду разработки. Wrike написан, в основном, на Dart с использованием Project Polymer. Его же использовали для нашей надстройки для Office 365. Это позволило переиспользовать значительную часть кода, а также писать не автономное приложение, работающее с Wrike через API, а альтернативное веб-представление основной системы. Microsoft Visual Studio использовалась только для написания и валидации манифеста (для этой цели вполне подходит Community Edition). Все остальное — традиционно в Webstorm.

P3P-сертификация


Для успешной работы приложения нужно было получать и принимать cookie с аттрибутом secure. В браузерах internet explorer 10, 11 и Edge до сих пор используется информация специальных p3p-заголовков, разрешающая сохранение и отправку любых cookie, и особенно обрабатывается случай с secure cookie (www.w3.org/Protocols/rfc2109/rfc2109, аттрибут “secure”).

О том, как подключить к проекту цифровую версию политик безопасности и данных об обрабатываемой и хранимой пользовательской информации (p3p), рассказывается на сайте W3C. Без поддержки p3p-протокола сайт будет выполнятся в песочнице. Соответствующие ограничения накладывает зона «Опасные Сайты», запрещая сохранение и передачу cookies.

Артефакты p3p-протокола — это разводящий файл манифеста (p3p.xml), сам манифест, описывающий политику безопасности и работы с данными вашего сайта в машиночитаемом формате (обычно policy1.xml), а также сокращенный вариант описанной политики. Его можно использовать в заголовке, возвращаемом при каждом запросе (трехбуквенные комбинации, описывающие различные политики).

Сложности начинаются с того момента, что в пункте 3 документации W3C перечислены инструменты, страницы которых уже не открываются, и почти не возможно найти бесплатный визард по созданию policy.xml. При заполнении манифеста вручную необходимо понять, какие секции важны для работы сайта, а какие не обязательны, но необходимы с юридической точки зрения.

Internet Explorer, встроенный в офлайн-приложение Office, по умолчанию игнорирует понятие манифеста (который должен лежать по пути /w3c/p3p.xml) и содержимое тегов в страницы. Единственное, что включает возможность сохранение и отправки security cookie, — HTTP-заголовок вида:

policyref="/w3c/p3p.xml", CP="CAO DSP COR ...".
 

Опять же есть нюанс. Если вы заполните правило, что на вашем сайте есть “Physical contact information” или CP=”PHY”, то тут же отключится поддержка cookies с аттрибутом secure, и все опять перестанет работать.

Можно пойти путем Amazon и сделать так, но при существовании на сайте policy.html, указать необходимые контактные данные прямо там не составляет особого труда.



Детали реализации


Инициализация


Мы поняли, что не стоит никогда подключать два раза код библиотеки office.js в одном HTML-файле — вы получите ошибку на стадии получения контента файлов и не раньше. Это может случиться если у вас есть template заголовка на каждую страницу, и вы дополнительно упомянули office.js в основном коде страницы.

Инициализация происходит не самым очевидным образом. Вместо вызова office.init() с передачей callback-функции или популярным паттерном future — мы обнаружили свойство initialize, которому надо установить свою callback-функцию.

Код инициализации на Dart:

void initOfficeDocument() {
 var office = context['Office'];
 office['initialize'] = (_) { … };
}
 


Как только это будет сделано внутренний таймер office.js поймает это событие и начнет инициировать document:

g.waitForFunction(function(){return Microsoft.Office.WebExtension.initialize!=undefined},...
где window.Office=Microsoft.Office.WebExtension


То есть инициализация асинхронная и реализована необычным паттерном. Если по какой-то причине содержимое вашей анонимной фунции, передаваемой в инициализацию окажется пустой, и кто-нибудь ее впоследствии удалит, надстройка перестанет работать. Так что наш совет разработчикам — снабдить достаточными комментариями это место.

Провайдер данных


Данные документа можно получить методом getFileAsync. Подробнее об этом можно прочитать в документации Microsoft. Однако метод работать не будет, пока не потребовать в манифесте прав на чтение всего документа.

 <Permissions>ReadAllDocument</Permissions>


Метод getFileAsync() возвращает объект файл, в котором можно извлечь кусочки файла и склеить их для передачи на сервер, сконвертировав в тип Uint8List. Слайсы передаются в формате javascript array. Интересная и не очень заметная в документации особенность заключается в том, что нельзя запрашивать слайсы размером более 65536 байт. Иначе этот метод не будет работать на всех платформах.

Также стоит обратить внимание на секцию Remarks в описании метода getFileAsync. Полученный массив можно целиком отправить на сервер через http request POST метод.

Сложности


С первой и основной сложностью мы столкнулись практически в начале разработки. Проблема появилась в HTTP-заголовке X-Frame-Options. Так как по умолчанию мы работаем со значением Deny, попытки авторизоваться в том же окне были невозможны. Появилась идея сделать все в попапе. Однако мы вспомнили, что есть офлайн-платформа. Посмотрели, как реагирует наш обрезанный офлайн-браузер на такие попытки — он блокировал все, что всплывает. Значит, нашу собственную и Google-авторизацию можно было выполнить только внутри окна. Тогда мы вспомнили, что есть онлайн-режим, и там x-frame-options deny уже на странице Google Auth. Вывод: приходится делать различные методы входа для онлайн- и офлайн-платформ.

Еще одной нетривиальной задачей стала отладка приложения. По требованиям Office Store приложение должно работать в браузерах IE 11 (от поддержки IE 9 и 10 можно отказаться, сделав для них страницу-заглушку), Chrome, Safari и Firefox актуальных версий для Office Online и в IE 11 для Office 2013/2016. С отладкой в браузерах проблем не возникало, а вот встроенный браузер в десктопном Office не имеет консоли отладки. так как были ошибки специфические для офлайн версии, пришлось их отлавливать посылая фиктивные запросы на сервер, передавая в аргументах запроса отладочную информацию.

Просматривать сообщения можно прокси-монитором. Если же ваш сервер не отвечает, подвис на выдаче страницы надстройки или долго готовит данные, то скорее всего офлайн-приложение Office зависнет. Похоже, что загрузка сайта для надстройки происходит в основном UI-потоке приложения, что существенно затрудняет отладку.

Еще одна неприятная ошибка — всплывающее предупреждение “An add-on for this website failed to run. Check the security settings in Internet Options”.



При тестировании командой Microsoft это трактуется как нарушение требования, согласно которому весь сайт надстройки должен работать на HTTPS-протоколе. Информацию о том, что сайт на HTTPS можно найти в боковом меню Security Info, SSL: On.
Выяснилось, что ошибка безопасности всплывает в тот момент, когда в DOM появляется ActiveX-объект или Javascript-код его порождает. Никто специально ActiveX-компонент не создавал, хотя очень хотелось. Для открытия ссылок в браузере по умолчанию можно было бы создавать объект new ActiveXObject(«wscript.shell») и вызывать на нем метод Run(“ссылка”), чтобы не удивлять пользователя открытием ссылок исключительно в Internet Explorer.

Ошибку вызывает библиотека webComponents, используемая в Dart Polymer (0.5), и jquery младших версий (1.3). Обе библиотеки на стадии инициализации пытаются присоединить к document “” для проверки возможностей и версии браузера. В Internet Explorer HTMLObjectElement является ActiveX-объектом, что и приводит к неописанной и недокументированной ошике. Для jquery необходимо обновиться, и версия 1.9 уже не создает объект при подключении. Для webComponents пришлось создать свою «улучшенную» версию.

Мелочь, которая из-за невнимательности стоила нам нервов и времени – ограничение API Office 365. Основной метод, обеспечивающий доступ к файлу, — это getFileAsync(). На текущий момент метод поддерживается в Word настольной и онлайн-версий, в Excel Online и PowerPoint Desktop (в PP Online надстройки до недавнего времени нельзя было запускать). С чем связано отсутствие поддержки метода в Excel Desktop – неизвестно. Мы искали баг, из-за которого не загружались файлы в Excel, больше недели, потому что надо было внимательнее читать документацию, а мы, как в анекдоте, скорее писатели. После того, как разобрались, пришлось удалить и поддержку Excel Online, потому что указать произвольную матрицу приложений в манифесте нельзя, только отдельно Word/Excel/PP и отдельно Online/Desktop.

По словам клиентов Wrike, которые согласились поучаствовать в бета-тестировании, очень полезным подобное приложение было бы именно в Excel, так что очень ждем от Microsoft поддержки getFileAsync() в Excel.

Вообще некоторые проблемы целостности экосистемы до сих пор присутствуют. Так, в какой-то момент, когда тестирование уже шло полным ходом, на несколько недель без предупреждения пропала поддержка надстроек при запуске Office Online в Safari. К счастью, после восстановления работы исправлять что-либо не пришлось – ничего не сломалось.

Еще один момент – как и упоминалось выше, вплоть до момента публикации надстройки не поддерживались в Powerpoint Online, и появились, опять же без предупреждения, после отправки приложения на тестирование. Понятно, что экосистема молодая и активно развивается, и надеемся, что в будущем будет более ясное информирование о технических изменениях.

Собственно, все это привело к тому, что на отладку и публикацию у нас ушло больше времени (примерно месяц), чем на саму разработку (около трех недель).

Публикация


Процесс публикации был довольно простым, и похож на аналогичные процессы в других магазинах приложений. Через Seller Dashboard создается приложение, указывается информация для отображения в магазине, загружается манифест, и все это отправляется на публикацию. Приложение проходит ручное тестирование, после чего, если все в порядке, автоматически выкладывается в магазине в течение указанного при отправке дня.

Надо отдать должное команде тестирования Microsoft – обычно от отправки на валидацию до получения отчета проходило не более рабочего дня. А тестируется приложение достаточно подробно – в частности, первый отказ мы получили в связи с парой трудноотлавливаемых багов, которые проявлялись только в конкретном сочетании браузера и приложения Office.

Ко второй отправке мы поправили техническую составляющую и… были удивлены, увидев отчет с такими причинами отказа, как несоответствие краткого описания в магазине функциональности приложения и отсутствие понимания задач приложения по виду его первой страницы. Для приложения-сателлита, каковым является Wrike Add-in for Office, подобная очевидность в принципе не нужна – целевой аудиторией являются уже существующие пользователи Wrike, которые представляют, зачем нужна наша надстройка для Office. Но с гайдлайнами не поспоришь, так что пришлось добавить несколько строк о ключевых функциях на страничку с логинкой.

Интересно, кстати, что после успешной публикации любое обновление приложения, которое не требует модификации манифеста, в принципе может проходить без валидации в магазине.

Небольшие сложности были и с самим форматом отчета. Он отчет доступен только в PDF, при этом скриншоты в нем даны в таком разрешении, что не виден, например, текст ошибки.

Итоги


С третьего раза валидация была пройдена, и приложение появилось в магазине. Сбор обратной связи от пользователей только начался, и что-то сказать о реальной эффективности сложно, но первые цифры по количеству загрузок обнадеживают.

Нам удалось создать достаточно востребованное и интересное приложение, которое справляется со своими задачами. Уже получили позитивные отзывы от пользователей, которые много работают с документами разного типа — копирайтеров, технических и маркетинговых писателей и т. д., так что есть ощущение, что работа проделана не зря. Надеемся, что наш опыт будет полезен и другим разработчикам, которые подумывают о создании надстройки для Office 365.

Комментарии (1)