슬랙 통합에서 게시물을 상위 주제에 선택적으로 스레딩

직장에서 우리는 슬랙을 많이 사용합니다. 슬랙에서 접근 가능해야 하지만 동시에 체계적으로 정리되고 검색할 수도 있어야 하는 콘텐츠가 있습니다. 이 두 가지 측면에서 디스커스가 특히 강점을 보인다고 생각해 왔습니다. 몇 가지 위키형 옵션을 시도해 봤지만, 모두 슬랙과의 연결 부족 등 여러 이유로 방치되는 경향이 있었습니다. 그래서 저는 이미 커뮤니티 디스커스 포럼을 운영 중인 입장에서, 기존 슬랙과 병렬로 운영되고 슬랙과 연결되는 디스커스 도입을 검토하고 있습니다. :smiling_face:

다만, 우리는 스레드를 적극 활용하는 채널이 많습니다. 이는 디스커스와 슬랙 간 양방향(watch 및 post) 통합을 위한 최우선 슬랙 채널도 포함됩니다.

채팅 통합 플러그인에 기본값이 아닌 모드를 추가하는 것이 플러그인의 구조를 크게 해치지 않을 것 같습니다. 이 모드는 새 주제를 슬랙 메시지로 게시하고, 슬랙 메시지 ID와 주제 간의 연관성을 저장한 후, 해당 주제에 대한 새 댓글을 슬랙에 스레드 메시지로 전송하는 방식입니다. 제 사용 사례에서 이것이 성공과 실패를 가르는 핵심 차별점이 될 수 있습니다.

추가: 제 사용 사례에서 이 기능은 사이트 전체 슬랙 채팅 설정이 아니라 watch 옵션이어야 합니다. “스레드 우선” 또는 "스레드 비우선"은 슬랙 채널의 목적(및 일반적인 참여자)에 따라 채널별로 설정되는 선호 사항이기 때문입니다.

4개의 좋아요

정말 멋진 아이디어네요! 플러그인에 해당 기능을 추가하는 것은 분명히 pr-welcome 입니다.

확인차 여쭤보는데, "게시(post)"라고 하셨을 때 기존 전사본(transcript) 게시 기능을 의미하시나요? 아니면 슬랙 스레드를 디스커스(Discourse) 주제와 '동기화’하려는 건가요? 후자의 경우 올바르게 구현하는 것이 꽤 복잡할 것 같고, 아마도 채팅 통합(chat-integration) 플러그인에 적합하지 않을 것 같습니다.

1개의 좋아요

아니요, 한쪽에서 게시하면 다른 쪽에도 반영되도록 단일 스레드를 양방향으로 동기화하려는 것이 아닙니다. 매우 활발한 두 도메인 간에 active-active 동기화를 위해 완전한 양방향 동기화를 구현한 경험이 있으며, 그 과정에서 발생할 수 있는 오류의 가능성에 대해 충분히 인지하고 있습니다. :smiling_face:

우리의 시나리오는 다음과 같은 채널입니다:

  • 해당 채널은 서로 무관한 주제에 대한 동시 대화가 많이 이루어지는 경향이 있기 때문에(채널은 특정 주제보다는 비즈니스 목적에 전념하며, 비현실적인 대안은 엔지니어링 팀의 절반을 하루에 수십 번씩 생성되는 임시 신규 채널로 초대하는 것입니다) 스레드형 답변이 일반적입니다.
  • 이러한 스레드형 대화 중 일부(모두는 아님)는 나중에 다른 사람이 답을 원할 질문의 답변으로 식별되어야 하며, 이를 Discourse의 관련 카테고리에 신뢰할 수 있는 것으로 홍보하는 데 사용되는 통합 기능(유용한 답변을 능동적으로 큐레이션하는 저 같은 사람이 관리)이 필요합니다.
  • Discourse의 해당 관련 카테고리에서 새 주제가 생성되면 Slack 채널에 Slack 게시물이 생성되어야 합니다.
    • 이러한 새 주제에 대한 추가 댓글은 Slack에서 초기 새 Slack 게시물에 이은 스레드로 게시되어야 합니다.
  • 사용자는 Slack에서 질문하기 전에 먼저 Discourse를 검색하도록 안내받습니다.

또한, 질문을 던지신 덕분에 관련 기능으로 Slack 스레드를 Discourse 게시물로 요약할 때, 통합 기능이 방금 요약된 원래 Slack 스레드의 끝에 새로운 Discourse 주제에 대한 포인터를 게시할 수 있으면 좋겠다는 생각이 듭니다. 이는 대화를 한곳에 유지하는 데 도움이 될 것입니다.

