pushbits / server

A simple server for push notifications via Matrix (and a minimalistic alternative to Pushover and Gotify) 🚀📯
https://www.pushbits.io
ISC License
305 stars 18 forks source link

no content/title with element-ios #49

Closed deadc0de6 closed 2 years ago

deadc0de6 commented 2 years ago

First thanks a lot for pushbits!

I installed it and tried sending message using the example curl command. While message are fully working on riot.im, on my phone (element-ios) however I do get message notification (bubble count increases) and the source user pops in the chat on new message but each message content is empty and there's no title to messages.

Is this somehow related to pushbits?

eikendev commented 2 years ago

Hi, thanks for opening this issue.

Would you share with us what kind of message you send (e.g., plain, Markdown, HTML), how you send it, and what version of PushBits you run? This allows us to efficiently try to reproduce it.

deadc0de6 commented 2 years ago

Sure, here are all requested info

Send command

$ pbcli --url=http://127.0.0.1:8080 --username=admin application create test
$ export PB_TOKEN="REDACTED"
$ curl \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{"message":"my message","title":"my title"}' \
    "http://127.0.0.1:8080/message?token=$PB_TOKEN"

using pushbits image from dockerhub: ghcr.io/pushbits/server:latest with digest: sha256:119169d9daaedb4a46b836898f887c81ec9be8d590ffc0af85f3d03f1e41ea79

eikendev commented 2 years ago

Hi, it took me a while to setup a test environment with an iPhone, sorry. I found the exact same behavior as you described: the iOS app shows the message content in the notification, but when the app is opened, the message is displayed as a single empty line.

This tells me the app definitely receives the full message, but somehow the message doesn't make it into the chat window. I modified PushBits so it only provides a bare text message without any HTML formatting (ommitting format and formatted_body) but it didn't help.

Let me leave this issue open for now, as I think it should be fixed eventually. My intuition tells me it's a bug in their iOS app, since it works without issue in the web and Android app (and I don't see where we do not act according to the specs). Could be wrong, however. Other than that, it could also be an issue with mautrix, the Matrix library we use.

deadc0de6 commented 2 years ago

@eikendev thanks a lot for investigating, much appreciated! Ok let's see if this gets solved by itself... ping me if you see anything.

eikendev commented 2 years ago

Coming back to this, I learned how to fix it, but it's still unclear to me which component's fault it is.

The problem lies with the NewContent property of our MessageEvent class. When removed from the struct, the iOS app displays the message correctly. When left in the struct, the message is "invisible" in the chat room (albeit visible in the system notification). This is the case even when the field is not populated and the omitempty flag is set (so it should be left out during serialization anyway).

@CubicrootXYZ This might also be of interest to you. I will try work out a proper fix over the weekend. See below my setup to test this behavior.

package main

import (
    "fmt"
    "log"

    "maunium.net/go/mautrix"
    "maunium.net/go/mautrix/event"
    mId "maunium.net/go/mautrix/id"
)

type MessageEvent struct {
    Body          string    `json:"body"`
    FormattedBody string    `json:"formatted_body,omitempty"`
    MsgType       string    `json:"msgtype"`
    RelatesTo     RelatesTo `json:"m.relates_to,omitempty"`
    Format        string    `json:"format,omitempty"`
    //NewContent    NewContent `json:"m.new_content,omitempty"`
}

type RelatesTo struct {
    InReplyTo map[string]string `json:"m.in_reply_to,omitempty"`
    RelType   string            `json:"rel_type,omitempty"`
    EventID   string            `json:"event_id,omitempty"`
}

type NewContent struct {
    Body          string `json:"body"`
    FormattedBody string `json:"formatted_body"`
    MsgType       string `json:"msgtype"`
    Format        string `json:"format"`
}

func main() {
    client, err := mautrix.NewClient("https://matrix.org", "", "")
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.Login(&mautrix.ReqLogin{
        Type:             mautrix.AuthTypePassword,
        Identifier:       mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: "@redacted:matrix.org"},
        Password:         "redacted",
        DeviceID:         mId.DeviceID("PushBits"),
        StoreCredentials: true,
    })
    if err != nil {
        log.Fatal(err)
    }

    room := "!redacted:matrix.org"
    messageEvent := &MessageEvent{
        Body:          fmt.Sprintf("%s\n\n%s", "title", "message"),
        FormattedBody: "<b>title</b><p>message</p>",
        MsgType:       "m.text",
        Format:        "org.matrix.custom.html",
    }

    _, err = client.SendMessageEvent(mId.RoomID(room), event.EventMessage, &messageEvent)
    if err != nil {
        log.Fatal(err)
    }

    client.Logout()
    client.ClearCredentials()
}
deadc0de6 commented 2 years ago

@eikendev I can at least answer why the omitempty is not working as you expect. NewContent is a struct and it has no nil/none/empty value in go, thus it will always be included in the generated json (with its fields set to their respective empty value). One solution would be to use a pointer (* NewContent) which has an empty value (nil).

deadc0de6 commented 2 years ago

@eikendev well actually the above explains why the message content is empty. Since you included (unintentionally) the NewContent (with empty fields), which from my understanding is used when the message content was edited, its edited value is empty and that's what the message shows. I'm guessing that using a pointer (and thus not including the NewContent thanks to omitempty) would fix the issue.

CubicrootXYZ commented 2 years ago

I can confirm that NewContent is always set. The behavior is the same for element android, empty notification but message gets shown correctly.

I will work on a fix. Thanks @deadc0de6 for investigating this with us.

eikendev commented 2 years ago

@deadc0de6 We published v0.8.2 where this issue should be fixed. Please let us know should the issue persist.

deadc0de6 commented 2 years ago

@eikendev @CubicrootXYZ awesome, thank you both for the quick fix :+1: