Slack 統合でスレッドを親トピックにオプションで紐付ける機能

仕事では、Slack を非常に頻繁に使用しています。Slack 上でアクセス可能である必要があるコンテンツもありますが、整理され検索可能であるべきです。その点において、Discourse が優れていると私は見ています。ウィキ風のオプションをいくつか試しましたが、それらはすべて、Slack との接続の欠如などの理由で更新されなくなりました。そのため、私は既にコミュニティ用の Discourse フォーラムを運用していることもあり、既存の Slack と並行して動作し、接続された Discourse の評価を進めています。:smiling_face:

ただし、スレッドを積極的に使用するチャンネルが多数あります。これには、Discourse と Slack の間で双方向(watch および post)に統合する優先度最高の Slack チャンネルも含まれます。

チャット統合プラグインに対して、デフォルトではないモードを実装することは無理でしょうか?このモードでは、新しいトピックを Slack のメッセージとして投稿し、Slack メッセージ ID とトピックの関連付けを保存し、そのトピックへの新しいコメントをスレッド付きメッセージとして Slack に送信します。私のユースケースでは、これが成功と失敗の主な分岐点になる可能性があります。

更新:私のユースケースでは、これはサイト全体の Slack チャット設定ではなく、watch のオプションとなります。「スレッドを優先する」か「スレッドを優先しない」かは、Slack チャンネルの目的(および典型的な参加者)に基づいた、チャンネルごとの設定だからです。

「いいね!」 4

これは素晴らしいアイデアですね!プラグインにその機能を追加するのは、間違いなく pr-welcome です。

確認させてください。「投稿」というのは、既存のトランスクリプト投稿機能を指していますか?それとも、Slack のスレッドを Discourse のトピックと「同期」させようとしているのでしょうか。後者の実装は非常に複雑になる可能性が高く、おそらく chat-integration プラグインには収まらないでしょう。

「いいね!」 1

いいえ、単一のスレッドを双方向に同期させて、どちら側からでも投稿し、もう一方にも反映させるようなことは意図していません。私は、非常に活発な 2 つのドメイン間で完全な双方向同期を実装する責任を負ったことがあり、そこで起こりうる問題点については十分に認識しています。:smiling_face:

私たちのシナリオは、以下のようなチャンネルです:

  • スレッド形式での回答が一般的です。このチャンネルは特定のトピックではなくビジネス目的のために設けられており、無関係なトピックに関する同時進行の会話が収集されがちだからです(現実的な代替案として、エンジニアリング部門の半分を、1 日に十数回も作成される一時的な新しいチャンネルに招待するのは非現実的です)。
  • これらのスレッド会話の多く(すべてではありません)は、後で誰かが答えを求めているであろう質問への回答として特定されるべきであり、その統合を使って、それらを Discourse の関連カテゴリで信頼性の高いものとして推奨します(私のように有用な回答を積極的にキュレーションする人のような役割です)。
  • Discourse のその関連カテゴリでの新しいトピックは、Slack のそのチャンネルへの投稿として反映されるべきです。
    • それらの新しいトピックに対する追加のコメントは、初期の新しい Slack 投稿に続くスレッドとして Slack に投稿されるべきです。
  • ユーザーは、Slack で質問する前にまず Discourse を検索するよう案内されています。

さらに、あなたがこの質問をしてくれたことで、関連機能として、Slack のスレッドを Discourse の投稿に要約する際に、その統合が要約された元の Slack スレッドの末尾に、新しい Discourse トピックへのポインタを投稿できる機能があると素晴らしいと考えました。これにより、会話を 1 つの場所に集約しやすくなります。

