Allow sending Private Messages to Staff

I have a client who wants to have people send a form with some information on it. No problem, just Compose a new pre-filled personal message via URL!

But this client also wants to disable private messages for at least most users, so that won’t work. (I tried :frowning:)

One solution would be a site setting that would allow users to be able to send PMs to staff.

Perhaps I’m missing something, bu tI’m afraid the other solutions all require a plugin or some other app. (e.g., Canned replies works only for staff, right?)

「いいね!」 3

Why does this form need to be in Discourse? Just create a Google Docs form or something.

Yeah. That was my idea too. Crazy guy just doesn’t want to leave Discourse.

I’ve got two clients right now who are itching to do everything in Discourse and not have WordPress/Drupal/Squarespace to handle other stuff.

「いいね!」 1

Right but at the point when you’re contorting the system into a :pretzel: maybe a simple Google Docs form would be better?

「いいね!」 1

If I’m reading you right, you want to restrict the target of pms to staff only?

You could do this relatively easily in a standalone plugin. The plugin.rb would read:

# name: only-pms-to-staff
# about: You can only send pms to staff
# version: 0.1
# authors: pfaffman

after_initialize do
  add_to_class('guardian', :can_send_private_message?) do |target|
    target.is_a?(User) &&
    # User is authenticated
    authenticated? &&
    # Have to be a basic level at least
    @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) &&
    # User disabled private message
    (is_staff? || target.user_option.allow_private_messages) &&
    # PMs are enabled
    (is_staff? || SiteSetting.enable_private_messages) &&
    # Can only send pms to staff
    target.staff?
  end
end

The original method is here.

See also: How do disable private messages between non staff users? - #10 by Mittineague

「いいね!」 11

Thanks, @angus!

Here’s what I ended up with. If I were better at understanding the distributed properties of and and or, I’d have moved target.staff? outside of those three expressions, but this seems to do what I wanted. My scant tests show that it allows sending to an admin and if you send to an admin and another user, it is denied.


after_initialize do
  add_to_class('guardian', :can_send_private_message?) do |target|
    target.is_a?(User) &&
      # User is authenticated
      authenticated? &&
      # Have to be a basic level at least
      (target.staff? || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages)) &&
      # User disabled private message
      (target.staff? || is_staff? || target.user_option.allow_private_messages) &&
      # PMs are enabled
      (target.staff? || is_staff? || SiteSetting.enable_private_messages)
  end
end

it doesn’t quite meet my standards for posting to #plugins just yet, but if anyone stumbles here and wants to do this, here’s this:

「いいね!」 10

On the face of it, these changes allow:

  1. Any user who has the min trust level to send a pm, to send a message to any other user who has not disabled pms, regardless of whether or not they are staff.

    The issue is this line:

    target.staff? || is_staff? || SiteSetting.enable_private_messages

    The first alternative, i.e. target.staff?, is redundant, as the last alternative will always be true as long as pms are turned on.

    The is_staff? check here is used to ensure that staff members can still perform an action even if that action is disabled (this is normal practice in the Discourse code). Keep those two as the only alternatives in that line, i.e.

    (is_staff? || SiteSetting.enable_private_messages)

    There was an issue with my initial code, as it didn’t allow staff members to send messages to non-staff members. The way to fix that is by adding the is_staff? check to that line specifically, i.e.

    (is_staff? || target.staff)

  2. Any user of any trust level to send a message to a staff member (e.g. immediately after joining).

    The issue is this line:

    (target.staff? || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages))

    This means that if the target is a staff member you don’t need the min trust level. Probably best to require the min trust level for all messages.

  3. If a staff member has specifically dis-allowed pms to be sent to them, you will still be able to send pms to them.

    The issue is this line:

    (target.staff? || is_staff? || target.user_option.allow_private_messages)

    Unless you want pms to reach staff members even if they have specifically disabled them, remove target.staff? from this check.

「いいね!」 9

First, I really appreciate your help.

But that didn’t seem to be the case, when I tested. I even tested sending to a staff and a non-staff person in a single message and it was rejected.

target.staff? || is_staff? || SiteSetting.enable_private_messages

The way I read that, it’s

  • the receiver is staff OR
  • the sender is staff OR
  • private messages are enabled (and they’re not for this site, which is what I’m trying to solve)

And I (or this client) want everyone to be able to send to staff.

Hooray! That’s what I wanted! :tada: (Of course, it could prove to be a problem, but we can solve it when there is one) It’s good advice to change that to TL1, though. I made a note of that too.

Ah, that’s (but one of the reasons) why I don’t think anyone should use this. For this site, I’m sure that no staff will be disallowing PMs. I should probably fix this one. I added a comment to remind me to do so when I can “test” – not to be confused with writing a proper test! (Or maybe I want to make sure that a staff member who needs to receive these messages doesn’t inadvertently disable PMs :slight_smile: – A documented bug is a feature!)

Thanks again, @angus! A couple more trivial plugins under my belt and I might do something useful!

「いいね!」 5

Ah, I had assumed you were going to keep the site setting on. That change in logic makes a bit more sense now :slight_smile:

However, I think you may want to keep the site setting on and restrict pms just via the guardian though. If the site setting is off this will also:

  1. Disable message-related elements in the UI, specifically the messages icon in the user menu will not appear and the private messages button will not appear in the user profile.

  2. Prevent the user from taking the notify_user and notify_moderator post actions (see here). These post actions require private messages.

