Продуктивність поштою: Як створювався Evernote для Outlook

Продуктивність — це, мабуть, один з найпопулярніших трендів останніх років, і рішення Evernote є яскравим прикладом в цій ніші. Відмінна новина для користувачів Evernote — тепер доступна можливість працювати з рішенням і в Outlook, про що далі й піде мова.
Я хочу подякувати за підготовку статті Родіона Насакина (Market Development Director Evernote в Росії і СНД), а також компанію Actimind, явлющуюся експертом у розробці плагінів для різних додатків, включаючи додатки Microsoft Office.
У цій статті ми хочемо розповісти про те, навіщо Evernote знадобилося створювати додаток для Outlook і поділитися досвідом його розробки.



Навіщо Evernote знадобився Outlook
Сервіс Evernote став популярним в чому за рахунок своєї універсальності, дозволяючи збирати, синхронізувати і впорядковувати різноманітну інформацію. Це можуть бути текстові замітки, рукописні замітки, скани, фотографії, скопійовані з Інтернету статті, списки завдань, голосові записи і багато іншого.

70% користувачів використовують Evernote в роботі та бізнесі, і очевидно, що істотна частина потрібної інформації надходить до них по email. Для Evernote, в свою чергу, важливо, щоб користувачі могли швидко збирати в одному місці всю інформацію, що відноситься до робочого проекту, і працювати з нею, не покидаючи програми.

Тому в Evernote крім набору мобільних та десктоп-додатків є відразу кілька інструментів для роботи з вхідними email. Це, зокрема, копіювання бесід з Gmail з плагіном Evernote Web Clipper і пересилання на спеціальний адреса Evernote. І, звичайно, як тільки в Office 365 з'явилася підтримка сторонніх доповнень (add-in), команда сервісу задумалася над спеціальним рішенням для такого помітного інструменту.

Розробку Evernote для Outlook доручили незалежної команді Actimind, нашим співвітчизникам із Санкт-Петербурга. Раніше хлопці вже працювали над доповненнями Evernote Web Clipper для браузерів, так що мали уявлення про Evernote API і специфіці сервісу в цілому.

З Evernote для Outlook користувачі отримали можливість скопіювати в свій аккаунт лист, листування цілком або її частину в Evernote, вказавши блокнот призначення і потрібні мітки. Корпоративні блокноти і мітки для користувачів вирішення Evernote Business також підтримуються.

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

Додаток працює і «зворотний бік» — можна швидко додати замітки з Evernote в створюване в Outlook листа, щоб поділитися ними з колегами.

Як влаштовано додаток для Outlook
Доповнення або надбудова (add-in) для Outlook представляє собою файл маніфесту, а також одну або кілька веб-сторінок. Маніфест це XML-файл, у якому зберігається деяка інформація про додатку, в тому числі адресу, з якого Outlook завантажить стартову сторінку. Сторінки ж відповідають безпосередньо за основну логіку і інтерфейс програми. Вони будуть відкриті в захищеному фреймі на сайті Outlook, і зможуть спілкуватися з сервісом через спеціально наданий API.

На відміну від класичних доповнень для Outlook, нові додатки запускаються тільки вручну, в контексті одного елемента. Поки додаток не запущено, воно не має жодного уявлення про дії користувача. Крім того, нові програми можуть працювати тільки з листами і запрошеннями. Підтримки завдань, журнальних записів та календарних подій в онлайн-версії Outlook поки немає. Зате нові програми мають кроссплатформенностью і можуть працювати в будь-яких клієнтів Outlook.com (Outlook 2013 або 2016, Outlook Online), включаючи мобільні.

Середовище розробки
Розробляти надбудову можна в будь-якому HTML+PHP+CSS редакторі, але ми б особливо виділили два варіанти.

По-перше, це Napa Office 365 Development Tools (www.napacloudapp.com), хмарне рішення, яке відмінно підходить для швидкого прототипування.



Тут можна швидко познайомитися з основними настройками маніфесту і випробувати JS API у справі. Napa хостить файли програми і автоматично оновлює маніфест при його зміні. Коли перестане вистачати можливостей онлайн редактора, проект можна експортувати, наприклад, в Visual Studio.

Visual Studio, починаючи з 2012 версії, підтримує можливість розробки надбудов для Office 365: оновлює маніфест, піднімає IIS з файлами, дозволяє проводити відладку через IE. Однак для роботи потрібно буде встановити додатковий компонент, про який детальніше можна почитати тут.

В інших редакторах може бути вбудований веб-сервер, але маніфест, швидше за все, доведеться завантажувати та оновлювати вручну, через пункт меню Outlook Manage add-ins. Втім, це потрібно не так часто.

Процес розробки
В якості основи була обрана зв'язка mithril+require.js код писався в основному на СoffeeScript і Less. Збірка здійснювалася з допомогою Grunt.
За основу маніфесту ми взяли експортований файл з Napa — там вже є все необхідне.

