Python > Beitragsinhalt abrufen, wenn erwähnt

Ich spiele mit Python herum. Genauer gesagt:

Ich schaue mir die API-Dokumentation an:

Discourse API Docs / Discourse API Docs

Ich bin neu (lerne) in Python und versuche einfach, die Beiträge zu empfangen, wenn @UserA irgendwo erwähnt wird. Ich dachte, ich müsste die Beitragsnummer von den Benachrichtigungen erhalten und dann diesen Beitrag abfragen, um den Beitragsinhalt abzurufen und zu speichern.

Von dort möchte ich diesen Beitragsinhalt als Datenvariable speichern und von dort aus mit einigen Dingen experimentieren.

Ein Teil meines Codes ist dieser:

# Erwähnungen nachschlagen
mention = client.notifications.json.get()

# Die Beiträge ausgeben
for post_number in mention:
    print(post_number)

Die aktuelle Ausgabe dieses Codes:

notifications
total_rows_notifications
seen_notification_id
load_more_notifications

Entschuldigung, wenn dies eine dumme Frage ist, ich bin relativ neu bei APIs und noch neuer bei Python. Ich habe den ganzen Tag ohne Erfolg daran gearbeitet. Wenn mir jemand in die richtige Richtung weisen kann, wäre das sehr willkommen.

3 „Gefällt mir“

Vielen Dank für das Posten des Links zu fluent-discourse!

Ich versuche gerade, mich in Python einzuarbeiten, daher gibt es möglicherweise bessere Wege, dies anzugehen, als das, was ich hier skizziere.

mention = client.notifications.json.get()

Dies gibt ein Dictionary von Erwähnungen für den username zurück, den Sie beim Erstellen des client festgelegt haben. Ich gehe davon aus, dass Sie username auf UserA gesetzt haben, als Sie den client erstellt haben.

Um zu bestätigen, dass ein Dictionary zurückgegeben wird, können Sie Folgendes ausführen:

print(type(mention))

Dies sollte <class 'dict'> zurückgeben.

Sie können die Schlüssel des Dictionarys sehen, indem Sie Folgendes ausführen:

print(list(mention))

Dies gibt ['notifications', 'total_rows_notifications', 'seen_notification_id', 'load_more_notifications'] zurück.

Für Ihren Fall möchten Sie die Werte, die unter dem Schlüssel notifications zu finden sind:

notifications = mention['notifications']

Wenn Sie dann type(notifications) ausführen, sehen Sie, dass es sich um eine Liste handelt. Um Benachrichtigungen zu erhalten, die durch Erwähnungen von UserA ausgelöst wurden, müssen Sie die Liste durchlaufen, um Einträge zu finden, bei denen notification_type auf 1 gesetzt ist. Der einfachste Weg, die Werte für die Discourse-Benachrichtigungstypen zu sehen, ist die Ausführung von Notification.types aus der Rails-Konsole Ihrer Discourse-Site:

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

Um also “Erwähnungs”-Benachrichtigungen für den Benutzer zu erhalten, dessen Benutzername Sie für den client festgelegt haben, versuchen Sie Folgendes (ich teste dies im Python-Interpreter, während ich es tippe):

data = client.notifications.json.get()
notifications = data['notifications']
# Erstellen Sie eine leere Listenobjekt, um "Erwähnungs"-Benachrichtigungen zu speichern
mentions = []
# Durchlaufen Sie die Liste `notifications`, um alle Einträge zu finden, bei denen `notification_type` auf `1` gesetzt ist
for notification in notifications:
    if notification['notification_type'] == 1:
        mentions.append(notification)

Dies erstellt eine Liste von Benachrichtigungen, die durch Erwähnungen ausgelöst wurden. Jeder Eintrag in der Liste ist ein Dictionary. Sie können dies mit etwas wie Folgendem überprüfen:

for mention in mentions:
    print(mention['topic_id'], mention['post_number'])
3 „Gefällt mir“

