Distinguish private messages from posts?

In a server-side ruby plugin, I’m using DiscourseEvent.on("post_created") to get data on post replies. However, this is also being triggered when a person replies to a private message. Unfortunately, I can’t see any attributes on the event objects that allow me to distinguish a reply to a topic from a reply in a PM conversation. The archetype property is set to “regular” in both of these cases.

Does anyone have any ideas how to distinguish a private message reply from other messages?

Something might be wrong, because the topic.archetype == "private_message" is the way to differentiate regular posts from PMs.

1 Like

Yea, I’m seeing the initial PM come through with that archetype, but replies after the initial message are “regular”.

But the archetype is on the topic, not on the post.

I just tried a new PM on my dev instance and the archetype is private_message.

Yea, but what about subsequent messages in the PM conversation? Those have regular.

edit: I’m testing on 1.7.0.beta5

But isn’t the archetype on the topic instead of the post? In the database there is only one line per topic, and it’s set correctly. Where are you testing this info?

Here’s the code that I’m using to trace out the event objects: https://github.com/MyPureCloud/Discourse-Webhooks/blob/master/plugin.rb#L85

Here’s the result of that trace for a PM reply. I believe the topic is the second object in the params array. I’ve truncated the user object for brevity.

[
  {
    "id": 242,
    "user_id": 2,
    "topic_id": 177,
    "post_number": 3,
    "raw": "replying in a PM asdf1234",
    "cooked": "<p>replying in a PM asdf1234</p>",
    "created_at": "2016-10-12T21:03:33.334Z",
    "updated_at": "2016-10-12T21:03:33.334Z",
    "reply_to_post_number": null,
    "reply_count": 0,
    "quote_count": 0,
    "deleted_at": null,
    "off_topic_count": 0,
    "like_count": 0,
    "incoming_link_count": 0,
    "bookmark_count": 0,
    "avg_time": null,
    "score": null,
    "reads": 0,
    "post_type": 1,
    "vote_count": 0,
    "sort_order": 3,
    "last_editor_id": 2,
    "hidden": false,
    "hidden_reason_id": null,
    "notify_moderators_count": 0,
    "spam_count": 0,
    "illegal_count": 0,
    "inappropriate_count": 0,
    "last_version_at": "2016-10-12T21:03:33.350Z",
    "user_deleted": false,
    "reply_to_user_id": null,
    "percent_rank": 1,
    "notify_user_count": 0,
    "like_score": 0,
    "deleted_by_id": null,
    "edit_reason": null,
    "word_count": 5,
    "version": 1,
    "cook_method": 1,
    "wiki": false,
    "baked_at": "2016-10-12T21:03:33.334Z",
    "baked_version": 1,
    "hidden_at": null,
    "self_edits": 0,
    "reply_quoted": false,
    "via_email": false,
    "raw_email": null,
    "public_version": 1,
    "action_code": null
  },
  {
    "raw": "replying in a PM asdf1234",
    "topic_id": "177",
    "archetype": "regular",
    "category": "",
    "typing_duration_msecs": "1900",
    "composer_open_duration_msecs": "11839",
    "visible": true,
    "is_warning": false,
    "ip_address": "127.0.0.1",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "referrer": "https://developer.inindca.com/forum/t/hey-this-is-a-pm/177",
    "first_post_checks": true
  },
  {
    "id": 2,
    "username": "tim.smith",
    "avatar_template": "/forum/user_avatar/developer.inindca.com/tim.smith/{size}/58_1.png",
    "name": "Tim Smith",
    "last_posted_at": "2016-10-12T21:03:33.334Z",
    "last_seen_at": "2016-10-12T21:03:14.864Z"
  }
]

edit: here’s a screenshot showing that the post is indeed a reply to a PM:

Hmmm I think this params variable isn’t used elsewhere.

And on brand new official WebHooks for post created we only send down the topic id.

The params variable is the name of the variable in my plugin, not something in Discourse. It’s an array of the 3 parameters passed into a Discourse event, presumably via DiscourseEvent.trigger(...). Here’s where it’s defined in my plugin: https://github.com/MyPureCloud/Discourse-Webhooks/blob/master/plugin.rb#L34

I’m not using Discourse’s webhooks. I’m consuming events in my plugin that are raised by Discourse directly, parsing/formatting the event data, and sending my own webhook.

In that case, you need to add post.topic.archetype as a field that gets sent.

Or, do Guardian.new(plugin _user).can_see? post and use the standard visibility checks.

2 Likes

you need to add post.topic.archetype as a field that gets sent.

What do you mean? The field is there in the event data for PM replies. It’s just set to “regular” so I can’t distinguish it from a reply to a topic.

Or, do Guardian.new(plugin _user).can_see? post and use the standard visibility checks.

Can you point me to some documentation on what Guardian is and why I need a new one? Also documentation for how to do a visibility check and which ones are standard?

1 Like

Are you confusing Topic archetype with Post post_type?

Guardian files can be seen here

https://github.com/discourse/discourse/tree/master/lib/guardian

I don’t think so. Take a look at the JSON I posted above in this post. The second JSON object in the array, which I think is the topic data, has "archetype": "regular". The post_type property is always set to 1 in the first object in the array for all posts, which I think is the post data.

Ah yes, now I see what you mean.

A post_type “regular” and an archetype “regular” are not in the same set of definitions.
For example, for topic the set includes regular, banner, private_message but for a post the set includes regular, moderator_action, system_action

So yes, for a topic that is a private message it does seem that the archetype should be private_message ant not regular.

Was this a topic that was admin wrenched into a message?

Nope. Just went to a user’s page and hit message. The first post does have private_message set for the archetype, just not any of the subsequent replies in the PM; they’re all set to regular.

I did just find something really interesting. This is actually a UI bug, not a backend bug. When creating a reply, a POST is made to {discourse site}/posts with the following form data (formatted with linebreaks for your pleasure):

raw=this+is+another+reply+iok+asldfkjad
&unlist_topic=false
&category=
&topic_id=177
&is_warning=false
&whisper=false
&archetype=regular
&typing_duration_msecs=2000
&composer_open_duration_msecs=6168
&reply_to_post_number=6
&nested_post=true

Note how the UI is specifying archetype=regular in the post! I did some hacking and modified that same request to send archetype=private_message, and volia! The resulting event data has archetype set to private_message. For fun, I set it to archetype=shits_and_giggles, and guess what? The resulting event also had archetype set to shits_and_giggles.

I’m rather surprised that UI code is providing data about the post and that discourse is sending that data back out without even validating it. It really seems like that data should be provided by the server, not the UI.

So, now that I’ve figured out where the “regular” value is coming from, could this be logged as a bug and fixed? Or point me to where the UI code is for this and I’ll see if I can figure out how to fix it?

1 Like

Interesting. But again, the best route is to simply reload the post from the database and pull all the fields you need from that.

Guardian is the class that takes care of all permission checks in Discourse.

Seriously? What’s the point of sending data with an event if you shouldn’t use it or can’t rely on it being accurate? That’s really poor design.

Probably because nobody actually looked at what the event code was doing and asked whether it made sense? This isn’t exactly the most well-exercised portion of code in Discourse.

It’s also possible you’re printing out the PostCreator object, in which case, yeah, that’s supposed to have the raw form data.

1 Like