Parameter "caption" Variabel überreichen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

Hallo und guten Morgen liebe Gemeinde, bin mal wieder an einem Punkt. Kann mir bitte jemand auf die Sprünge helfen: Ich möchte gerne dem Parameter "catpion" im folgenden Code meinen Text (TEXT) übergeben. Klappt mal wieder nicht und stundenrund gesucht. Für die Hilfe bedanke ich mich sehr.

Code: Alles auswählen

TOKEN = token
CHAT_ID = chat_id
TEXT = 'text123'


request_url = "https://api.telegram.org/bot" + TOKEN + "/sendMediaGroup"
params = {
    "chat_id": CHAT_ID,
    "caption1" : TEXT,
    "media":"""[{"type": "photo", "media": "attach://random-name-1", "caption" : "TEXT", "parse_mode": "Markdown"},   
                 { "type": "photo" , "media": "attach://random-name-2", "caption": ""}]"""
}

files = {
    "random-name-1": open("/home/...Bild1.jpg", "rb"),
    "TEXT" : TEXT,
    "random-name-2": open("/home/...Bild2.jpg", "rb")
}


result = requests.post(request_url, params= params, files= files, )
print(result.text)
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

Das "catpion" in deinem Text hat meinen Morgen verschönert :D

Zuerst muss man sich natülich fragen, warum du das alles per Hand zu Fuß machst und kein Modul verwendest.

Ohne die API von Telegram zu kennen, sieht es für mich so aus, als müsste das alle snich tin "params" sondern in "data". Es sei denn in requests hat sich in letzter Zeit etwas grundlegendes geändert.

Warum heißt da ein Schlüssel "caption1"? Ich kann mir nicht vorstellen, dass die bei Telegram ihre Namen nummerieren.

Warum ist der Inhalt ovn "media" eine Zeichenkette, die so etwas wie eine Datenstruktur enthält? Ich bin mir ziemlich sicher, dass muss einfach eine Liste mit entsprechenden dicts sein. Um den Rest sollte sich requests kümmern. Sollte es das nicht, musst du trotzdem vorher die entsprechenden Daten bauen und dann mit json parsen.
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

... ach, ... Danke lieber @sparrow, genau das mit der data-Liste hab ich schon stundenrund probiert. Aber irgendwie kam ich mit mehreren Bildern in einer Nachricht (mediagroup) nicht weiter und hab diesen Code im Netz gefunden. Nur ein Bild mit Text nach TG zu senden, das bekomme ich ja gut hin (mit besagter einfacher data-Übergabe). Bei mediagroup ist es mir einfach schleierhaft, wie man das so machen könnte. Da muss nämlich der Caption-Text direkt mit oder unter das erste Bild. Ist mir immer noch ein Rätsel, wie das gehen soll.
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Diesem Post auf StackOverflow entnehme ich, dass die Caption des ersten Media-Objekts für die Caption der MediaGroup sorgt. Sollten die anderen Media-Objekte ebenfalls eine Caption haben, erscheint sie nur unter dem jeweiligen Objekt.
Ungetestet müsste dein Request also so aussehen, wobei ich keine Ahnung habe, ob die Dateien so korrekt mitgegeben werden. Stecke da nicht so drin.

Code: Alles auswählen

# (...)
data = {"chat_id": CHAT_ID, "media": [{"type": "photo", "media": "attach://random-name-1", "caption" : "TEXT"}, {"type": "photo", "media": "attach://random-name-2"}]}
files = {"random-name-1": open("/home/...Bild1.jpg", "rb"), "random-name-2": open("/home/...Bild2.jpg", "rb")}
result = requests.post(request_url, data=data, files=files)
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

Hallo und Danke @einfachTobi" zunächst. Ich komme leider mit Deinem Vorschlag nicht weiter.
Ausgabe (egal was ich mache): b'{"ok":false,"error_code":400,"description":"Bad Request: can\'t parse media JSON object"}'

In dem Code, den ich heute morgen gepostet habe, müsste ich nur diesen Wert "TEXT" vom Schlüssel/Wertpaar: "caption" : "TEXT" im param "media" auschen gegen meine Variable TEXT( 'text123'). Ich komme da nicht ran oder hin. Der Code funktioniert ja so, nur dass ich eben den "TEXT" nicht austauschen kann. Danke nochmals für die Hilfe
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Wie meinst du, dass du an "TEXT" nicht ran kommst? Das fügst du doch selbst dort ein. Dann schreib halt deine Variable da rein. Vermutlich solltest du die Daten dann als JSON mitgeben:

Code: Alles auswählen

# (...)
TEXT = "ich bin ein text"
data = {"chat_id": CHAT_ID, "media": [{"type": "photo", "media": "attach://random-name-1", "caption" : TEXT}, {"type": "photo", "media": "attach://random-name-2"}]}
# (...)
result = requests.post(request_url, json=data, files=files)
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

Das funktioniert so nicht. Auch ohne "caption" bekomme ich : ""ok":false,"error_code":400,"description":"Bad Request: parameter \"media\" is required"
Diese drei Anführungszeichen, frag mich warum, aber die müssen wohl sein.

