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 个赞

Jay,你之前找到这个问题的解决方案了吗?

我们遇到了类似的问题,如果能禁止普通的 1 对 1 私聊,问题就能迎刃而解。这是一个志愿者组织,他们希望志愿者与协调员沟通,但最好志愿者之间不要互相联系。

4 个赞

上面提到的插件(https://github.com/pfaffman/discourse-allow-pm-to-staff)可以正常工作。我虽不能做出任何承诺,但委托开发该插件的客户仍在继续使用,因此它得到了积极维护,甚至拥有在 Travis 上运行的测试。

4 个赞

感谢分享 @pfaffman@angus

@Stephen,你这边成功运行了吗?

我明白这是免费提供的,没有任何承诺,对此我们非常感激。:slight_smile:

只是提醒一下,目前它似乎无法正常工作。除非我配置有误,否则该插件已安装并启用。

我进行了测试:将“发送消息所需的最小信任等级”设置为 1,让 TL0 用户尝试向工作人员发送私信;同样地,将其设置为 2,让 TL1 用户尝试向工作人员发送私信。

在这两种情况下,如果普通用户的信任等级低于“发送消息所需的最小信任等级”设置,其个人资料页面上针对工作人员的个人消息按钮都会被隐藏。目标工作人员用户的设置中也已启用接收私信。

在我的测试中,2.5.0 稳定版和 2.6.0.beta1(测试通过)均存在此问题。

在稳定版上,我还尝试从 /u/用户名/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 页面显示“已启用?”设置为 Y。

  • 调整“发送消息所需的最低信任等级”,并使用一个低于所选信任等级(TL)的普通用户账户尝试向工作人员发送消息进行测试。

  • 尝试在稳定版 2.5.0 上移除除该插件外的所有插件,以排除可能存在冲突的情况,但这并未带来任何改变。

1 个赞

找到问题了 :partying_face:

我没有自定义/配置 Travis 测试,这似乎导致插件无法正常工作。

所以我尝试只保留 plugin.rb 文件,其他都删除,结果它就开始工作了。我还根据我的使用场景稍微修改了一下逻辑。

目前的情况是,信任等级为 TL0 及以上的用户可以在其信任等级低于配置的“发送消息所需的最低信任等级”时向管理员发送消息,但不能向版主发送消息。

要修改这一点,需要稍微调整以下这段代码(非常感谢清晰的注释 :)):

# 至少需要基本等级——现在:或者发送给管理员
(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 个赞