Das ist toll. Danke für die Informationen. Es gibt nicht viele Informationen über Python x Discourse da draußen, also freue ich mich zu lernen, und vielleicht hilft das anderen. Ich habe gerade Ihren Code ausprobiert und er scheint wie erwartet zu funktionieren. Natürlich habe ich nicht aufgehört zu spielen, also habe ich einen Workaround gefunden, um bis zu Schritt 5 zu gelangen, und eine andere Möglichkeit, die Werte zu erhalten, die ich bis zu einem rohen Einfügen des Beitragsinhalts benötigte.

Was ich im Grunde möchte, ist Folgendes.

  1. Benachrichtigungen erhalten
  2. Beitragsnummern erhalten
  3. Beitragsinhalt erhalten
  4. Antwort mit OpenAI generieren
  5. Antwort posten
  6. Dieselbe Benachrichtigung als gelesen markieren?
# Richten Sie eine Schleife ein, um den Bot unbegrenzt laufen zu lassen
while True:
    # Benutzeraktionen abrufen und Beitrags-ID abrufen    
    data = {
    'username': 'theuser',
    # Für Erwähnungen und Antworten benötige ich die Filter 6 + 7, aber aus irgendeinem Grund wird nur 1 JSON-Antwort geliefert.
    'filter': 6 | 7,
    'limit': 10,
    }
    
    unread_mentions = client.user_actions.json.get(data)
    print(unread_mentions)

    user_actions = unread_mentions['user_actions']

    # Schleife über jede ungelesene Erwähnung
    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}')
    
        # Den Beitragsinhalt abrufen   
        post = client.posts[post_id].json.get()

        # Den Beitragsinhalt ausgeben
        post_content = post['raw']

        # Eine Antwort auf den Beitrag generieren
        response = generate_response(post_content)
    
        # Eine Antwort auf das Forum posten
        content = {
            'topic_id': topic_id,
            'raw': response + ' @' + str(username)
        }
        make_post = client.posts.json.post(content)

Derzeit habe ich zwei Probleme:

  • Es wird nur 1 Erwähnung abgerufen. Ich muss etwas vergessen haben, habe aber noch nicht herausgefunden, warum.
  • Natürlich wollen wir auf einen Beitrag nur einmal antworten, und da wir eine Schleife verwenden, brauchen wir hier etwas, um dies zu verhindern.
    • Wir können die post_id in einer .txt-Datei speichern (ich bin mir nicht sicher, wie viele Daten dies speichern kann, ich denke, Sie können hier eine ganze Menge Erwähnungen verarbeiten.
    • Meine ideale Lösung war es, die Benachrichtigung als gelesen zu markieren. Aber ich habe erkannt, dass wir in keinem unserer Codes ungelesene Erwähnungen abrufen (nun, ich habe es zuerst versucht, ungelesene Benachrichtigungen abzurufen, aber ich konnte die post_id-Variable nicht extrahieren/speichern, die ich für /posts/get.json und das Abrufen des “raw”-Inhalts benötigte.

Mein Endziel ist es, die Antwort mit der OpenAI API zu füttern. Aber zuerst muss ich einen Weg finden, die oben genannten Probleme zu lösen.

Ich gehe davon aus, dass Sie eine Antwort von OpenAI generieren möchten, wenn ein bestimmter Benutzername (z. B. UserA) in einem Beitrag erwähnt wird. Wenn das korrekt ist, könnten Sie anstatt API-Anfragen an Discourse zu senden, um Benachrichtigungen zu erhalten, einen Discourse Notification Event Webhook auf den Server Ihrer Python-Anwendung zeigen. Die Python-Anwendung müsste die Nutzlast des Webhooks prüfen. Wenn der notification_type der Nutzlast auf 1 gesetzt ist und seine user_id mit der ID des Benutzers übereinstimmt, für den Sie Benachrichtigungen erhalten möchten, würden Sie eine API-Anfrage an Discourse senden, um den Beitrag zu erhalten, der im Feld original_post_id der Nutzlast festgelegt ist. Senden Sie dann den Beitrag, der aus dieser Anfrage zurückgegeben wird, an OpenAI.

Hier ist ein Beispiel dafür, wie die Nutzlast für eine Erwähnungsbenachrichtigung aussieht:

{
  "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"
    }
  }
}