이것은 사실 원래 기능 아이디어와 연결되어 있습니다. 두 가지 기능이 모두 있다면, 요약 시 새 Slack 메시지를 게시하는 대신 요약된 스레드에 메시지를 게시하고, 해당 스레드를 추가 Discourse 댓글을 게시할 장소로 지정하는 것이 합리적일 것입니다. 해당 스레드의 추가 Slack 댓글을 Discourse로 요약하지는 않으며, 해당 주제에 대한 대화를 Discourse로 유도하는 것이 의도입니다. 저에게는 이것이 논리적으로 보입니다:

  • GIVEN: 주제와 연관된 Slack 메시지 ID를 저장할 장소가 있습니다.
  • AND: 주제에 대한 새 댓글은 저장된 Slack 메시지에 대한 댓글로 게시됩니다.
  • THEN: post thread slackbot 통합 기능을 사용할 때 주제의 Slack 메시지 ID를 설정하여, 주제에 대한 새 Discourse 댓글이 해당 스레드에 공지되도록 하고, Discourse 주제/댓글로 돌아가는 링크를 포함합니다.

이것은 "질문하기 전에 먼저 Discourse를 확인하세요"라는 개념을 사회화하는 데 정말로 도움이 될 것입니다.

5개의 좋아요

전부 괜찮아 보입니다!

:100:

3개의 좋아요

시각 자료로, 이 모습이 슬랙(Slack) 측에서 홍보하고자 하는 UX인가요?

… 어머, 스레드 시작 날짜에서 연도가 빠졌네요. 추측해 볼 수 있을까요?

@riking 어느 정도는 그렇지만, 몇 가지 차이점이 있습니다.

공지(announce)는 그렇게 보이지 않을 것입니다. 통합 기능의 watch 측에서 게시됩니다. 이동되었다고 언급하지도 않을 것입니다. makerforums에 제가 구현한 slack 통합 기능의 현재(스레드 없음) 인터페이스 예시는 다음과 같습니다:

스레드 모델에서는 해당 게시물 중 첫 번째가 slack 스레드를 시작하고, Nedman의 댓글은 대신 스레드형 slack 응답으로 표시됩니다. post thread :thread_url이 사용되면 :thread_url이 새 주제와 함께 저장되고, 채팅 통합 기능의 watch 측이 해당 slack 스레드에 초기 주제 게시물 그리고 모든 추가 댓글을 게시하지만, 콘텐츠는 동일합니다.

watch thread 통합 기능은 discourse로 이동하여 제목을 작성하고 게시 전에 새 주제 게시물을 수정할 수 있는 기회를 제공합니다. 따라서 slack에 게시되는 공지에는 post thread를 실행한 사람을 저자로 표기하고, 주제 제목을 링크 텍스트로 하여 discourse로 연결되는 줄이 있으며, 게시물 시작 부분의 인용문이 포함됩니다. 여기서 제안하는 변경 사항은 기본값이 아닌 채널별 구성(즉, 사이트 전체 채팅 통합 플러그인 구성이 아닌 watch 옵션)을 통해 해당 콘텐츠를 채널이 아닌 _스레드_에 게시하는 것입니다. ("채널에도 함께 전송"은 우리 목적을 무효화하므로 해당되지 않습니다.) discourse에서 해당 새 주제에 대한 추가 댓글도 동일한 slack 스레드에 들어가게 됩니다.

그리고, 추측을 원하신다면, slack가 스레드를 출시한 2017년일 것입니다?

2개의 좋아요

이 문제에 대해 고민하며 chat.postMessage Slack API 문서를 읽어보았는데, 내 긴 설명을 훨씬 더 간단한 것으로 정리할 수 있을 것 같습니다.

watch만 follow와 달리 어떤 메커니즘을 통해 스레드 응답을 선택할 수 있는지 아직 파악 중입니다. 아니면 @david, mute thread watch follow 우선순위를 가진 새로운 thread 규칙 필터를 도입하고, trigger_notification을 통해 규칙을 전달하여 규칙에 민감한 동작을 활성화하는 방식은 어떻게 생각하시나요?

  1. watch가 스레드로 설정되어 있는 경우(또는 thread 규칙이 정의된 경우), Slack 채널에 새 게시물 알림을 보낼 때 해당 게시물 토픽에 Slack ts가 연결되어 있다면, Slack에서 제공된 ts 값을 thread_ts로 설정하여 해당 Slack 스레드에 게시물을 게시합니다.

  2. Slack 채널에 새 게시물 알림을 보낼 때, 해당 게시물 토픽에 ts가 연결되어 있지 않다면, 토픽에 대한 반환된 응답의 ts를 저장합니다(이렇게 하면 watch가 스레드로 설정되어 있을 경우 해당 토픽의 향후 게시물들을 스레드로 묶을 수 있습니다).

  3. post thread :thread_url 명령을 사용할 때, 생성되는 토픽에 스레드 ts를 저장합니다. 이 값은 스레드 watch 규칙에서만 사용됩니다.