これは実際、元の機能アイデアと密接に関連しています。なぜなら、両方の機能があれば、要約時に新しい Slack メッセージを投稿する代わりに、要約されたスレッドにメッセージを投稿し、そのスレッドを Discourse の追加コメントを投稿すべき場所としてマークすることが理にかなっているからです。そのスレッド内の追加の Slack コメントを Discourse に要約することはありません。そのトピックに関する会話を Discourse へ誘導することが目的です。これは論理的だと考えられます:

  • 前提:トピックに関連する Slack メッセージ ID を保存できる場所がある。
  • かつ:トピックへの新しいコメントは、保存された Slack メッセージへのコメントとして投稿される。
  • 結果:post thread Slackbot 統合機能を使用する際に、トピックの Slack メッセージ ID を設定し、そのスレッド内でトピックへの新しい Discourse コメントを通知し、Discourse のトピック/コメントへのリンクを含める。

これにより、「質問する前にまず Discourse を確認する」という概念を浸透させるのに大きく貢献するでしょう。

「いいね!」 5

それはすべて私にとって素晴らしいですね!

:100:

「いいね!」 3

ビジュアル的な補助として、これはあなたが推進したい Slack 側の UX に見えますか?

… おや、スレッドの投稿者から年が抜けていますね。何か予想はありますか?

@riking 部分的にそうですね。ただし、いくつかの違いがあります。

発表の形式はそれほど単純にはならないでしょう。これは、統合の watch 側によって投稿されます。「移動された」という旨は記載されません。以下は、私が makerforums に実装した Slack 統合からの、現在の(スレッド化されていない)インターフェースの例です。

スレッドモデルでは、これらの投稿の最初のものが Slack スレッドを開始し、Nedman のコメントはスレッド化された Slack 応答として表示されます。post thread :thread_url が使用された場合、:thread_url は新しいトピックに保存され、チャット統合の watch 側が、初期のトピック投稿と、それ以降のすべてのコメントをその Slack スレッドに投稿しますが、コンテンツは同じです。

watch thread 統合は Discourse に移動させ、そこでタイトルを入力し、投稿する前に新しいトピック投稿を編集する機会を与えます。したがって、Slack に投稿される発表には、すでに post thread を実行した人の名前が著者として記載され、次にトピックタイトルがリンクテキストとして表示され、それが Discourse へのリンクとなり、その後に投稿の冒頭からの引用が表示されます。ここで提案している変更は、デフォルトではなくチャンネルごとの設定(サイト全体のチャット統合プラグイン設定ではなく、watch オプション)を用いることで、そのコンテンツをチャンネルではなくスレッドに投稿するということです(「チャンネルにも送信」ではありません。これでは私たちの変更の目的が果たせなくなります)。Discourse のその新しいトピックに対する追加のコメントも、同じ Slack スレッドに送られます。

そして、推測を求められているので、2017 年、Slack がスレッドを導入した年でしょうか?

「いいね!」 2

これについて考え、chat.postMessage Slack API ドキュメントを読んだ結果、私の長々とした説明をより単純なものに簡略化できると考えました。

現在、follow ではなく watch のみがスレッド応答を選択できる機能を持っていますが、その仕組みについてはまだ調査中です。あるいは、@david さん、優先順位を mutethreadwatchfollow とする新しい thread ルールフィルターを導入し、そのルールを trigger_notification に流してルールに応じた動作を実現するのはどうでしょうか?

  1. watch がスレッド化するように設定されている場合(あるいは thread ルールが定義されている場合)、新しい投稿の通知を Slack チャンネルに送信する際、その投稿トピックに Slack の ts が関連付けられていれば、その ts 値を thread_ts として設定し、該当する Slack スレッドに投稿します。

  2. 新しい投稿の通知を Slack チャンネルに送信する際、その投稿トピックに ts が関連付けられていない場合は、トピックに対して返されたレスポンスの ts を保存します(これにより、将来そのトピックへの投稿を watch がスレッド化するように設定されている場合にスレッド化できます)。

  3. post thread :thread_url コマンドを使用する際、作成されるトピックにスレッドの ts を保存します。これはスレッド化された watch ルールでのみ使用されます。

