Поддержка IMAP для групповых почтовых ящиков

:rotating_light: Мы удаляем поддержку IMAP в Discourse. Подробнее читайте в этом посте: IMAP support for group inboxes - #39 by martin . :rotating_light:


Мы рады представить альфа-версию поддержки IMAP для групповых почтовых ящиков. Эта функция позволяет вводить учётные данные и настройки IMAP для каждой группы отдельно, чтобы синхронизировать групповые почтовые ящики с электронной почтой. :email:

:warning::warning: :warning:

Это функция на стадии альфа-тестирования, поэтому она ещё не полностью завершена и отполирована. Вероятно, в ней есть ошибки; мы в настоящее время не поддерживаем её и не используем в рабочей среде. Используйте на свой страх и риск!

:warning: :warning: :warning:

Преимущества

  • Ваша группа сможет сразу начать использовать почтовые ящики Discourse, так как вся ваша существующая почта будет синхронизирована! :running_woman:
  • Ваша группа сможет синхронизировать сообщения между Discourse и вашим почтовым провайдером, что исключит единую точку отказа. Люди смогут отвечать как с почтового аккаунта, так и внутри Discourse, и всё будет синхронизировано :zap:
  • Вам больше не нужно настраивать сложные правила пересылки с вашего почтового провайдера во входящие ящики Discourse. :arrow_right:
  • Метки электронной почты будут синхронизироваться с тегами Discourse, что поможет поддерживать порядок :card_file_box:
  • Вы будете отвечать людям, пишущим на адрес вашей группы, с того же адреса электронной почты, который вы настроили, даже если отвечаете из Discourse. Больше никакой путаницы! :relieved:

Функциональность

  • Весь входящий и исходящий трафик будет синхронизироваться между IMAP-сервером и Discourse. На основе проанализированных писем будут создаваться соответствующие темы и ответы на посты. Ответы можно создавать как из Discourse, так и с IMAP-сервера, и всё будет синхронизировано!
  • На письма можно отвечать как из группового почтового ящика Discourse, так и с почтового аккаунта.
  • Теги, применённые к теме в Discourse, будут созданы как метки и применены к письму на IMAP-сервере (это зависит от провайдера).
  • Письма, архивированные на IMAP-сервере, будут архивироваться в групповом почтовом ящике.
  • Темы групповых личных сообщений, архивированные в Discourse, будут архивироваться на IMAP-сервере.
  • Письма, удалённые на IMAP-сервере, приведут к удалению темы в групповом почтовом ящике.
  • Темы групповых личных сообщений, удалённые в Discourse, будут удалены на IMAP-сервере.
  • Письма, отправленные группами с включённой этой функцией, будут иметь адрес ответа, установленный в соответствии с именем пользователя электронной почты, указанным в настройках IMAP.

Начало работы

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

  • enable imap и enable smtp должны быть включены. IMAP используется для синхронизации с вашим почтовым сервером, а SMTP — для отправки писем с вашего почтового сервера.
  • tagging enabled и allow staff to tag pms — оба параметра должны быть включены, так как синхронизация меток применяется к личным сообщениям.
  • enable imap write — должно быть включено, если вы хотите, чтобы изменения, внесённые в Discourse, отражались на вашем почтовом сервере (например, теги, архивирование тем и удаление тем).
  • enable imap idle — позволяет получать обновления в реальном времени с вашего почтового сервера, ЕСЛИ ваш сервер поддерживает IDLE. Это значительно ускоряет отражение изменений в вашем почтовом провайдере в Discourse. Рекомендуется включить эту опцию (например, Gmail её поддерживает). Если вы хотите узнать все подробности, вы можете прочитать об этом в RFC для IDLE.
  • imap polling period mins — Если IDLE не поддерживается, это количество минут, которое мы ждём перед проверкой IMAP-сервера на наличие изменений. Это также время ожидания между отправкой изменений на IMAP-сервер из Discourse, если включено enable imap write. Минимальное значение — 1 минута.

Эти настройки можно оставить по умолчанию и изменить, если вы столкнётесь с проблемами синхронизации:

  • imap polling old emails — Максимальное количество старых (обработанных) писем для обновления при каждой проверке IMAP-ящика (0 — все).
  • imap polling new emails — Максимальное количество новых (необработанных) писем для обновления при каждой проверке IMAP-ящика.
  • imap batch import email — Минимальное количество новых писем, которое запускает режим импорта (отключает оповещения о постах).