현재 제 생각과 우려 사항은 다음과 같습니다:

  1. 규칙별로 스레드에 게시할지 여부를 어떻게 결정할 것인가. 현재로서는 새로운 필터를 추가하는 것이 가장 쉬워 보이지만, 제가 무언가를 놓치고 있는 것일 수도 있습니다.

  2. 원래의 Slack 게시물 URL과 스레드 ID를 전사(transcript) 흐름을 통해 전달하는 부분이 현재 가장 불분명합니다. 게시물을 저장할 때까지 유지하기 위해 어딘가에 제공자별(provider-specific) 스레드 ID를 추가해야 할 것 같습니다. Slack ts에 대해서만 구현할 계획이지만, 아마도 스레드를 지원하는 채팅 통합은 Slack만이 아닐 것입니다.

  3. 게시물을 위해 Slack ts를 일반적인 DiscourseChat 커스텀 스레드 필드가 아니라 Topic의 Slack 전용 커스텀 필드에 저장해야 한다고 생각합니다.

1개의 좋아요

‘threading’ 부울 값이 규칙별로 정말 필요합니까? 왜 새 사이트 설정을 만들지 않나요?

chat_integration_slack_thread_responses

이 설정이 활성화되어 있고, 해당 토픽의 스레드 ID 기록이 있다면, 이후 알림을 Slack 스레드로 보내면 됩니다.

네, 전혀 문제가 없다고 생각합니다. Slack 전용 토픽 커스텀 필드를 사용하면 됩니다. 나중에 다른 제공업체에 대해 이 기능을 구현해야 한다고 판단되면, 해결책을 더 일반화할 수 있습니다.

네, 이것은 매우 까다로운 문제입니다. v1에서는 다음과 같은 것을 포함하는 것이 좋을 것 같습니다.

<!--SLACK_THREAD_ID=abcdefg-->

게시물 상단에 이 문자열을 배치하면 됩니다. 그러면 플러그인이 이 문자열로 시작하는 게시물을 확인하고 커스텀 필드를 할당할 수 있습니다. 완벽하지는 않지만, 좋은 시작점이 될 수 있습니다.

2개의 좋아요

정말 감사합니다!

어젯밤에 스택 전체에서 테스트가 통과하는 상태로 첫 번째 AC 두 개를 구현했습니다(다만 아직 라이브 환경에서는 테스트하지 않았습니다). 단, 전사(transcript) 플로우에는 아직 적용하지 않았습니다. Topic에 커스텀 필드를 사용하고 thread 규칙을 적용하는 방식으로 구현했습니다. 따라서 적어도 초안 PR에서 코드를 보여줄 수 있을 정도로 좋은 진전을 이루고 있습니다.

또한, 사용되지 않는 pstore_get을 slack 프로바이더에서 제거하는 별도의 커밋도 작성해 두었습니다. pstore의 유일한 사용처가 이것이라면, 해당 정리 커밋에서 app/initializers/discourse_chat.rb의 모든 pstore_*도 함께 제거해 드릴까요?

저도 정확히 그 부분에서 시작했고, 그렇게 했다면 훨씬 쉬웠을 것입니다!

하지만 제 사용 사례(그리고 다른 회사에서도 비슷한 이야기를 들었으니 우리만의 문제는 아닙니다)를 고려할 때, 스레드 사용 여부에 대한 선호도가 채널마다 다릅니다. 스레드를 사용하도록 설계된 채널(대부분의 사람들이 일부 주제에만 관심을 두기 때문)과 스레드를 극도로 꺼리는 채널(스레드가 중요한 정보를 묻어버리기 때문)이 있습니다.