einfachTobi hat geschrieben: Donnerstag 16. Dezember 2021, 13:16 Wie meinst du, dass du an "TEXT" nicht ran kommst? Das fügst du doch selbst dort ein. Dann schreib halt deine Variable da rein. Vermutlich solltest du die Daten dann als JSON mitgeben:

Code: Alles auswählen

# (...)
TEXT = "ich bin ein text"
data = {"chat_id": CHAT_ID, "media": [{"type": "photo", "media": "attach://random-name-1", "caption" : TEXT}, {"type": "photo", "media": "attach://random-name-2"}]}
# (...)
result = requests.post(request_url, json=data, files=files)
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

Ok, jetzt hab ich's selbst hinbekommen. Für alle, die so wie ich, noch "neu" in Python sind: hier die Lösung. Für die Option TG "sendMediaGroup" mit Variableübergabe an den Parameter "caption" (Beispiel: 2 oder 3 Bilder, ein Text in einer Nachricht)
Dafür wird zunächst die Pyton-Liste "mediaList" erstellt, nur das erste Bild bekommt die "caption"-Variable "mediaText". Anschließend wird die Liste zum Jsonstring konvertiert. Der Json-String wird an den Parameter von sendMediaGroup "media" übergeben. Und dann klappt der Versand mit Text und Bildern. Danke an alle für die Hilfe.

Code: Alles auswählen

    mediaText = '*Mein Text-Beispiel*'
    mediaList = [{'type': 'photo', 'media': 'attach://random-name-1', 'caption' : mediaText, 'parse_mode': 'Markdown'},
                     { 'type': 'photo' , 'media': 'attach://random-name-2', 'caption': ""}]

    strJson = json.dumps(mediaList)

    params = {
        'chat_id': CHAT_ID,
        'media': strJson
    }

    files = {
        'random-name-1': open(img1, 'rb'), 'caption': text,
        'random-name-2': open(img2, 'rb')
    }

    result = requests.post(request_url, params=params, files= files)
    print(result.text)

Benutzeravatar
__blackjack__
User
Beiträge: 14016
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jyll: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Grunddatentypen haben nichts in Namen verloren. Den Typen ändert man gar nicht so selten mal während der Programmentwicklung und dann muss man überall im Programm die betroffenen Namen ändern, oder man hat falsche, irreführende Namen im Quelltext.

Man nummeriert keine Namen. Entweder will man dann bessere Namen oder gar keine Einzelwerte sondern eine Datenstruktur. Oft eine Liste. Hier wohl auch für die Bilddateinamen

Der Schlüssel "caption" in `files` kommt mir ja falsch vor. `text` ist auch nirgends definiert.

Dateien die man öffnet, sollte man auch wieder schliessen.

Das sähe dann ungefähr so aus (ungetestet):

Code: Alles auswählen

    caption = "*Mein Text-Beispiel*"
    image_filenames = ["random-name-1", "random-name-2"]

    with ExitStack() as stack:
        response = requests.post(
            request_url,
            params={
                "chat_id": CHAT_ID,
                "media": json.dumps(
                    [
                        {
                            "caption": caption,
                            "media": f"attach://{name}",
                            "parse_mode": "Markdown",
                            "type": "photo",
                        }
                        for name in image_filenames
                    ]
                ),
            },
            files={
                name: stack.enter_context(open(name, "rb"))
                for name in image_filenames
            },
        )
    response.raise_for_status()
    print(response.text)
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

@__blackjack__: Vielen Dank. Wollte es gerade selbst ändern, da ich meinen Fehler (Schlüssel "caption" in `files` ) jetzt bemerkte. Hat zwar auch so geklappt. Danke auch noch mal für die Erklärung mit den Namen. Ist oft verwirrend, wenn man Code-Beispiele im Netz findet und sich fragt, was ist nun richtig. Gut, wenn man es noch einmal von einem Profi erklärt bekommt. Werde Deinen Code jetzt übernehmen. Danke nochmals. VG Jyll
Jyll
User
Beiträge: 26
Registriert: Montag 26. Juli 2021, 14:18

@__blackjack__: Dein Code läuft, bis auf das kleine Detail, dass der caption-Text nicht ausgegeben wird. Der darf ja nur am ersten Bild eingefügt werden. Sonst wird er "verschluckt". Hab's jetzt mit u.a. Codezeile probiert. Klappt leider auch nicht. Vielleicht hast Du eine Idee. Danke nochmals für die Hilfe.

Code: Alles auswählen

x = 0 ...
..
x = x
....
                "media": json.dumps(
                    [
                        {
                            "caption": caption if x == 0 else '',
                            "media": f"attach://{name}",
                            "parse_mode": "Markdown",
                            "type": "photo",
                        }

...
x= x+1
Benutzeravatar
__blackjack__
User
Beiträge: 14016
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Was für eine besch…eidene API, dass die folgende "caption"-Einträge dann nicht einfach ignoriert und einen zwingt so etwas Unregelmässiges zu basteln.

Ungetestet (`chain()` und `repeat()` aus dem `itertools`-Modul):

Code: Alles auswählen

                "media": json.dumps(
                    [
                        {
                            "caption": caption,
                            "media": f"attach://{name}",
                            "parse_mode": "Markdown",
                            "type": "photo",
                        }
                        for caption, name in zip(
                            chain([caption], repeat("")), image_filenames
                        )
                    ]
                ),
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Antworten