Если вы хотите, чтобы метки/теги синхронизировались с IMAP-сервером, необходимо включить параметры сайта tagging enabled и allow staff to tag pms.

Далее перейдите в группу, которую вы хотите синхронизировать с вашим IMAP-сервером, и заполните настройки.

Эти настройки зависят от провайдера; подробнее см. ниже. После ввода настроек и учётных данных нажмите «Сохранить изменения», и мы проверим учётные данные на серверах IMAP-провайдера. Если проверка успешна, список почтовых ящиков будет заполнен, и вам нужно выбрать тот, который вы хотите синхронизировать (рекомендации по этому вопросу также зависят от провайдера):

Если проверка учётных данных не удалась, на странице будет показано сообщение об ошибке. Важно понимать: SMTP-сервер, который вы указали, будет использоваться для отправки писем от имени аккаунта, указанного в полях «имя пользователя» и «пароль», а не основной SMTP-сервер Discourse, настроенный для массовой рассылки.

Наконец, в вашем файле app.yml необходимо добавить DISCOURSE_ENABLE_EMAIL_SYNC_DEMON: true в секцию env и выполнить команду ./launcher rebuild. Это запустит фоновый рабочий процесс, который начнёт синхронизацию писем! :fireworks:

Информация, специфичная для провайдера

Gmail

  • :warning: Вы должны создать пароль приложения, иначе вам придётся включить «Доступ для менее безопасных приложений», что Google в любом случае планирует отключить в ближайшее время. Используйте этот пароль вместо пароля вашей учётной записи Gmail в настройках IMAP. Подробнее см. на Sign in with app passwords - Gmail Help . :warning:
  • Убедитесь, что вы используете следующие настройки для SMTP и IMAP:
    • Порт IMAP: 987
    • Порт SMTP: 587
    • Сервер IMAP: imap.gmail.com
    • Сервер SMTP: smtp.gmail.com
    • Используйте SSL как для SMTP, так и для IMAP
  • Настоятельно рекомендуется (скоро это станет функцией интерфейса) выбирать только почтовый ящик «[Gmail]/Все письма» для синхронизации.
  • Мы не удаляем письма в Gmail сразу, а только перемещаем их в корзину, когда тема удаляется в Discourse. Функция удаления «через 30 дней» в Gmail возьмёт на себя дальнейшую обработку.
  • Теги, применённые к темам в Discourse, создадут метки в Gmail и применят их к потокам писем. Метки в Gmail также являются IMAP-почтовыми ящиками!

Ограничения

Это функция на стадии альфа-тестирования, поэтому она ещё не полностью завершена и отполирована. В настоящее время действуют следующие ограничения:

  • В настоящее время поддерживается только Gmail как IMAP-провайдер. У нас есть некоторая общая функциональность IMAP, но нет гарантии, что она будет работать. Следующей нашей большой целью является поддержка Outlook Online.
  • Восстановление удалённых писем из корзины Gmail и отражение этого состояния в Discourse в настоящее время работает нестабильно.
  • :warning: Изменение почтового ящика для синхронизации после того, как письма уже были синхронизированы, не рекомендуется и может привести к множеству странных проблем. :warning:
  • Для каждой группы можно синхронизировать только один почтовый ящик.
  • Взаимодействие между группами — неизведанная территория и будет работать плохо (например, отправка письма team@yoursite.com с support@yoursite.com, если каждый из этих адресов настроен для разных групп).

Также могут быть другие тонкие нюансы и недоработки, так как это альфа-функция.

Обратная связь и дорожная карта

Мы будем рады получить обратную связь от всех, кто использует эту функцию с Gmail. Я буду тем, кто займётся устранением любых ошибок и проблем. Отладка сейчас немного сложна, но я работаю над этим!

Следующие задачи, над которыми я буду работать:

  • Улучшение отладки для упрощения просмотра логов IMAP и выявления проблем.
  • Улучшение интерфейса групповой электронной почты для ограничения выбора почтовых ящиков в Gmail, а также для предотвращения или запрета изменения почтовых ящиков.
  • Валидация для предотвращения использования одних и тех же данных IMAP для нескольких групп.
  • Возможно, улучшение способа хранения настроек группового IMAP и улучшение пользовательского опыта при проверке учётных данных.
  • Поддержка Outlook.

В настоящее время, пока мы устраняем недочёты, эта функция недоступна для наших хостинговых клиентов.

Особая благодарность :pray:

