Возможность привязки постов к родительской теме в интеграции со Slack

На работе мы очень часто используем Slack. Есть контент, который должен быть доступен в Slack, но при этом организованным и поисковым — именно в этом, как я видел, Discourse отлично справляется. Мы пробовали несколько вариантов, похожих на вики, но все они приходили в упадок, отчасти из-за отсутствия связи со Slack. Поэтому я инициирую оценку возможности запуска Discourse параллельно с нашим существующим Slack и в связке с ним, поскольку я уже управляю форумом Discourse для сообщества. :smiling_face:

Однако у нас много каналов, где активно используются потоки (threads). В том числе самый приоритетный канал Slack, который должен быть интегрирован с Discourse двусторонне (и «подписка», и «публикация»).

Не нарушит ли это логику плагина чат-интеграций, если реализовать не стандартный режим, при котором новые темы публикуются в Slack как сообщения, сохраняется связь между ID сообщения в Slack и темой, а новые комментарии к этой теме отправляются в Slack как сообщения внутри потока (threaded messages)? Для моего случая это может стать ключевым фактором, определяющим успех или провал.

Обновление: Для моего сценария это будет опция «подписки» (watch), а не общесайтовая конфигурация чата со Slack, поскольку «предпочитать потоки» или «не предпочитать потоки» — это настройка для каждого канала в отдельности, зависящая от его назначения (и типичных участников) канала Slack.

4 лайка

Звучит как отличная идея! Добавление этой функции в плагин определённо будет приветствоваться (pr-welcome).

Просто уточняю… под «публикацией» вы имеете в виду существующую функцию публикации транскриптов? Или вы пытаетесь синхронизировать поток в Slack с темой в Discourse? Думаю, второе довольно сложно реализовать корректно, и, вероятно, это не впишется в плагин chat-integration.

1 лайк

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

Наш сценарий — это канал, в котором:

  • Ответы в виде потоков (threads) являются нормой, поскольку в канале одновременно ведутся разговоры на разные темы (канал предназначен для бизнес-целей, а не для конкретной темы; альтернатива — приглашать половину инженерного отдела в новые временные каналы, создаваемые по дюжине раз в день — непрактична)
  • Многие, но не все из этих потоковых разговоров должны идентифицироваться как ответы на вопросы, которые позже кто-то другой захочет найти, и интеграция должна способствовать их продвижению как надежных в соответствующей категории Discourse (кто-то вроде меня активно курирует полезные ответы)
  • Новые темы в этой связанной категории в Discourse должны приводить к появлению сообщений в Slack в том же канале
    • Дополнительные комментарии к этим новым темам должны публиковаться в Slack в виде потока, следующего за первоначальным новым сообщением в Slack
  • Пользователей направляют сначала искать информацию в Discourse, прежде чем задавать вопросы в Slack

Кроме того, ваш вопрос заставляет меня подумать, что как связанная функция было бы здорово иметь возможность при сводке потока Slack в пост на Discourse, чтобы интеграция размещала ссылку на новую тему Discourse в конце исходного потока Slack, который только что был обобщён. Это помогло бы нам вести разговор в одном месте.

Это на самом деле связано с первоначальной идеей функции, потому что если бы у нас было и то, и другое, то имело бы смысл при сводке не публиковать новое сообщение в Slack, а размещать сообщение в самом обобщаемом потоке, и помечать этот поток как место для дополнительных комментариев на Discourse. При этом дополнительные комментарии Slack в этом потоке не сводились бы в Discourse; цель — перенаправить обсуждение этой темы на Discourse. Это кажется мне логичным:

  • ДАННО: есть место для хранения ID сообщения Slack, связанного с темой
  • И: новые комментарии к теме публикуются как комментарии к сохранённому сообщению Slack
  • ТО: устанавливать ID сообщения Slack для темы при использовании функции интеграции Slackbot post thread, что приводит к анонсированию новых комментариев Discourse по теме в этом потоке, включая ссылки обратно на тему/комментарий Discourse

Это действительно помогло бы внедрить концепцию «сначала проверьте Discourse, прежде чем спрашивать».

5 лайков

Мне всё это звучит отлично!

:100:

3 лайка

В качестве визуального примера: похоже ли это на UX Slack, который вы хотите продвигать?