Der Vorteil dieses Ansatzes ist, dass Sie Benachrichtigungen in Echtzeit erhalten können, ohne eine große Anzahl von API-Anfragen an Ihre Discourse-Site senden zu müssen.

Wenn Sie sich für den Webhook-Ansatz entscheiden, wäre es ratsam, das Feld “Secret” des Webhooks in Discourse festzulegen und dann die Anfrage in Ihrer Python-Anwendung zu validieren, um sicherzustellen, dass der Secret-Schlüssel korrekt eingestellt ist. Ich habe noch nicht versucht, eine Route in einer Python-Anwendung einzurichten, um dies zu tun. Details zur Validierung eines Webhook-Secrets unter WordPress finden Sie hier: wp-discourse-custom-webhook-request/wp-discourse-custom-webhook-request.php at master · scossar/wp-discourse-custom-webhook-request · GitHub.

1 „Gefällt mir“

Vielen Dank für Ihre Antwort, ich weiß das sehr zu schätzen.

Ich habe mir die Discourse-Webhooks noch nie angesehen. Ich werde mir das ansehen.

1 „Gefällt mir“

EDIT: Ich glaube, ich irre mich. Es sieht so aus, als ob ich nach Typ 1 und 2 suche. Typ 2 wird ausgelöst, wenn es eine Antwort an den Benutzer gibt. Das macht diesen Beitrag im Grunde irrelevant. Während ich damit herumspiele, kam mir folgende Frage in den Sinn:

mentioned ist klar und deutlich, Typ == 1, wenn es eine klare @Erwähnung gibt.

Aber bei replied bin ich etwas verwirrt.

Wenn ich auf das Thema antworte, über eine der allgemeinen Schaltflächen, kommt es als Antwort an. Das ergibt Sinn.

Aber wenn man auf die Antwort-Schaltfläche für einen bestimmten Beitrag eines Benutzers klickt, würde man denken, es sei eine Erwähnung, aber es ist immer noch eine Benachrichtigung vom Typ 2.

Diese Benachrichtigung sollte vom Typ Erwähnung sein

Sollte eine Benachrichtigung „Antwort an Benutzer“ nicht Typ 1 erhalten? Denn sie ist im Grunde genau dasselbe wie eine Erwähnung, nur ohne die @Erwähnung im Beitrag.

Zur Referenz, da es nirgendwo sonst im Meta steht, poste ich hier die Benachrichtigungstypen. Vielleicht können diese Arten von Benachrichtigungen einen neuen Typ erhalten, oder einfach Typ 1?

[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}
1 „Gefällt mir“

Ich glaube nicht. Erwähnungsbenachrichtigungen ("notification_type": 1) sind für den speziellen Fall gedacht, wenn ein @Benutzername zu einem Beitrag hinzugefügt wird. Die Verwendung desselben Benachrichtigungstyps für direkte Antworten würde zu Verwirrung führen.

Es gibt einen Sonderfall, den man beachten sollte. Wenn ein Benutzername zu einer Antwort auf das Thema eines Benutzers hinzugefügt wird, ist die an den Benutzer gesendete Benachrichtigung "notification_type": 1 und nicht "notification_type": 2. Wenn ich zum Beispiel hier Ihren Benutzernamen erwähne, sollte dieser Beitrag eine Benachrichtigung auslösen, die Ihnen mitteilt, dass ich Sie erwähnt habe, und keine Benachrichtigung, die besagt, dass ich Ihnen geantwortet habe: @MarcP.

Beachten Sie, dass ein anderer Benutzer, der dieses Thema verfolgt, eine Benachrichtigung mit dem Typ 9 (gepostet) erhalten würde.

2 „Gefällt mir“

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