이 선호도를 이끄는 본질적으로 무관한 두 가지 측면을 확인했습니다:

  • 소속: 수십 년간 IRC를 능숙하게 사용해 온 멤버들이 대부분인 채널은 단일 채널 내 뒤섞인 대화 스레드를 정신적으로 구분하는 데 익숙하며, 중요한 내용을 보기 위해 스레드를 클릭하는 것을 원하지 않습니다. 반면, 이메일 환경에서 생활해 온 멤버들이 대부분인 채널은 대화가 스레드 형태로 구성되고, 관심 있는 대화를 클릭해서 보는 것을 기대합니다.
  • 목적: 공지사항 성격의 비즈니스 목적을 가진 채널은 공격적으로 스레드를 사용하는 경향이 있지만, 연구나 협업 목적의 채널은 의도적으로 스레드를 사용하지 않는 경우가 많습니다. 이는 스레드가 정보를 숨기며, 이를 알아채고 클릭하지 않는 한 접근할 수 없기 때문입니다.

규칙 옵션에 대해 공통 구문을 원하신다면, Rule을 :tags와 마찬가지로 배열인 :options 값을 가질 수 있도록 일반적으로 확장하는 것이 좋다고 생각합니다. 커맨드라인 셸의 방식을 차용하는 것도 합리적일 수 있습니다. 예를 들어 /discourse [watch|follow|mute] -something -here를 입력하면 :options가 ['something', 'here']로 설정되는 방식입니다. 여기서 앞선 -는 옵션을 도입하는 용도로 예약됩니다. 그러면 /discourse watch my-category-slug #tagged-foo -threaded와 같이 사용할 수 있습니다. 제가 이미 한 일보다 이 방식이 얼마나 더 많은 작업을 필요로 하는지 확신은 없습니다. 이 문제에 대해 강한 의견이 있으신가요? 양쪽 모두 논리가 성립합니다: Rule에 값을 하나 더 추가하면 채팅 프로바이더를 작성하는 것이 더 복잡해지고, 필터 값을 하나 더 추가하면 슬랙 전용 기능(예: 전사 게시)이 하나 더 생겨 슬랙 외 사용자에게 인터페이스가 더 복잡해집니다. 물론 제가 놓치고 있는 부분이 있을 수 있습니다. 예를 들어, 카테고리 슬러그가 -로 시작할 수 있다면 갑자기 모호해지거나, 셸은 --를 "이 이후의 모든 것은 인수가 아님"으로 사용하지만, 우리는 --를 "이 이후의 모든 것은 옵션"으로 반전할 수도 있습니다. 이 부분을 조사해 보기를 원하신다면, 규칙 옵션을 지정하는 데 적절하다고 생각하시는 구문에 대해 방향을 잡아 주십시오. 하지만 단순히 thread를 추가하는 것이 제게는 더 단순해 보이므로, 일반적인 “옵션” 기능을 추가하라는 구체적인 지시가 없다면 그 방향으로 변경을 보류하겠습니다.

[편집: 필터를 옵션으로 변경하는 것은 UI를 확실히 복잡하게 만들 것입니다. UI는 일반적인 옵션에 대한 일반적인 지원을 위해 확장되어야 하므로, 이는 좋은 선택으로 보이지 않습니다. 따라서 이제 UI를 살펴본 결과, 필터를 유지하는 편이 더 깔끔하다고 생각합니다.]

게시물 전사 플로우에 대해, HTML 주석 아이디어에 감사합니다. 제 사용 사례에서는 이로 인해 불이익이 되지 않을 것입니다. 솔직히 말해, 적어도 초기에는 제가 주요 사용자가 될 것으로 예상합니다. 아주 간단하고 좋은 해킹(hack)입니다.

이 PR에 포함시키지는 않겠지만, 게시 중인 메시지의 채널에서 결과적으로 생성되는 디스코urs 포스트가 만들어질 범주로 매핑하는 기능이 있으면 좋겠다는 별도의 아이디어가 있습니다. 이를 위해, 전사(envelope)나 사이드카(sidecar)를 도입하는 것이 가장 좋다고 생각합니다. 그러면 그 envelope이나 sidecar에 카테고리 ID와 슬랙 ID를 모두 포함할 수 있습니다. 저는 여전히 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(보내지 않음)이고 원하는 값으로 설정할 수 있습니다. 개념적으로는 꽤 단순하지만, 단순한 플래그를 설정하기 위해 판단을 내려야 하므로 더 많은 작업이 필요합니다. (초기 전사(transcripts)용으로 작성된 코드를 사용해 스레드를 가져와야 하는데, 리팩터링이 필요한지는 바로 떠오르지 않습니다.)

하지만 이 작업을 진행하시길 원하신다면, 제가 하고 있는 작업이 좋은 프레임워크가 되어줄 것이라고 생각합니다. 다만 기본값으로 켜지도록 설정하지는 말아 주세요. 업그레이드 시 이것이 적용되어 제가 디스코스로(Discourse) 큐레이션한 콘텐츠로 사용자들에게 "스팸"을 보내는 상황이 발생하면 불만족스러운 사용자들을 만들게 될 테니까요.