… о боже, год отсутствует в заголовке темы. любые догадки?

@riking Немного, но с некоторыми отличиями.

Сообщение об этом выглядело бы не совсем так; его публиковала бы сторона watch интеграции. В нём не указывалось бы, что тема была перемещена. Вот пример текущего (без нитей) интерфейса из интеграции со Slack, который я реализовал для makerforums:

В модели с нитями первый из этих постов запускал бы поток в Slack, а комментарий Nedman’а был бы ответом в этом потоке. При использовании post thread :thread_url параметр :thread_url сохранялся бы вместе с новой темой, и сторона watch интеграции чата публиковала бы как начальное сообщение темы, так и все дальнейшие комментарии в этот поток Slack, но содержимое оставалось бы прежним.

Интеграция watch thread перенаправляет вас в Discourse, где вы должны ввести заголовок и имеете возможность отредактировать новое сообщение темы перед публикацией. Таким образом, объявление, публикуемое в Slack, уже указывает на автора, запустившего post thread, затем содержит строку с заголовком темы в виде текста ссылки, ведущей на Discourse, и далее — выдержку из начала сообщения. Предложение, которое я здесь выдвигаю, заключается в том, чтобы при использовании нестандартной конфигурации на уровне канала (то есть опции watch, а не глобальной конфигурации плагина интеграции чата на всём сайте) этот контент публиковался бы в поток, а не в канал. (Не «также отправлять в канал» — это свело бы на нет цель изменения для нас.) Дальнейшие комментарии к этой новой теме в Discourse также отправлялись бы в тот же поток Slack.

И, раз вы просите предположений, 2017 год, когда Slack выпустил потоки?

2 лайка

Я обдумывал это и изучил документацию по API chat.postMessage в Slack, и, думаю, могу свести свою простыню текста к чему-то гораздо более простому.

Только правило watch, а не follow, имеет возможность выбирать потоковые ответы, хотя механизм, который я использую, я пока пытаюсь определить. Или же, @david, что вы думаете о новом фильтре правил thread с приоритетом mute thread watch follow, и о передаче этого правила через trigger_notification для включения поведения, чувствительного к правилам?

  1. Если watch настроен на использование потоков (или определено правило thread), при отправке уведомления о новом посте в канал Slack, если тема поста имеет связанный с ней ts в Slack, опубликовать сообщение в этом потоке Slack, установив thread_ts равным значению ts, полученному от Slack.

  2. При отправке уведомления о новом посте в канал Slack, если тема поста не имеет связанного с ней ts, сохранить возвращённое значение ts для этой темы (чтобы будущие посты по этой теме могли быть объединены в поток, если watch настроен на потоки).

  3. При использовании команды post thread :thread_url сохранить ts потока в созданной теме, который будет использоваться только правилами watch для потоков.

Вот мои текущие мысли и опасения:

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

  2. Передача исходного URL сообщения в Slack и идентификатора потока через поток транскрипции — это то, что сейчас кажется мне наиболее непрозрачным. Похоже, мне действительно нужно добавить идентификатор потока для каждого провайдера в каком-то месте и сохранить его до сохранения поста. Я бы реализовал это только для ts в Slack, но, вероятно, это не будет единственной интеграцией чата с потоками.

  3. Для публикации, думаю, мне нужно хранить ts Slack в пользовательском поле, специфичном для Slack, в теме, а не в общем пользовательском поле DiscourseChat для потока.

1 лайк

Действительно ли булево значение ‘threading’ должно быть специфичным для каждого правила? Почему бы не создать новую настройку сайта

chat_integration_slack_thread_responses

Если она включена и у нас есть запись ID потока темы, то мы отправляем последующие уведомления в поток Slack.

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

Да, это очень непросто. В качестве версии 1 я бы склонился к включению чего-то вроде

<!--SLACK_THREAD_ID=abcdefg-->

в начале сообщения. Затем плагин может проверять сообщения, начинающиеся с этой строки, и назначать пользовательское поле. Это не идеально, но, возможно, хорошая отправная точка?

2 лайка

Спасибо большое!

Вчера я реализовал первые два пользовательских соглашения (AC), и все тесты в стеке проходят успешно (хотя я еще не тестировал в рабочей среде), используя пользовательское поле в Topic и правило thread. Пока я не затрагивал поток транскрипции. Так что я добиваюсь хорошего прогресса в направлении возможности показать код хотя бы в черновике PR.