現在の考えと懸念点は以下の通りです:

  1. ルールごとにスレッドへの投稿を決定する方法。現時点では新しいフィルターが最も簡単だと考えられますが、何か見落としているかもしれません。

  2. 元の Slack 投稿 URL とスレッド ID をトランスクリプトフローに渡す処理が、現在最も不明確です。これを実現するには、プロバイダーごとのスレッド ID をどこかに追加し、投稿を保存するまで保持する必要があるようです。現在は Slack の ts に対してのみ実装しますが、スレッド機能を備えた他のチャット統合も想定されます。

  3. 投稿については、一般的な DiscourseChat のカスタムスレッドフィールドではなく、Topic に Slack 固有のカスタムフィールドとして Slack の ts を保存する必要があると考えます。

「いいね!」 1

「threading」ブール値は本当にルールごとに必要なのでしょうか?新しいサイト設定

chat_integration_slack_thread_responses

を作成するのはどうでしょうか。これが有効で、トピックのスレッドIDの記録があれば、その後の通知をSlackのスレッドに送信します。

はい、それで全く問題ないと思います。Slack固有のトピックカスタムフィールドを使用してください。将来的に他のプロバイダー向けにこの機能を実装する必要があると感じたら、より汎用的なソリューションに作り直すことができます。

はい、これは非常に難しい問題です。v1としては、以下のようなものを投稿の先頭に含めることを検討したいです。

<!--SLACK_THREAD_ID=abcdefg-->

その後、プラグインがこの文字列で始まる投稿を検査し、カスタムフィールドを割り当てることができます。完璧な解決策ではありませんが、良い出発点になるかもしれません。

「いいね!」 2

ありがとうございます!

昨夜、カスタムフィールドを Topic に追加し、thread ルールを使用して、最初の 2 つの AC を実装し、スタック全体でテストをパスさせました(まだライブ環境でのテストは行っていません)。トランスクリプトフローはまだ実装していませんが、少なくともドラフト PR でコードを表示できるようになる方向で順調に進んでいます。

また、スラックプロバイダーから未使用の pstore_get を削除する別のコミットもあります。スタック全体で pstore の使用はこの箇所のみなので、このクリーンアップコミットで app/initializers/discourse_chat.rb 内のすべての pstore_* も削除してもよろしいでしょうか?

まさにそこから始めましたし、確かにそれが簡単だったでしょう!

しかし、少なくとも私のユースケースでは(他社の皆様からも同様の声を聞いており、私たちが特別というわけではありません)、チャンネルによってスレッドを使用するかどうかの好みが異なります。スレッドを使用することを意図したチャンネル(ほとんどの人が特定のトピックのみに関心があるため)と、スレッドを強く嫌うチャンネル(スレッドが重要な情報を埋もれさせてしまうため)があります。

この好みを決定づけている、本質的に無関係な 2 つの側面を目撃しました:

  • 会員構成:長年 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 を検討した結果、フィルタに留める方がクリーンだと考えます。]

ポストトランスクリプトフローについては、HTML コメントのアイデアをありがとうございます。私のユースケースでは問題になりません。正直言って、少なくとも最初は私が主要なユーザーになることを想定しています。シンプルで素敵なハックですね。

この PR には含めない別のアイデアとして、投稿されるメッセージのチャンネルから、生成される Discourse ポストが作成されるカテゴリへのマッピングがあると良いと思います。そのためには、トランスクリプトをエンベロープまたはサイドカー形式に変更するのが最適だと考えます。そうすれば、エンベロープまたはサイドカーにカテゴリとスラック 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(送信しない)になりますが、任意の値に設定可能です。概念的には比較的シンプルですが、単純なフラグを設定するかどうかを判断するために、スレッドを取得する必要があります(元々はトランスクリプト用に書かれたコードを使用します。リファクタリングが必要かどうかは、その場で即座には判断できません)。