И @dan, и @j.jaffeux являются основными авторами этой огромной функции, над которой мы работали очень долго. Без их замечательной работы я не смог бы довести функцию до этого уровня и сделать это объявление :tada:.

41 лайк

Это одновременно и прекрасные, и ужасные новости. Позвольте мне объяснить. С одной стороны, это отличная новость — интеграция IMAP с группами Discourse открывает ряд полезных решений для идентификации групп (с использованием правильного исходного адреса), упрощает работу нескольких пользователей с одной учётной записью IMAP (что нативно поддерживается плохо, например, нет общих состояний прочтения) и прокладывает путь к почтовым ящикам ActivityPub. С другой стороны, это ужасные новости, поскольку реализация отдаёт предпочтение гигантам электронной почты, превратившим федеративный сервис в во многом централизованную систему. Я понимаю привлекательность работы с крупными провайдерами, но надеюсь, что стандарт IMAP будет предпочтительнее провайдер-специфичных расширений, чтобы любой почтовый провайдер поддерживался, как только эта функция достигнет стадии бета-тестирования.

Отличная работа, что это стало возможным.

10 лайков

Есть веская причина, по которой эта функция считается «альфа» :slight_smile:

Проблема с IMAP, насколько я могу судить со стороны, заключается в том, что нам приходится иметь дело с огромным количеством моментов, допускающих «различные толкования».

Мы, безусловно, хотим, чтобы это работало с большим количеством провайдеров; наши внутренние потребности тяготеют к крупному Google, потому что реальность такова, что мы используем Google в Discourse, поэтому мы решили сначала решить свою собственную проблему.

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

17 лайков

Это справедливое замечание. Как отметил @sam, мы в первую очередь сосредоточились на Gmail, поскольку используем его сами, и для нас это наиболее актуально. Однако я считаю, что наш базовый «общий» провайдер, хотя и не соответствует RFC на 100% и не обладает полным набором функций, довольно точно следует протоколу IMAP. См. https://github.com/discourse/discourse/blob/master/lib/imap/providers/generic.rb. Единственные доработки, которые, как мне кажется, потребуются, — это специальная обработка архивации и удаления. Сейчас при удалении мы просто помечаем сообщение флагом \Deleted и отправляем команду EXPUNGE, но я знаю, что некоторые почтовые клиенты позволяют пользователю выбрать: выполнить это действие сразу или сначала переместить сообщение в папку «Корзина», а затем выполнить EXPUNGE и т. д. Не уверен, какой стандарт архивации принят для IMAP. У нас есть отдельный класс провайдера для Gmail, который переопределяет некоторые из этих общих методов.

Если у вас есть предложения по другим «общим» серверам или провайдерам IMAP, против которых я мог бы протестировать решение, это было бы очень полезно, так как Gmail имеет свою собственную уникальную обработку функций и расширения IMAP для Gmail.

Также, как отметил Сэм, любые pull-запросы с улучшениями приветствуются. В противном случае мы будем реагировать на запросы сообщества. Я предполагаю, что следующим крупным кейсом для организаций, желающих внедрить такую функциональность, станет Outlook (у него тоже есть свои уникальные правила: например, архивация реализуется как отдельная папка/почтовый ящик, а поддержка меток отсутствует).

12 лайков

Выглядит очень интересно. Наша компания недавно перешла с собственного почтового сервера на G-Suite, и эта интеграция значительно упростит нам ответы на запросы клиентов и управление трекерами прогресса. У меня есть один вопрос к @martin. Мне не до конца ясно, будет ли использоваться SMTP Gmail для ответов на сообщения, полученные в групповом почтовом ящике, или же будет применяться массовый SMTP, настроенный для отправки писем от имени Discourse? Я вижу, что в описании плагина также упоминается SMTP Gmail, но мне всё же нужна ясность по этому вопросу.

6 лайков

Для отправки ответов используется SMTP-сервер Gmail, так как вы отправляете ответы от имени учётной записи электронной почты, используемой для синхронизации IMAP! Я добавлю примечание об этом в первый пост, чтобы прояснить ситуацию.

7 лайков

Это действительно гениально. Я могу придумать столько вариантов использования этого. Молодцы @martin @dan @j.jaffeux :raising_hands:

9 лайков

Короткое обновление. На прошлой неделе я объединил эти два PR. Во-первых, исправление, чтобы тегирование не требовалось включать для работы архивации и удаления:

Во-вторых, теперь я записываю все логи IMAP в базу данных для удобства проверки. Ежедневно будет выполняться задача по удалению логов старше 5 дней:

11 лайков

Это просто супер! Спасибо.

Хочу отметить, что мне пришлось создать пароль приложения в моем аккаунте Google, чтобы Discourse принял мое имя пользователя и пароль.

5 лайков

У вас включена двухфакторная аутентификация на стороне Google? Если да, то это стандартная практика.

2 лайка

Да. Я полагаю, это требовалось для создания пароля приложения (хотя я точно не помню).

1 лайк

Это отмечено в первом посте :wink: В противном случае придётся проходить через невероятные сложности, чтобы аккаунт Gmail принял «менее защищённые приложения». В какой-то момент нам потребуется поддержка OAuth для Google, так как именно в этом направлении всё движется.

4 лайка

Ой! Я что-то упомянул, что мои навыки чтения оставляют желать лучшего? :woozy_face:

5 лайков

Ничего страшного! Это важный момент, поэтому я переместил его в начало списка Gmail и добавил несколько предупреждающих индикаторов. Спасибо, что пытались предупредить других об этом, чтобы сэкономить им время и нервы :slight_smile:

6 лайков

Я пытаюсь понять, почему не удаётся синхронизировать письма с IMAP-сервером Dovecot (к сожалению, у меня нет опыта работы с Ruby или Rails).

При чтении imap_sync_logs видно, что демон импорта зацикливается:

UIDVALIDITY = 1612565899 не совпадает с ожидаемым 0, кэш IMAP сбрасывается, и происходит повторная синхронизация писем для почтового ящика INBOX

Поэтому я задаюсь вопросом, не должно ли в этом случае обновляться значение @group.imap_uid_validity:

После ручного обновления этого значения демон импорта зацикливается в другом месте.

Dovecot не поддерживает 'LABELS' в:

что приводит к ошибке Net::IMAP::BadResponseError, которая, к сожалению, не попадает в логи.

Теперь у меня возникают следующие вопросы:

  • достаточно ли поддержки пользовательских флагов в Dovecot для двусторонней синхронизации с Discourse;
  • как определить Dovecot в lib/imap/providers/detector.rb;
  • как эмулировать функцию меток в провайдере для Dovecot.

5 лайков

Синхронизация IMAP для общих почтовых ящиков всё ещё находится на ранней стадии разработки и в настоящее время поддерживает только Gmail. Теоретически вы могли бы написать провайдер для dovecot, но несколько недель назад я заметил, что в основном коде есть несколько мест, где используются функции, специфичные только для Gmail, и их необходимо перенести в код, специфичный для провайдера. Так что извините за это, но, возможно, вам стоит подождать, пока это не приблизится к стадии готовности к использованию.

7 лайков

Полагаю, что 'LABELS' — это нестандартная функция Gmail.
Я хотел бы понять разницу между Google IMAP и стандартным IMAP.

Вот мое резюме на данный момент:

стандартный IMAP Google IMAP
архивированные письма хранятся в подпапках все письма хранятся в одной папке
у архивированных сообщений отсутствует метка \\INBOX
пользовательские флаги хранятся вместе с системными флагами хранит пользовательские флаги в виде меток

Было бы достаточно:

  • эмулировать метки в стандартном IMAP, разделив флаги на системные и пользовательские;
  • обрабатывать email_is_archived на стороне провайдера (например, добавлять и проверять флаг “archived”);

чтобы запустить синхронизацию через стандартный IMAP?

Это затронет следующие строки:

Эта строка кажется мне странной:

Все системные флаги будут перезаписаны тегами Discourse.
Правильно ли это обрабатывает все флаги IMAP (\Answered, \Deleted, \Draft, \Flagged, \Recent и \Seen / $Forwarded, $MDNSent, $SubmitPending и $Submitted)?

2 лайка

Я вернулся к этому вопросу после некоторого перерыва.

Мне не удалось разобраться, как правильно настроить заголовок reply-to. Я могу создать группу для синхронизации с конкретным аккаунтом Gmail, но при попытке ответить по электронной почте адрес в заголовке reply-to устанавливается в настроенный уведомительный email из Discourse, а не в IMAP-адрес.

Не упустил ли я что-то?

1 лайк

Только что протестировал это с почтовым провайдером GoDaddy, но без успеха. С Gmail работает отлично, но, к сожалению, мы хотим использовать свой собственный домен. Есть ли какие-либо обновления, чтобы это было готово к запуску?

1 лайк

Кстати, вы можете использовать свой собственный домен с Gmail (за деньги).

1 лайк