<?xml version="1.0" encoding="utf-8"?>
<OfficeApp xsi:type="MailApp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/office/appforoffice/1.1">
<Id>e8df9484-022a-479e-8175-c08d2d540bdb</Id>
...
<DisplayName DefaultValue="Evernote DEV"/>
<IconUrl DefaultValue="https://localhost:44555/app/images/app-icon.png" />
...
<FormSettings>
<Form xsi:type="ItemRead">
<DesktopSettings>
<SourceLocation DefaultValue="https://localhost:44555/app/html/home-read.html" />
<RequestedHeight>350</RequestedHeight>
</DesktopSettings>
<TabletSettings>
<SourceLocation DefaultValue="https://localhost:63342/app/html/home-read.html?mobile" />
<RequestedHeight>350</RequestedHeight>
</TabletSettings>
<PhoneSettings>
<SourceLocation DefaultValue="https://localhost:44555/app/html/home-read.html?mobile" />
</PhoneSettings>
</Form>
<Form xsi:type="ItemEdit">
<DesktopSettings>
<SourceLocation DefaultValue="https://localhost:44555/app/html/home-compose.html" />
</DesktopSettings>
...
</Form>
</FormSettings>
<Permissions>ReadWriteMailbox</Permissions>
...
</OfficeApp>

Основні частини маніфесту включають ID додатка, його назву та опис, а також режими роботи і заслання. Додаток Evernote працює в режимі читання (ItemRead) і в режимі редагування листа (ItemEdit), на десктопах, планшетах та мобільних телефонах. При бажанні, можна вказати різні посилання для кожного з цих випадків.

Оскільки HTTPS для усіх ресурсів є обов'язковою вимогою, знадобиться сертифікат. На перший час і для локальної розробки вистачить самоподпісанного, але для повноцінної перевірки в мобільних клієнтів потрібен буде справжній.

Після додавання маніфесту програми в акаунт Outlook над листом у режимі читання (або на верхній панелі в режимі редагування) з'явиться іконка програми.

Як згадувалося вище, всі надбудови виконуються вручну, у відчиненому фреймі зверху або збоку, в режимі редагування) від тіла листа. У нього буде завантажена відповідна сторінка з маніфесту. Сторінка повинна містити посилання на office.js, який створить глобальний об'єкт Office і проведе його ініціалізацію. Залишиться тільки помістити логіку запуску програми Office.initialize.

Office.initialize = (reason) =>
language = Office.context.displayLanguage
context.init()

Після виклику initialize можна починати користуватися JS API, наприклад, отримати мову інтерфейсу, вибраний користувачем. До речі, в наявності хороша підтримка локалізації, в тому числі і полів маніфесту.



Ми використовували схему з кількома версіями надбудови — для розробки, тестування збірок, і одну стабільну для презентації. З точки зору Outlook це різні програми, у кожного з них — свій маніфест з унікальним ID, і посилаються вони на різні місця. Таким чином можна вести розробку і тестування, не заважаючи один одному. У нашому випадку маніфест DEV-версії вказує на шлях виду «localhost:44555», що зручно для спільної розробки. Але при необхідності кожен розробник може створити собі свою версію маніфесту для зручності або експериментів.

Як згадувалося на початку, в режимі читання листа додаток повинен вміти зберігати поточне лист або всю переписку, а також вкладення цих листів.



При збереженні листи ми також зберігаємо всі його атрибути. В JS API отримати їх дуже легко:

item = Office.context.mailbox.item 
mail.subject = item.subject
mail.sender = item.from.displayName + " ("+ item.from.emailAddress+")"

З тілом листи складніше, в режимі читання його отримати не вийде. На щастя, при наявності у додатки рівня доступу ReadWriteMailbox дозволяється виконувати метод makeEwsRequestAsync, який дозволяє виконати вручну сформований SOAP-запит до сервісу, правда, не будь, а з обмеженого списку. З допомогою цього методу від сервісу можна отримати деякі речі, які поки що недоступні через JS API.

Office.context.mailbox.makeEwsRequestAsync(
@getItemUniqueBodyRequest(Office.context.mailbox.item.id),
(asyncResult) -> @processMailSoap(asyncResult, callback))

getItemUniqueBodyRequest формує SOAP-запит на основі ідентифікатора листи, processMailSoap розбирає присланий відповідь. makeEwsRequestAsync, як і багато інших потенційно тривалі методи JS API, є асинхронним. На асинхронні методи поширюється обмеження — одночасно можуть виконуватися не більше трьох, крім того, максимальний розмір результату, що повертається обмежений одним мегабайтом.

