go-telegram-bot-api / telegram-bot-api

Golang bindings for the Telegram Bot API
https://go-telegram-bot-api.dev
MIT License
5.58k stars 863 forks source link

Right way of parsing webhook update JSON string to golang struct? #649

Closed kamil-alekber closed 1 year ago

kamil-alekber commented 1 year ago

I parse incoming webhook update JSON with this piece of code:


func ParseTelegramWebhookUpdate(body string) (tgbotapi.Update, error) {
    var messageFromBody tgbotapi.Update

        // aws encodes body with base64
    rawDecodedText, err := base64.StdEncoding.DecodeString(body)
    if err != nil {
        return messageFromBody, fmt.Errorf("failed to parse base64 body from request payload %s", err)
    }

    if string(rawDecodedText) == "" {
        return messageFromBody, fmt.Errorf("empty body from request payload %s", err)
    }

    err = json.NewDecoder(bytes.NewReader(rawDecodedText)).Decode(&messageFromBody)
    if err != nil {
        return messageFromBody, fmt.Errorf("failed to parse webhook update json body from request payload %s", err)
    }

    return messageFromBody, nil
}

however it sometimes fails with Null dereference errors:

Screenshot 2023-04-29 at 7 45 10 PM

here is what I receive for a json

{"update_id":1234443258,
"edited_message":
{
    "message_id": 684,
    "from": {
        "id": 123,
        "is_bot": false,
        "first_name": "x",
        "last_name": "x",
        "username": "x",
        "language_code": "en"
    },
    "chat": {
        "id": 123,
        "first_name": "x",
        "last_name": "x",
        "username": "x",
        "type": "private"
    },
    "date": 1682768401,
    "edit_date": 1682776196,
    "text": "/ask come up with 5 ideas on telegram bot",
    "entities": [
        {
            "offset": 0,
            "length": 4,
            "type": "bot_command"
        }
    ]
}
}

if my code is not completely correct what is the right way of doing parsing update json to golang struct?

kamil-alekber commented 1 year ago

figured it out:

    if !update.Message.IsCommand() {
        fmt.Printf("message text is empty or not a command: %s", update.Message.Text)
        return
    }

this won't work with any other message like edited_message, it makes sense of course, silly me 😄

will close the thread