У меня также есть отдельный коммит для удаления неиспользуемого pstore_get из провайдера Slack. Поскольку это единственное использование pstore во всем стеке, хотите ли вы, чтобы я также удалил все pstore_* из app/initializers/discourse_chat.rb в этом коммите очистки?

Именно с этого я и начал, и это, безусловно, было бы проще!

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

Я заметил два по сути не связанных между собой аспекта, определяющих это предпочтение:

  • Членство: В каналах, где большинство участников десятилетиями активно использовали IRC, люди привыкли мысленно разграничивать перемешанные разговорные потоки в одном канале и не хотят переходить в потоки, чтобы увидеть важный контент. В то же время в каналах, где большинство участников привыкли к электронной почте, ожидают, что разговоры будут организованы в потоки, и они будут переходить в те разговоры, которые их интересуют.
  • Цель: Каналы с бизнес-целью объявлений, как правило, агрессивно используют потоки, тогда как каналы с исследовательскими или коллаборативными целями часто намеренно не используют потоки, поскольку те скрывают информацию, если вы не заметите их и не перейдете внутрь.

Если вы хотите иметь общий синтаксис для опций правил, я бы подумал, что Rule можно расширить так, чтобы у него было значение :options, которое, как и :tags, является массивом. Мне кажется, что имеет смысл взять пример из командных оболочек, чтобы /discourse [watch|follow|mute] -something -here устанавливал :options в ['something', 'here'], где ведущий - обозначает опцию. Тогда это будет выглядеть так: /discourse watch my-category-slug #tagged-foo -threaded. Я не знаю, насколько больше работы это потребует по сравнению с тем, что я уже сделал. У вас есть сильные предпочтения в ту или иную сторону? Я вижу аргументы за и против: добавление еще одного значения в Rule усложняет написание чат-провайдера; добавление еще одного значения фильтра делает еще одну специфичную для Slack функцию (например, публикацию транскрипции), что усложняет интерфейс для пользователей, не использующих Slack. Конечно, я могу упускать что-то, что сделает это сложнее, чем я думаю; например, если slug категории может начинаться с -, это сразу создаст неоднозначность; оболочка использует --, чтобы означать «всё после этого не является аргументом», но, возможно, мы могли бы инвертировать это, так что -- будет означать «всё после этого является опцией». Если вы хотите, чтобы я изучил это, пожалуйста, дайте мне направление по синтаксису, который вы считаете подходящим для указания опций правил. Но просто добавить thread кажется мне проще, поэтому, пока нет конкретных указаний добавить общую функцию «options», я подожду с любыми изменениями в этом направлении.

[Редактирование: Переход от фильтра правила к опции определенно усложнит интерфейс, который должен будет получить общую поддержку общих опций, и это не кажется мне хорошим выбором. Поэтому, после рассмотрения интерфейса, я предпочитаю остаться с фильтром; я думаю, что это чище.]

Что касается потока транскрипции постов, спасибо за идею с HTML-комментарием. Для моего случая это меня никак не затруднит; я честно ожидаю быть основным пользователем, по крайней мере, на начальном этапе. Это приятный простой хак.

У меня есть отдельная идея, которую я не планирую включать в этот PR: было бы здорово иметь отображение от канала, из которого отправляется сообщение, к категории, в которой должен быть создан соответствующий пост в Discourse. Для этого, как мне кажется, транскрипт лучше изменить, добавив обертку или sidecar, в котором могли бы содержаться и категория, и ID Slack. Это выглядит как значительный объем обучения для меня, так как я все еще нахожусь на этапе «продвинутого гугления проблемы» при изучении Ruby on Rails. :wink:

2 лайка

Ещё одна идея для доработки этой функции:

Что если добавить ещё одну настройку, например cross_post_to_channel_after_hours (по умолчанию 48?), где, если время с момента последнего ответа превышает X часов, пост отправляется в тред с флагом «также отправить в канал».

Не воспринимайте моё предложение слишком серьёзно прямо сейчас, если вы просто хотите сначала добиться базовой работоспособности (это, вероятно, более разумная стратегия!). Просто на заметку…

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

