Allow sending Private Messages to Staff

AI-generated summary

The discussion revolves around creating a feature to allow users to send private messages (PMs) to staff members only, while restricting PMs between non-staff users. pfaffman initially proposed the idea and sought help to implement it.

angus provided a solution using a plugin, but pfaffman encountered issues with the implementation. angus pointed out three potential problems with pfaffman’s code and suggested corrections.

The plugin was later developed and made available on GitHub (https://github.com/pfaffman/discourse-allow-pm-to-staff). pfaffman confirmed that the plugin works, and markersocial later reported that the plugin was working after removing unnecessary files and customizing the code to fit their specific use case.

The plugin’s functionality allows users to send PMs to staff members, even if the site setting for private messages is disabled. However, angus advised that keeping the site setting on and restricting PMs via the guardian might be a better approach. pfaffman noted that the current implementation meets their client’s requirements, but acknowledged that it might not be suitable for all use cases.

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

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:

https://github.com/pfaffman/discourse-allow-pm-to-staff

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 사용자가 스태프에게 개인 메시지를 보내는 경우를 테스트했습니다.

두 경우 모두, 사용자의 신뢰 등급이 ‘메시지 전송 최소 신뢰 등급’ 설정보다 낮으면 일반 사용자 계정에 대해 스태프 프로필에서 개인 메시지 버튼이 숨겨졌습니다. 수신 대상인 스태프 사용자의 설정에서도 개인 메시지 수신은 활성화되어 있습니다.

제 환경에서는 2.5.0 안정판과 2.6.0.beta1 (tests-passed) 모두에서 이러한 증상이 나타납니다.

안정판에서는 /u/username/messages 페이지에서 메시지를 직접 작성하고 수신자로 스태프를 입력해 보았으나, 제출 시 메시지가 거부되었습니다.

2개의 좋아요

음, 제 개발 인스턴스에서 2.6.0.beta1로 실행할 때 작동하는 것 같고, 2.5.0.beta4를 사용하는 프로덕션 인스턴스에서도 작동하며, 트래비스에서도 여전히 테스트를 통과하고 있습니다.

제 추측으로는 멀티사이트 환경에서는 작동하지 않는 것 같고, 혹시 멀티사이트를 사용하고 계신 건가요?

2개의 좋아요

동작한다는 소식을 들으니 정말 기쁩니다! 아마 제가 뻔한 것을 놓치고 있는 것 같습니다. 이는 멀티사이트(multisites) 환경이 아니라, 표준 도커 설치 환경이었습니다.

다음과 같은 단계를 수행했습니다:

  • https://github.com/pfaffman/discourse-allow-pm-to-staff.git에서 플러그인을 설치했습니다. 해당 플러그인을 명시적으로 활성화하거나 플러그인 특정 옵션을 설정하지는 않았습니다. 다만 /admin/plugins 페이지에서 ‘enabled?’ 항목이 Y로 설정되어 있었습니다.

  • ‘min trust to send messages’ 값을 조정하고, 해당 신뢰 수준(TL) 미만인 일반 사용자 계정으로 스태프에게 메시지를 보내는 것을 시도하여 테스트했습니다.

  • 충돌이 있는지 확인하기 위해 stable 2.5.0 환경에서 해당 플러그인을 제외한 모든 플러그인을 제거해 보았지만, 결과는 달라지지 않았습니다.

1개의 좋아요

문제가 뭔지 파악했어요 :partying_face:

Travis 테스트를 커스터마이즈/구성하지 않아서 플러그인이 작동하지 않는 것 같았어요.

그래서 플러그인.rb 파일만 남기고 나머지를 전부 제거해 보았는데, 제 환경에서는 정상적으로 작동하기 시작했어요. 제 용도에 맞게 로직을 약간 수정하기도 했죠.

현재 상태에서는, TL0+ 사용자가 ‘메시지 전송 최소 신뢰 수준’ 설정값보다 낮은 신뢰 수준이 되면 관리자에게 메시지를 보낼 수 있지만, 모더레이터에게는 메시지를 보낼 수 없어요.

이 부분을 수정하려면 아래 섹션을 아주 약간만 변경하면 됩니다 (명확한 주석 감사합니다 :slight_smile: ):

# Have to be a basic level at least -- and now: OR SENDING TO ADMIN
(is_group || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) || notify_moderators || target.admin) &&

모든 스태프(개인 메시지 수신을 명시적으로 비활성화하지 않은 사용자)에게 메시지 전송을 허용하려면 아래처럼 변경하세요:

# Have to be a basic level at least -- and now: OR SENDING TO STAFF
(is_group || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) || notify_moderators || target.staff?) &&

관리자가 아닌 모더레이터에게만 메시지 전송을 활성화하려면:

# Have to be a basic level at least -- and now: OR SENDING TO MODERATOR
(is_group || @user.has_trust_level?(SiteSetting.min_trust_to_send_messages) || notify_moderators || target.moderator) &&

다시 한번 @pfaffman 과 @angus 님께 감사드립니다!
:100:

2개의 좋아요

이상하네요. 그렇게 될 수 있는 방법을 모르겠어요.

1개의 좋아요