And there may be more instances of that setting being used to disable functionality in the future.

If I’m reading you right, your case is one of permissions, not one of functionality? You still want the functionality, just a restricted version of it.

edit: re-reading your first post, maybe you do want to disable the functionality entirely! Well at least we thought this through.

「いいね!」 7

This is how my naive solution is so lucky! The plan is to use a URL to generate the initial message, so not being able to see the PM interface is a bonus!

That’s pretty fine too, as this is basically doing the same thing as using a Google form would be. It’s mostly for a one-way initiation of a conversation. I should check what happens if someone replies to the PM, though.

Ah, yes. The Royal “We”. Thanks very much for your help. You’ve taught me a lot and I appreciate it.

「いいね!」 3

ジェイ、これに対する解決策は見つかりましたか?

同様の問題に直面しています。通常の 1 対 1 のプライベートメッセージを禁止することで、この問題は非常にきれいに解決できるはずです。これはボランティア組織で、ボランティアがコーディネーターとコミュニケーションを取る必要がありますが、ボランティア同士でのやり取りは理想的には避けてほしいと考えています。

「いいね!」 4

上記のプラグイン(https://github.com/pfaffman/discourse-allow-pm-to-staff)は機能します。保証はいたしかねますが、発注したクライアントが現在も使用しており、活発にメンテナンスされています。さらに、travis で実行されるテストも備えています。

「いいね!」 4

@pfaffman さん、@angus さん、共有ありがとうございます!

@Stephen さん、これは動作していますか?

これは約束なしで無料で提供されたものだと理解していますが、本当に感謝しています。:slight_smile:

念のためお知らせしますが、現在は動作していないようです。何か設定を間違えている可能性はありますが、プラグインはインストールされ、有効化されています。

「メッセージ送信に必要な最低信頼レベル」を 1 に設定し、TL0 のユーザーがスタッフにプライベートメッセージを送ろうとした場合と、「メッセージ送信に必要な最低信頼レベル」を 2 に設定し、TL1 のユーザーがスタッフにプライベートメッセージを送ろうとした場合の両方をテストしました。

どちらの場合も、ユーザーの TL が「メッセージ送信に必要な最低信頼レベル」の設定値より低い場合、スタッフのプロフィールページからプライベートメッセージを送るボタンは通常ユーザーアカウントには表示されませんでした。また、対象のスタッフユーザーの設定でもプライベートメッセージの受信は有効になっています。

これは、2.5.0 stable バージョンと 2.6.0.beta1(テスト合格)の両方で確認しました。

stable バージョンでは、/u/username/messages ページから手動でメッセージを作成し、スタッフを宛先として入力して送信を試みましたが、送信時にメッセージは拒否されました。

「いいね!」 2

さて、私の開発環境(2.6.0.beta1)および本番環境(2.5.0.beta4)では問題なく動作しており、Travis のテストも引き続きパスしています。

私の推測では、マルチサイト環境では動作しないのではないかと思われますが、あなたはマルチサイト環境で実行されていますか?

「いいね!」 2

それが機能しているとのこと、素晴らしいですね!もしかすると、何か見落としているのかもしれません。これはマルチサイトではなく、標準的な Docker インストールでの話です。

実施した手順は以下の通りです。

  • https://github.com/pfaffman/discourse-allow-pm-to-staff.git からプラグインをインストールしました。このプラグインを特に有効化したり、プラグイン固有のオプションを設定したりはしていませんが、/admin/plugins では「enabled?」が Y に設定されているようです。

  • 「メッセージを送信するための最低信頼レベル」を調整し、そのレベルより低い TL の通常ユーザーアカウントでスタッフにメッセージを送ろうとしてテストしました。

  • 競合の可能性を排除するため、安定版 2.5.0 でこのプラグイン以外をすべて無効にしてみましたが、変化はありませんでした。

「いいね!」 1

何が問題だったか分かりました :partying_face:

Travis テストをカスタマイズ/設定していなかったため、プラグインが機能しなくなっていたようです。

そこで、plugin.rb ファイル以外はすべて削除して試したところ、私の環境では動作し始めました。また、私のユースケースに合わせてロジックも少し変更しました。

現在の仕様では、TL0 以上のユーザーは、設定された「メッセージ送信に必要な最低信頼レベル」を下回った場合に管理者にメッセージを送信できますが、モデレーターには送信できません。

これを修正するには、以下の部分を手軽に変更する必要があります(明確なコメントに感謝します :slight_smile: ):

# 最低でも基本レベルである必要があります -- さらに:管理者への送信も許可
(is_group || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) || notify_moderators || target.admin) &&

すべてのスタッフメンバー(個人メッセージの受信を無効にしていない人)にメッセージを送信できるようにしたい場合は、以下のように変更してください:

# 最低でも基本レベルである必要があります -- さらに:スタッフへの送信も許可
(is_group || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) || notify_moderators || target.staff?) &&

管理者ではなくモデレーターへのみメッセージ送信を有効にしたい場合は:

# 最低でも基本レベルである必要があります -- さらに:モデレーターへの送信も許可
(is_group || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) || notify_moderators || target.moderator) &&

@pfaffman さん、@angus さん、ありがとうございます!
:100:

「いいね!」 2

それは奇妙ですね。それがどうして起こり得るのか、私にはわかりません。

「いいね!」 1