Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support extra data in message #120

Closed
eternal-flame-AD opened this issue Jan 25, 2019 · 6 comments · Fixed by #121
Closed

Support extra data in message #120

eternal-flame-AD opened this issue Jan 25, 2019 · 6 comments · Fixed by #121
Labels
a:feature New feature or request in:server
Milestone

Comments

@eternal-flame-AD
Copy link
Member

eternal-flame-AD commented Jan 25, 2019

Since gotify is not specifically designed for mobile notifications, and there are more and more requests on extending the message structure such as #63 and #119. A simple message field is a little too limited to process multiple kinds of messages. I propose adding an extras field in the message struct in the next major version of gotify which is passed to the client, and the client would try to interpret these extra fields when they could understand them.
The message struct would look like this:

type Message struct {
	// The message id.
	//
	// read only: true
	// required: true
	// example: 25
	ID uint `gorm:"AUTO_INCREMENT;primary_key;index" json:"id"`
	// The application id that send this message.
	//
	// read only: true
	// required: true
	// example: 5
	ApplicationID uint `json:"appid"`
	// The actual message.
	//
	// required: true
	// example: Backup was successfully finished.
	Message string `form:"message" query:"message" json:"message" binding:"required"`
	// The title of the message.
	//
	// example: Backup
	Title string `form:"title" query:"title" json:"title"`
	// The priority of the message.
	//
	// example: 2
	Priority int `form:"priority" query:"priority" json:"priority"`
	// The date the message was created.
	//
	// read only: true
	// required: true
	// example: 2018-02-27T19:36:10.5045044+01:00
	Date time.Time `json:"date"`
	// Extra data passed to the client.
	//
	// read only: true
	Extras map[string]json.RawMessage `json:"extras"`
}

And the message could be sent like this:
The android:* will only be rendered on Android clients.

{
    "title":"Garage door opened",
    "priority":5,
    "message":"Your garage door is open",
    "extras":{
        "android:intent":[
            {
                "fire":"on_receive",
                "action":"gotify.event.garage",
                "data":"open"
            }
        ],
        "android:actions":[
            {
                "type":"button",
                "action":"POST",
                "url":"https://api.my.home/garage/door/close",
                "text":"Close Garage Door"
            },
            {
                "type":"button",
                "action":"open",
                "url":"https://api.my.home/garage/nvr/shot",
                "text":"Take a picture from the NVR"
            }
        ]
    }
}

Other optional features such as E2E encryption:

{
    "title":"Encrypted message",
    "priority":5,
    "message":"This message is E2E encrypted. you need a supported client to read it",
    "extras":{
        "e2e:encrypted":{
            "message":"<encrypted_message>",
            "key":"<ephmeral key>"
        }
    }
}

This would not be difficult to implement on the server side but it would definitely pave the way for future implementations on more powerful features based on the messages.

@eternal-flame-AD
Copy link
Member Author

eternal-flame-AD commented Jan 25, 2019

If you don't like adding fields to messages, here is an alternative with syntax similar to go compiler directives: use specialized directives embedded in messages to provide extras:

For example, the message would look like:

Your garage door is open.

//android:button close https://api.my.home/garage/door/close
//android:intent gotify.event.garage open

Benefits:

  • Less intrusive API changes
  • More transparency to users
  • geeky

Setbacks:

  • Difficult to build complex directives(eg: with structured data)
  • The parser is harder to implement
  • The message would be less friendly, especially when directive payloads are large
  • Unwanted directive injections intentionally or unintentionally, eg: when part of the message is provided from an untrusted source.

@sik0vny
Copy link

sik0vny commented Jan 25, 2019

This is definitely going into the right direction. Great stuff!

I would vote for the first proposal, it is more structured and clean.

@jmattheis
Copy link
Member

Great Idea! We should probably implement it before we fully release the plugin-api. Otherwise, we had to release a new gotify/plugin-api version which I'd like to prevent.
Also, we should make a common way to add buttons (or other things) in both WebUI and gotify/android.

I'm in favor of the extra "extras" property on the Message struct.

Some side note: If we implement e2e we shouldn't do this via extra properties. It seems like a hacky approach to me (:.

@jmattheis jmattheis added a:feature New feature or request in:server labels Jan 25, 2019
@eternal-flame-AD
Copy link
Member Author

eternal-flame-AD commented Jan 26, 2019

Great Idea! We should probably implement it before we fully release the plugin-api. Otherwise, we had to release a new gotify/plugin-api version which I'd like to prevent.

Maybe we can use a milestone to track these TODOs before issuing the next version.

Also, we should make a common way to add buttons (or other things) in both WebUI and gotify/android.

I am not very certain about whether a unified or split config is better, since webUI and android are very different user interfaces. If we are certain to add the extra field into the milestone, we can discuss this further in #119 and gotify/android#44.

Some side note: If we implement e2e we shouldn't do this via extra properties. It seems like a hacky approach to me (:.

I think this is the best way to implement E2E while keeping gotify simple. I thought about having a dedicated message structure for E2E messages but I proposed this instead. The reasons are:

  • Some clients might not implement E2E features, and we would like to provide them with a "fallback" message to indicate that "there is a message here, but I cannot decrypt it"
  • No extra code on the server side for processing messages.

The biggest setback for this implementation would be that other extras would not be encrypted. Still, let's bring discussion about the detailed implementation on E2E in #63

@mwild1
Copy link

mwild1 commented Mar 4, 2019

Is the schema here implying that only Android clients would/should implement actions? My desktop notifications also support actions, for example.

In fact there is already a standard for such notifications, maybe it could be borrowed? E.g. take a look at this implementation: https://www.npmjs.com/package/freedesktop-notifications

Lots of info about the ecosystem here: https://wiki.archlinux.org/index.php/Desktop_notifications

@jmattheis
Copy link
Member

@mwild1 Looks good, if there is a standard for it then gotify should use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:feature New feature or request in:server
Development

Successfully merging a pull request may close this issue.

4 participants