もしあなたがこれに取り組みたいのであれば、私が現在行っていることが良い枠組みを提供してくれることを願っています。ただ、デフォルトで有効にしないようお願いします。もしアップグレード時にこれが有効になり、私が Discourse にコンテンツを選別していることでユーザーが「スパム」された場合、ユーザーが不満を持つことになるからです。

「いいね!」 1

単純化のために、Discourse トピック内の直前の投稿の日付を確認するだけでよいと思います。

(いくつかの場合には少し異なる動作になりますが、始めるには良い方法かもしれません)

@david ドラフトの PR をアップロードしました。私が書いた単体テストはすべて通過しています。まだ Slack に対して実際に実行してテストしていないため、その作業が完了するまでマージしたくありません。少なくとも、私の環境ではすべての単体テストが通過し、それらに対して意味のあるテストを追加するよう努めました。

また、ID のコメントを投稿の最初ではなく最後に配置しました。そうすることで、より長く残る可能性が高く、改変されるリスクが低いと感じたためです。また、それを解析する際にも慎重なアプローチを試みました。

このプラグインの開発にご尽力いただき、ありがとうございます!

最初のリンティングエラーは修正しましたが、私が変更していないテストが失敗するようになりました。最新のマスタをベースにしており、ローカルではテストは通過します。失敗しているテストについて何かご存知でしょうか?

「いいね!」 4

PR を大幅に整理しましたが、まだ本番リリースの準備が整っていません。現在、修正方法がわからない問題が 2〜3 件あります。

  1. スレッドアイコンに fa-arrow-circle-o-right を使おうとしていますが、本番サイトの UI では空表示になってしまいます。(ブランチを本番サーバーにチェックアウトした後、su discourse -c 'bundle exec rake assets:precompile' && sv restart unicorn を実行してテストしています。)plugin.rb にも追加し、参照も設定しましたが、次の手順がわかりません。Discourse で使用が許可されている Font Awesome アイコンのリストはありますか? lib/svg_sprite/svg_sprite.rb を発見し、chevron-right がこの用途に最適だとわかりました。

  2. ローカルではすべてのテストがパスしていますが、Travis では私の変更とは無関係に見える一貫したエラーが発生しています。当然ながら、これの調査や原因特定は困難です。spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb で、期待されるレスポンス(例:200)の代わりに 404 が返り、13 件の失敗が確認されました isolate_namespace を無闇に書かないように修正し、rake routes の存在も知るに至りました。

投稿には成功しました:

まだ整理が必要な部分もあるかもしれませんが、これで動作すると思います。

マージ後、Discourse Chat Integration を適切に更新します。

「いいね!」 2

ここで学ぶ新しい機会を次々と見つけています。今は yarn prettier の実行方法を知りましたが、次はフロントエンドのテストの更新方法を学ぶことになります…

エラー: アサーションに失敗しました:`channel` プロパティ(`<(unknown):ember3806>` の)を `<(unknown):ember3799>` に設定するには、`set()` を使用する必要があります。

この場所でのあなたのすべての仕事に心から感謝します、@mcdanlj - これは今マージされました:

「いいね!」 4

とても役立つレビューをありがとうございます!お約束通り、公式統合ウィキの投稿を更新しました。変更点を他の方法で強調したい場合は、それもいいですよ。執筆者としての自負とか、そういうものはありませんので。:smiling_face:

「いいね!」 3

チャット統合の設定で、Slack に対してスレッド機能を有効にしてください。

Slack への投稿のスレッド化を有効化

つまり、統合において thread オプションを無視するようにプラグインを設定したい、ということですね?

数日前に現在の 2.6 ベータ版 1a にアップデートし、テストは通過しましたが、アップグレード以降、Slack へのクロス投稿がスレッド化されていないようです。現在も、Slack チャンネルではトピック投稿と返信が個別に表示されています。