1개의 좋아요

더 단순하게 하려면, 대신 Discourse 토픽의 이전 게시글 날짜를 확인하는 것이 좋을 것 같습니다.

(일부 경우 동작 방식이 조금 다를 수 있지만, 시작점으로 충분히 좋습니다.)

@david 작성한 단위 테스트를 통과하는 초안 PR을 올려 두었습니다. 아직 Slack에서 라이브로 실행해 보지 않아, 그 작업이 완료되기 전에는 병합을 하고 싶지 않습니다. 하지만 적어도 제 환경에서는 모든 단위 테스트가 통과하며, 의미 있는 테스트를 추가하려고 노력했습니다.

또한, ID 주석을 게시물 끝에 배치했습니다. 시작 부분에 두는 것보다 끝 부분에 두는 것이 더 잘 유지되고 깨질 가능성이 적을 것 같았기 때문입니다. 그리고 이를 파싱하는 과정에서 보수적으로 접근했습니다.

이 플러그인에 대한 작업에 감사드립니다!

초기 린팅 실패를 수정했지만, 이제 건드리지 않은 테스트들이 실패하고 있습니다. 최신 master를 기반으로 하고 있으며, 로컬에서는 테스트가 통과합니다. 실패하는 테스트에 대해 어떤 통찰을 가지고 계신가요?

4개의 좋아요

PR을 많이 정리했지만 아직 완전히 준비되지는 않았습니다. 아직 두세 가지 문제를 해결하는 방법을 모르고 있어 고충을 겪고 있습니다.

  1. fa-arrow-circle-o-right를 스레드 아이콘으로 사용하려고 했는데, 라이브 사이트의 UI에서 빈 상태로 표시됩니다. (라이브 서버에서 테스트하기 위해 라이브 사이트에서 내 브랜치를 체크아웃한 후 su discourse -c 'bundle exec rake assets:precompile' && sv restart unicorn을 실행했습니다.) plugin.rb에 추가하고 참조도 했는데, 다음 단계가 무엇인지 막막합니다. Discourse에서 사용할 수 있는 승인된 FontAwesome 아이콘 목록이 있나요? lib/svg_sprite/svg_sprite.rb를 찾았고, 이 용도로는 chevron-right가 매우 좋습니다.

  2. 로컬에서는 모든 테스트가 통과하지만, Travis에서는 제 변경 사항과 무관해 보이는 일관된 오류가 발생합니다. 당연히 이를 조사하거나 추론하기가 어렵습니다. spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb에서 404가 다른 예상 값(예: 200) 대신 반환되는 13개의 실패가 발생했습니다. isolate_namespace를 무분별하게 복사하지 않고 수정했으며, 이제 rake routes에 대해 알게 되었습니다.

성공적으로 게시했습니다:

더 정리할 부분이 있을 수 있지만, 작동하는 것 같습니다.

이것이 병합된 후, Discourse Chat Integrations 링크를 적절히 업데이트하겠습니다.

2개의 좋아요

여기서 계속 새로운 학습 기회를 발견하고 있습니다. 이제 yarn prettier를 실행하는 방법을 알게 되었고, 다음에는 프론트엔드 테스트를 업데이트하는 방법을 배울 차례입니다…

Error: Assertion Failed: You must use set() to set the `channel` property (of <(unknown):ember3806>) to `<(unknown):ember3799>`.

여기서 해주신 모든 작업에 진심으로 감사드립니다 @mcdanlj - 이제 병합되었습니다:

4개의 좋아요

매우 유용한 리뷰를 작성해 주셔서 감사합니다! 약속대로 공식 통합 위키 게시물을 업데이트했습니다. 변경 사항을 다른 방식으로 언급하고 싶으시다면 그것도 괜찮습니다. 저자로서의 자존심 같은 건 전혀 없으니까요. :smiling_face:

3개의 좋아요

Slack용 채팅 통합 설정에 스레딩 기능이 활성화되도록 해 주실 수 있을까요?

Slack 게시글 스레딩 활성화

인테그레이션에서 thread 옵션을 무시하도록 플러그인을 구성할 수 있기를 원한다는 뜻인가요?

며칠 전 최신 2.6 beta1a 테스트 패치로 업데이트를 완료했지만, 제가 파악한 바로는 업그레이드 이후 Slack의 x-post가 스레드 형태로 표시되지 않고 있습니다. 여전히 Slack 채널에서 토픽 게시글과 답글이 각각 개별적으로 표시되고 있습니다.