Если бы это была обычная настройка, а не опция для каждого канала, она называлась бы chat_integration_slack_copy_threads_to_channel_after_hours. По умолчанию значение было бы 0 (не отправлять), но вы могли бы установить любое другое. Концептуально это довольно просто, но требует больше работы, так как нужно получить поток (используя код, изначально написанный для транскрипций; не помню сразу, потребует ли это рефакторинга), чтобы принять решение об установке простого флага.

Но если вы хотите поработать над этим, надеюсь, то, что я делаю, послужит хорошей основой. Я лишь прошу не включать это по умолчанию, потому что, если это сработает при обновлении и мои пользователи будут «спамиться» мной из-за курирования контента для Discourse, у меня будут недовольные пользователи.

1 лайк

Чтобы упростить задачу, я думаю, можно просто проверить дату предыдущего сообщения в теме Discourse.

(В некоторых случаях это будет работать немного иначе, но это может стать хорошей отправной точкой)

@david У меня есть черновик PR, который проходит юнит-тесты, как я их написал. Я ещё не пробовал запускать его вживую с Slack, поэтому не хочу мержить его, пока это не будет сделано. Но хотя бы все мои юнит-тесты проходят, и я постарался добавить для них осмысленные тесты.

Я также перенёс комментарий с ID в конец поста вместо начала, так как там он, скорее всего, выживет и будет меньше шансов, что его исказят, и я постарался быть консервативным при его извлечении.

Спасибо за вашу работу над этим плагином!

Я исправил свои первоначальные ошибки линтинга, но теперь падают тесты, которые я не трогал. Я работаю на основе последней версии master, и локально тесты проходят. У вас есть какие-то идеи насчёт падающих тестов?

4 лайка

Я значительно привёл PR в порядок, но он ещё не совсем готов к слиянию. На данный момент у меня есть два-три момента, которые вызывают трудности, и я пока не знаю, как их исправить.

  1. Я пытаюсь использовать fa-arrow-circle-o-right как иконку темы, но на моём работающем сайте в интерфейсе она отображается пустой. (После переключения на свою ветку на рабочем сервере я запускаю su discourse -c 'bundle exec rake assets:precompile' && sv restart unicorn для тестирования.) Я добавил её в plugin.rb и также сделал ссылку на неё, но теперь не понимаю, какие шаги предпринять дальше. Существует ли список иконок Font Awesome, одобренных для использования в Discourse? Нашёл lib/svg_sprite/svg_sprite.rb, и chevron-right отлично подходит для этой задачи.

  2. Локально все тесты проходят успешно, но в Travis я получаю постоянные ошибки, которые, кажется, не связаны с моими изменениями, и, естественно, мне трудно их расследовать или анализировать. 13 сбоев с кодом 404 вместо ожидаемого (например, 200) в spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb Исправлено отказом от «копипаста» с isolate_namespace, и теперь я знаю о команде rake routes.

Мне удалось успешно отправить сообщения:

Возможно, ещё потребуется кое-что почистить, но, думаю, это работает.

После слияния я обновлю Discourse Chat Integrations соответствующим образом.

2 лайка

Я постоянно нахожу здесь новые возможности для обучения. Теперь я знаю, как запускать yarn prettier, а следующим шагом я изучу, как обновлять тесты фронтенда…

Ошибка: Ошибка утверждения: Вы должны использовать set() для установки свойства `channel` (объекта <(unknown):ember3806>) в значение `<(unknown):ember3799>`.

Огромное спасибо за всю вашу работу здесь, @mcdanlj — это уже объединено:

4 лайка

Я очень ценю ваши полезные отзывы! Как и обещал, я обновил официальную статью в вики об интеграции. Если вам удобнее указывать изменения другими способами, я только за — у меня нет никаких амбиций на авторство или чего-то подобного. :smiling_face:

3 лайка

Пожалуйста, включите потоковую обработку в настройках интеграции чата для Slack, как в примере:

Включить потоковую обработку сообщений в Slack

Вы имеете в виду, что хотите иметь возможность настроить плагин так, чтобы он отказывался учитывать опцию thread в интеграции?

Мы обновились до текущей версии 2.6 beta1a, тесты прошли успешно несколько дней назад, но, насколько я могу судить, после обновления посты в Slack не объединяются в потоки. Мы по-прежнему видим отдельные посты по темам и ответы в каналах Slack.