воскресенье, 15 июля 2018 г.

Экспорт событий из email в Google-календарь в один клик — подводные камни

image


Как одну из возможностей сервиса предварительной записи клиентов zabroniruy.com реализовывали идею, чтобы клиент получал всю информацию о предстоящих события в формате, который можно легко экспортировать (желательно в один клик) в существующие планировщики задач. В ходе работы столкнулись с тем, что не все планировщики одинаково “дружелюбны” к разработчикам.

За основу взяли формат iCalendar — этот формат простой и поддерживается многими приложениями.

С самим форматом никаких проблем не возникло. Просто добавили вложение в письмо и пользователь Outlook или Evolution (тестировали в этих приложениях) может экспортировать данные в свой календарь в один клик. Но мы хотели, чтобы пользователи Gmail имели возможность так же легко добавлять события в свой Google календарь, вместо того, чтобы скачивать файл и затем экспортировать его в календарь (мало кто станет таким заниматься).

И вот тут началось самое интересное. Google отображает иконку календаря для письма с вложенным ics файлом, но вложение можно только скачать. Но в Gmail есть опция “Вставить приглашение” и в этом случае получателю отправится письмо с вложением, которое можно импортировать в свой Google календарь в один клик. Вот этого мы и захотели добиться. Поиск в самом Google ничего не дал, пришлось своими силами искать причину того, что наше вложение не обрабатывается так же, как и письмо с приглашением, созданное напрямую из Gmail.

Код прикрепления файла к письму в этот момент выглядел вот так:
$mailer->createAttachment(
    $data,
    Zend_Mime::TYPE_OCTETSTREAM,
    Zend_Mime::DISPOSITION_ATTACHMENT,
    Zend_Mime::ENCODING_BASE64,
    'icalendar-file.ics'
);


До того, как мы получили первую работоспособную версию, испробовали разные подходы, но решение, как часто бывает, оказалось очень простым. Изучив письмо с приглашением из Gmail, мы заметили, что отсутствует загловок Content-Disposition, т.е. вложение добавленно в письмо как inline. Мы установили заголовок Сontent-disposition: inline в письме, сгенерированный нашим сервисом, сменили Content-type у вложения, чтобы указать тип файла, добавили method=REQUEST, чтобы Outlook принимал письмо как приглашение и “свершилось чудо”: в Gmail появилась ссылка “Добавить в календарь”, а Outlook стал отображать письмо как приглашение на событие.

Решение для ZendFramework:
$mailer->createAttachment(
    $data,
    'text/calendar; charset=UTF-8; method=REQUEST',
    Zend_Mime::DISPOSITION_INLINE,
    Zend_Mime::ENCODING_BASE64,
    'icalendar-file.ics'
);
$mailer->setType(Zend_Mime::MULTIPART_ALTERNATIVE);

multipart/alternative — указывает на то, что в частях сообщения используются разные типы content/type.

Вот так это выглядит в Evolution:
image

И вот так в Outlook:
image

0 коммент.:

Отправить комментарий