GJS : how to get notification content?

Hi,
I try to write an extension that aims to do a specific task whenever a notification has a given subject.

So far I managed to log the sender application of the notification, using Main.MessageTray, something like :

const MessageTray = Main.messageTray;
(…)
this.source_added = MessageTray.connect(‘source-added’, this._on_source_added.bind(this));
(…)
on_source_added(tray, source) {
log(source.title);
(…)
}

This logs the sender application. But how can I log the notification content itself ?
.

Every source has a notifications property that contains a list of notifications, and a notification-added signal to indicate that a new notification has been pushed.

1 Like

Then why does log(source.notifications) show nothing ?

        log(source.title);
        log(source.notifications);
        log(source.notification-added);

Only source.title is logged (notify-send).

I’ll have to guess: You are keeping the source alive after it has been removed, and source.notifications is an empty array (which the plain log() function represents as empty string).

1 Like

At what point is the source removed ?

In fact, to try and understand how I could achieve my goal (to do a specific task whenever a notification has a given subject) I installed this small extension, New Mail Indicator (~100 lines). Basically that extension peeks into source.title, and if it matches the default mail program, it changes its icon. So, I thought, if it can get the notification’s source, it should be able to get the notification’s content. But I can not figure out how.

All I did so far was adding a few log instructions to the function that peeks into source, but the only thing that’s ever logged is source.title (e.g., the program that sends the notification). source.notifications never logs anything, whatever the sender program is (browser, mail client, notify-send,…).

Excerpt :

	// color mail icon related notification
    _on_source_added(tray, source) {
        log(source.title);
        log(source.notifications);
        log(source.notification-added);
        if (source && source.title && source.title == this.app_name) {
			this.new_mail = true;
        	this.icon.icon_name = 'mail-unread-symbolic';
        	this.button.set_style('color: ' + NEW_MAIL_ICON_COLOR + ';');
        }
    }

Ah, that explains the issue.

That’s what happens on the shell side in order to show a notification:

  • create a source
  • add source to messageTray
  • create notification
  • add notification to source

So when the source-added signal is emitted, the source doesn’t have any associated notifications yet. You have to listen to the notification-added signal to track newly added notifications.

1 Like

How do you listen to the notification-added signal ? I tried this, but _on_notification_added() is never called (nothing is logged)

_on_source_added(tray, source) {
    this.notification_added = source.connect('notification-added',this._on_notification_added.bind(this));
}

_on_notification_added(source, notification) {                                                                                                    
    log("notification added");
}


Just like in your code snippet. I can’t tell why it’s not working for you, the message list in the calendar popup does exactly that to track notifications …

Almost there…
It works now, I don’t know why it didn’t last time, maybe a typo somewhere.

One last problem : I can indeed get my notification’s title, but not its body. According to DevDocs, it’s supposed to have a body attribute.

    _on_notification_added(source, notification) {
        log(notification.title);
        log(notification.body);
    }

If I do :

$ notify-send "MY TITLE" "This is a test"

The title gets logged, but not the body

PS : in case it matters, I’m still using Gnome 3.38 (Debian stable)

You are looking at the GNotification documentation, which is the client-side notification API in GIO (read: the API applications use to show notification in gnome-shell).

That’s very different from the Notifications object gnome-shell uses internally to implement the GNotification API (and org.freedesktop.Notifications as used by notify-send).

(Side note: GNotification only has setters for body/title, so you wouldn’t be able to read either title or body if that was the object you are dealing with)

What you are looking for is notification.bannerBodyText.

1 Like

Many many thanks for your efficient help, everything works fine now.

Note : the Notifications object gnome-shell uses internally doesn’t seem to be documented anywhere. Googling gnome and bannerBodyText returns very few results, all of them related to some code snippets, most of them snippets of some extensions.

A recap, if someone has the same question. For the details, read below Florian’s explanations.

_on_source_added(tray, source) {
    this.notification_added = source.connect('notification-added',this._on_notification_added.bind(this));
}

_on_notification_added(source, notification) {                                                                                                    
    log(notification.title);
    log(notification.bannerBodyText);
}

For the details, read this tr

Much of GNOME Shell’s internal API remains undocumented, and also lacks tutorials. If you have time, you can contribute what you’ve learned to gjs.guide :slightly_smiling_face:

Indeed, a Google search for "bannerBodyText" has very paltry results, and I can’t figure out why the GNOME Shell source code wouldn’t be among them.

…Worse, does GNOME’s GitLab instance really not have a source code search?!? Entering bannerBodyText into its search field produces zero results, and I notice that “source code” is not among the selectable search categories.

(Searching the same string in GitHub’s global search produces 360 source-code matches, at least. Unfortunately, while a few are valid, the majority are false-positive hits for a variable named BannerBodyText that’s apparently common in some e-commerce framework; #TIL that GitHub does not have a case-sensitive search option.)

Yes, you can only search for code (or commits) within project scope. Not within global scope. I think that’s done for performance: Searching in GitLab | GitLab. A major infrastructure move was done very recently so they’ll probably want to observe it as-is for a time (the move wasn’t without pain :face_holding_back_tears:) but maybe make a suggestion for this in a separate topic.

1 Like

Aha! Thanks.

Mmm, and even the per-project code results require you to select a particular branch (or tag) in which to display results.

(I guess these limitations are all due to gitlab.gnome.org lacking GitLab’s Elasticsearch-based “Advanced Search” functionality. Or at least not having it yet, if I’m being optimistic.)

The link says “Moved to GitLab Premium in 13.9” so I assume we’re not getting it. That would costs tens of thousands USD yearly.

1 Like

I knew I should’ve trusted my default inclination towards pessimism!