Таким же чином можна отримати ланцюжок листів, а от з вкладеннями виникнуть проблеми. JS API не надає прямого доступу до тіл вкладень. Але спосіб отримати їх є, для цього потрібно викликати функцію Office.context.mailbox.getCallbackTokenAsync, отримати від неї краткодействующий токен доступу, і передати його на сервер разом з посиланням на сервіс Exchange, яка знаходиться в Office.context.mailbox.ewsUrl. Серверна частина має можливість виконати обмежений набір SOAP-запитів до сервера за допомогою сертифіката, в тому числі і отримати дані вкладень. Набір запитів, що сервіс може виконати з токеном, ширше, ніж доступний клієнтської частини з makeEwsRequestAsync, до того ж на нього не поширюється обмеження в 1MB. Але, на жаль, токен обмежений доступом до одного елемента, в контексті якого була відкрита надбудова, навіть якщо в її маніфесті зазначено дозвіл ReadWriteMailbox, тому зберегти ланцюжок листів з вкладеннями поки неможливо.

Користувачі мають можливість поставити блокнот і мітки Evernote, які будуть використовуватися за замовчуванням. Для зберігання цих налаштувань PHP API надає об'єкт Office.context.roamingSettings, який синхронізується для конкретної надбудови між усіма пристроями цього користувача Outlook. Значення зберігаються у формі JSON.

notebook = Office.context.roamingSettings.get(defaultNotebookSettingName)
Office.context.roamingSettings.set(defaultTagsSettingName, ["tag1","tag2"]) 
Office.context.roamingSettings.saveAsync(callback)

В режимі написання листа користувач може додати посилання на будь-яку зі своїх нотаток. Користувачі зможуть відкрити нотатку в браузері, навіть якщо вони не є користувачами Evernote.



Outlook JS API підтримує методи для вставки фрагментів HTML в тіло. Попутно визначаємо, в якому форматі тіло листа є текст і HTML, RTF формат листів в Outlook 365 недоступний.

Office.context.mailbox.item.body.getTypeAsync (result) =>
if result.status == Office.AsyncResultStatus.Failed then return
switch result.value
when Office.MailboxEnums.BodyType.Html
noteUrl = @getNoteShareUrl(note.guid, notebook, shareKey)
imgSrc = @getNoteShareThmbUrl(note.guid, notebook, shareKey)
html = @generateHtml(note, createdBy, noteUrl, imgSrc)
Office.context.mailbox.item.body.setSelectedDataAsync(innerHtml, { coercionType: Office.MailboxEnums.BodyType.Html })
when Office.MailboxEnums.BodyType.Text
noteUrl = remote.getNoteShareUrl(note.guid, notebook, shareKey) + "\n"
Office.context.mailbox.item.body.setSelectedDataAsync(noteUrl, { coercionType: Office.MailboxEnums.BodyType.Text })

До листа можна додати вкладення, якщо у вас є пряме посилання на них. Outlook сам завантажить і прикріпить файл. А от можливість вставки inline-елементів обмежена. СontentID не підтримується, а base64-посилання Outlook фільтрує. Можна примудритися і створити вкладення, а потім послатися на нього через ім'я, але цей спосіб ненадійний, до того ж результат з'явиться не одразу, а тільки після поновлення і збереження листи. Залишається тільки використовувати абсолютні посилання на зображення. На даний момент іконка пропадає, якщо користувач закриє доступ до замітці, в силу особливостей роботи цього механізму в Evernote.

Труднощі
В цілому, Office JS API досить добре документований, але без складнощів, звичайно, не обійшлося. Деякі моменти, гідні згадки, наведені нижче.

Практично відразу ж ми зіткнулися з проблемою same-origin policy. Добре, якщо у вас є можливість розмістити файли надбудови разом з її серверною частиною, або є доступ до налаштувань CORS. У нас такої можливості під час розробки не було. Для економії часу ми вели розробку паралельно з підготовкою серверної частини.
Найпростішим способом обійти same-origin policy є Chrome, запущений з прапором --disable-web-security. Аналогічні можливості існують практично для всіх основних браузерів, але для повноцінного тестування і підтримки мобільних пристроїв нам довелося піднімати невеликий проксі-сервер.

Налагодження програми, що працює в настільному браузері, не представляє проблеми. На ваш вибір є кошти IDE і відладчик браузера. Але ось налагодження на мобільних пристроях і в десктопному клієнта може викликати певні труднощі, оскільки додаток заховано всередині клієнта Outlook. Найцікавіше, що поведінка програми в мобільному клієнті може відрізнятися від поведінки програми, відкритого в онлайн-версії Outlook на тому ж пристрої (в основному страждають стилі, звичайно). Трохи допомагає внутрішній лог з висновком в інтерфейс, але повноцінного відладчика в таких умовах все ж іноді не вистачає, але недавній анонс виходу Office UI Fabric — інтерфейс відладчика, за словами команди розробників Office 365, повинен заповнити цей пробіл.

Add-In Evernote для Outlook
Однак, в цілому, у нас вийшло створити досить функціональний і зручне рішення на рівні розширень Evernote Web Clipper для браузерів. Так що якщо ваша аудиторія активно працює з Outlook, вам важлива кросплатформеність і мобільність, а також ви роздумуєте про інтеграцію, сподіваємося, що наш досвід буде вам корисний.



Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.