Is there a way to make Ubuntu read out notifications?

Ubuntu has a very cool notification system. Is there a way to make Ubuntu read out notifications when they appear?

Or is it possible to link the text in notifications to espeak?


This question is really interesting so as the answer.

dbus-monitor when executed waits for the signal and when arrives it catches and gives the appropriate information about it. Similarly it can be executed to get the info about Notifications. When executed:

dbus-monitor "interface='org.freedesktop.Notifications'" | grep --line-buffered "member=Notify\|string"

It will wait for the notifications and when any notification arrives it gives the information of the notifications.

For example when sound is increased/decreased or any song track is changed or any other it gives the message. I'm manually creating a desktop notification using notify-send command on any other terminal:

notify-send "Hello How are you?"

Then the first terminal in which dbus-monitor command is executing will give message like:

saurav@saurav-P4I45Gx-PE:~$ dbus-monitor "interface='org.freedesktop.Notifications'" | grep --line-buffered "member=Notify\|string"
   string ":1.473"
method call sender=:1.474 -> dest=:1.475 serial=7    path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications;  member=Notify
   string "notify-send"
   string ""
   string "Hello How Are You?"
   string ""
         string "urgency"

Now above output can be easily passed to espeak to read message. For example,

Replacing the above dbus-monitor command with following will read the notification message:

Check, How does it work:

  • Execute this command in a terminal and leave it running:

    dbus-monitor "interface='org.freedesktop.Notifications'" | grep --line-buffered "string" | grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v | grep --line-buffered '.*(?=string)|(?<=string).*' -oPi | grep --line-buffered -v '^\s*$' | xargs -I '{}' espeak {}
    

    I know it has become very long, but there is no other way to make it small because the filtering of actual notification made it lengthy.

  • Then run a desktop notification either the way I described above using notify-send or any thing else. I'm using notify-send. So executing following command in other terminal:

    notify-send "Hello! I am Saurav Kumar."
    

    As soon as you execute the command it will speak(read) the notification.

Although it ate my 4-5 hours, but I'm happy now to make it working.

You can also make your own command like saynoti and execute it every time you want a reading notification. By following these steps you can do so:

  • First save the actual command to a file called saynoti. You can use any file name that will become your actual command name.

  • Then make the file executable and move or copy it to /bin:

    chmod +x saynoti
    sudo cp saynoti /bin
    
  • Now you can simply execute your new command to start Speaking Notification:

    saynoti
    
  • To kill the running process you can execute this command:

    pkill dbus-monitor
    

    or simply press Ctrl + C on the terminal where saynoti is running.

  • You can also run saynoti every time your system starts by making it a start-up application.

I would like to say thank you for this question. Because of this question, I learned a lot of things. :)

Reply if you get any problem or need any further change/modification. I'm sure you will be happy to get the final working version.