# Python \> Get post content if mentioned

**URL:** https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309
**Category:** Development
**Tags:** mentions
**Created:** [December 8, 2022, 6:49pm UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309 "2022-12-08T18:49:25Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![MarcP](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcp/32/160184_2.png) [@MarcP](https://meta.discourse.org/u/MarcP)
#### Post date: [December 8, 2022, 6:49pm UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/1 "2022-12-08T18:49:25Z")

</div>

I am playing around with python. To be specific:

> **[Client Challenge](https://pypi.org/project/fluent-discourse/)**

I am looking this API docs:

[Discourse API Docs](https://docs.discourse.org/#tag/Posts/operation/postReplies) / [Discourse API Docs](https://docs.discourse.org/#tag/Notifications/operation/getNotifications)

I am new (learning) with Python, and am trying to simply receive the posts if @UserA gets mentioned somewhere. I was thinking I need to get the post\_number from the notifications, and then query that post, to retrieve and store the post content.

From there I want to store that post content, as a data variable and from there experiment with some things.

A part of my code is this:

```plaintext
# lookup mentions
mention = client.notifications.json.get()

# print the posts
for post_number in mention:
    print(post_number)

```

The current output of this code:

```plaintext
notifications
total_rows_notifications
seen_notification_id
load_more_notifications

```

Sorry if this is a stupid question, I am relatively new with API’s and even newer with Python. I have been working with this all day without success, if anyone can point me in the right direction, that would be highly appreciated.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [December 8, 2022, 10:24pm UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/2 "2022-12-08T22:24:46Z")

</div>

Thanks for posting the link to fluent-discourse!

> [@MarcP](#):
>
> am trying to simply receive the posts if @UserA gets mentioned somewhere.

I’m currently trying to get up to speed with Python, so it’s possible there are better ways of approaching this than what I’m outlining here.

`mention = client.notifications.json.get()`

This is returning a [dictionary](https://docs.python.org/3/library/stdtypes.html#dict) of mentions for the `username` you set when you created the `client`. I am assuming that you set the `username` to `UserA` when you created the `client`.

To confirm that a dictionary is being returned, you can run:

```python
print(type(mention))

```

That should return `<class 'dict'>`

You can see the dictionary’s keys by running:

```python
print(list(mention))

```

That will return `['notifications', 'total_rows_notifications', 'seen_notification_id', 'load_more_notifications']`

For your case, you want the values that are found under the `notifications` key:

```python
notifications = mention['notifications']

```

If you then run `type(notifications)`, you’ll see that it is a [list](https://docs.python.org/3/library/stdtypes.html#lists). To get notifications that were triggered by mentions of `UserA`, you need to iterate through the list to find entries where the `notification_type` is set to `1`. The easiest way to see the values for the Discourse notification types is to run `Notification.types` from your Discourse site’s rails console:

```ruby
 pry(main)> Notification.types
=> {:mentioned=>1,
 :replied=>2,
 :quoted=>3,
 :edited=>4,
 :liked=>5,
 ...

```

So to get “mention” notifications for the user whose username you’ve set for the `client`, try something like this (I’m testing this in the Python interpreter as I type it):

```python
data = client.notifications.json.get()
notifications = data['notifications']
# Create an empty list object to store "mention" notifications
mentions = []
# Iterate through the `notifications` list to find all entries where the `notification_type` is set to `1`
for notification in notifications:
    if notification['notification_type'] == 1:
        mentions.append(notification)

```

That will create a list of notifications that were triggered by mentions. Each item in the list will be a dictionary. You can check it with something like:

```python
for mention in mentions:
    print(mention['topic_id'], mention['post_number'])    

```

---

<div class="post-metadata">

### Author: ![MarcP](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcp/32/160184_2.png) [@MarcP](https://meta.discourse.org/u/MarcP)
#### Post date: [December 8, 2022, 10:46pm UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/3 "2022-12-08T22:46:44Z")

</div>

This is neat. Thanks for the info. There is not many information on Python x Discourse available out here, so happy to learn, and perhaps this will help others. I just tried your code, and it seems to work as expected. Of course, I didn’t stop playing, so I’ve found a workaround to get up until step 5, and a different way to get the values I needed all the way up to a raw paste of the post content.

What I want is basically this.

1. Get notifications
2. Get post\_numbers
3. Get post content
4. Generate reply with OpenAI
5. Post reply
6. Mark that same notification as read?

```plaintext
# Set up a loop to run the bot indefinitely
while True:
    # Get user_actions and fetch post id    
    data = {
    'username': 'theuser',
    # For mentions and replies, I need to get filters 6 + 7, but for some reason only 1 json response is given.
    'filter': 6 | 7,
    'limit': 10,
    }
    
    unread_mentions = client.user_actions.json.get(data)
    print(unread_mentions)

    user_actions = unread_mentions['user_actions']

    # Loop over each unread mention
    for user_action in unread_mentions['user_actions']:
        topic_id = user_action['topic_id']
        post_number = user_action['post_number']
        post_id = user_action['post_id']
        username = user_action['username']

        print(f'Topic ID: {topic_id}, Post Number: {post_number}, Post ID: {post_id}, Reply to: {username}')
    
        # Get the post content   
        post = client.posts[post_id].json.get()

        # Print the post content
        post_content = post['raw']

        # Generate a response to the post
        response = generate_response(post_content)
    
        # Post a response to the forum
        content = {
            'topic_id': topic_id,
            'raw': response + ' @' + str(username)
        }
        make_post = client.posts.json.post(content)

```

Currently I’m having two problems:

- Only 1 mention is fetched. I must’ve forgot something, but haven’t found out why yet.
- Ofcourse we want to reply to a post only one time, and since we are looping we need something here to prevent this.
  - We can store the post\_id in a .txt file (not sure how many data this can store, I think you can handle quite a few mentions here.
  - My ideal solution, was to mark the notification as read. But I came to realize in none of our code, we are fetching **unread** mentions (well, I tried at first, fetching unread notifications, but I was unable to extract/store the post\_id variable which I needed to use /posts/get.json and fetch the “raw” content.

My end goal is to feed the response with OpenAI API. But I first need to find a way to sort out the problems above.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [December 8, 2022, 11:51pm UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/4 "2022-12-08T23:51:14Z")

</div>

> [@MarcP](#):
>
> Generate reply with OpenAI

I’m assuming that what you want to do is generate a response from OpenAI when a given username (for example, `UserA`) is mentioned in a post. If that’s correct, instead of making API requests to Discourse to get the notifications, you could point a Discourse Notification Event webhook to your Python application’s server. The Python application would need to look at the webhook’s payload. If the payload’s `notification_type` was set to `1`, and its `user_id` matched the ID of the user you are interested in getting notifications for, you’d make an API request to Discourse to get the post that’s set in the payload’s `original_post_id` field. Then send the post content that’s returned from that request on to OpenAI.

Here’s an example of what the payload for a mention notification looks like:

```plaintext
{
  "notification": {
    "id": 55267,
    "user_id": 2,
    "notification_type": 1,
    "read": false,
    "high_priority": false,
    "created_at": "2022-12-08T23:23:36.379Z",
    "post_number": 5,
    "topic_id": 277,
    "fancy_title": "I should be able to call this topic anything",
    "slug": "i-should-be-able-to-call-this-topic-anything",
    "data": {
      "topic_title": "I should be able to call this topic anything",
      "original_post_id": 10999,
      "original_post_type": 1,
      "original_username": "scossar",
      "revision_number": null,
      "display_username": "scossar"
    }
  }
}

```

The benefit of this approach is that it would let you get notifications in real time - without having to make large numbers of API requests to your Discourse site.

If you go with the webhook approach, it would be a good idea to set the webhook’s “Secret” field on Discourse, then validate the request on your Python application to make sure that the secret key is correctly set. I haven’t tried setting up a route on a Python application to do this yet. Details about how to validate a webhook’s Secret on WordPress are here: [wp-discourse-custom-webhook-request/wp-discourse-custom-webhook-request.php at master · scossar/wp-discourse-custom-webhook-request · GitHub](https://github.com/scossar/wp-discourse-custom-webhook-request/blob/master/wp-discourse-custom-webhook-request.php#L78).

---

<div class="post-metadata">

### Author: ![MarcP](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcp/32/160184_2.png) [@MarcP](https://meta.discourse.org/u/MarcP)
#### Post date: [December 8, 2022, 11:56pm UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/5 "2022-12-08T23:56:23Z")

</div>

Thanks for your reply, I highly appreciate this.

I never looked into Discourse webhooks. I will look into this.

---

<div class="post-metadata">

### Author: ![MarcP](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcp/32/160184_2.png) [@MarcP](https://meta.discourse.org/u/MarcP)
#### Post date: [December 16, 2022, 12:47am UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/6 "2022-12-16T00:47:19Z")

</div>

**EDIT: I think I am mistaken. It looks like I am looking for type 1 and 2. Type 2 will trigger if there is a reply to the user. This makes this post basically irrelevant.While playing with this, the following question came to mind:**

> [@simon](#):
>
> ```plaintext
> => {:mentioned=>1,
> :replied=>2,
> 
> ```

`mentioned` is loud and clear, type == 1 if there is a clear @Mention

But for `replied` I am kinda confused.

When I reply to the topic, through one of the general buttons, it comes in as a reply. Makes sense.

But if you click the reply button to a specific post from a user, one would think it’s a mention, but it is still a type 2 notification.

![This should be a mention type notification](https://global.discourse-cdn.com/meta/optimized/4X/5/a/9/5a9aa08f7370c64e77791fb51e0a08e36cbf9e9a_2_690x51.png)

Shouldn’t a “reply to user” notification get type 1? Because it’s basically the exact same as a mention, just without the @Mention in the post.

For reference, since it is nowhere else on meta, posting the notification types here. Perhaps these types of notifications can get a new type, or just type 1?

```plaintext
[1] pry(main)> Notification.types
=> {:mentioned=>1,
 :replied=>2,
 :quoted=>3,
 :edited=>4,
 :liked=>5,
 :private_message=>6,
 :invited_to_private_message=>7,
 :invitee_accepted=>8,
 :posted=>9,
 :moved_post=>10,
 :linked=>11,
 :granted_badge=>12,
 :invited_to_topic=>13,
 :custom=>14,
 :group_mentioned=>15,
 :group_message_summary=>16,
 :watching_first_post=>17,
 :topic_reminder=>18,
 :liked_consolidated=>19,
 :post_approved=>20,
 :code_review_commit_approved=>21,
 :membership_request_accepted=>22,
 :membership_request_consolidated=>23,
 :bookmark_reminder=>24,
 :reaction=>25,
 :votes_released=>26,
 :event_reminder=>27,
 :event_invitation=>28,
 :chat_mention=>29,
 :chat_message=>30,
 :chat_invitation=>31,
 :chat_group_mention=>32,
 :chat_quoted=>33,
 :assigned=>34,
 :question_answer_user_commented=>35,
 :watching_category_or_tag=>36}

```

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [December 16, 2022, 1:17am UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/7 "2022-12-16T01:17:14Z")

</div>

> [@MarcP](#):
>
> Shouldn’t a “reply to user” notification get type 1? Because it’s basically the exact same as a mention, just without the @Mention in the post.

I don’t think so. Mention notifications (`"notification_type": 1`) are meant for the specific case of when an `@username` is added to a post. Using the same notification type for direct replies would cause confusion.

There’s an edge case to be aware of. If a username is added to a reply to a user’s topic, the notification that’s sent to the user will be `"notification_type": 1`, not `"notification_type": 2`. For example, by mentioning your username here, this post should trigger a notification telling you that I’ve mentioned you, and not a notification saying that I replied to you: @MarcP.

Note that if a user other than yourself was watching this topic, they would get a notification with its type set to 9 (posted.)

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [January 15, 2023, 1:17am UTC](https://meta.discourse.org/t/python-get-post-content-if-mentioned/248309/8 "2023-01-15T01:17:42Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
