3

I have a script that I have written that I would like to use whenever I click on a mailto: link. Which means I need to select it as the default Mail handler in my default applications.

But how do I register a mailto handler so that I can select it in the default applications?

Using Ubuntu 18.04, not virtualized.

I am not using a specific mail application, I am trying to write a script that will process the mailto links for me (for example, using different mail clients for different destination domains), but I need to convince Ubuntu that this script is an option for a default mail application

K7AAY
  • 17,705

1 Answers1

0

Thanks to @danzel, I found the answer was indeed to use a .desktop file.

So I created a simple script that allows you to specify a set of different mailers - I use my work email (Outlook for web), my personal email (via ssh) and sometimes gmail.

Here's the code:

#!/usr/bin/ruby
# 1) Put "mailto.desktop" in /usr/share/applications
# 2) sudo update-desktop-database
# 3) System Prefs -> Details -> Default Applications

require 'uri'

# %SUBJECT% decoded subject, i.e.:  "Hey guys!"
# %subject% encoded subject, i.e.:  "Hey%20guys%21"
# Same for %to% and %body%
# Also %mailto% for initial value of "mailto:..."
MAILERS = {
    'Home' => ['ssh','-t','my-home-server.com','elm','-s','"%subject%"','%to%'],
    'Work' => ['browser','https://outlook.office.com/?path=/mail/action/compose&to=%mailto%'],
    'Gmail' => ['browser','https://mail.google.com/mail/u/0/?&view=cm&fs=1&to=%TO%&su=%SUBJECT%&body=%BODY%']
}

def fatal(title,message)
    system('zenity','--width','400','--height','250','--error','--title',title,'--text',message)
    exit -1
end

def clean(str)
    #'"'+str+'"'
    str.sub(/"/,'')
end

#########################
# Figure out mailto:
#########################
mailtoStr=ARGV.join('')
mailtoStr.sub!(/^mailto:/,'')
mailto = mailtoStr.split(/[\?\&]/)
mailtoStr.sub!(/\?/,'&')  # Outlook is confused if you use:  'mailto:addr@some.com?subject=...' instead of '..&subject..'
mailHash = Hash.new
mailto.each { |m|
    m.match(/^([^=]+)=(.*)/m)
    key,val = $1,$2
    key,val = 'to',m unless key
    mailHash[key.upcase] = clean(val)
    mailHash[key.downcase] = clean(URI.decode(val))
}
fatal("No 'to' specified",'Need to specify an address in the mailto') unless mailHash['to']

FIELDS = %w(to body subject mailto)
def sendInfo(mailHash,mailtoStr,field)
    return '' unless field
    return mailtoStr if field=='mailto'
    return '%'+field+'%' unless FIELDS.index(field.downcase)
    mailHash[field] || ''
end

#########################
# Pick mailer
#########################
mailer = 'Work' if mailHash['to'].match(/@my-work-domain.com$/)
mailer ||= `zenity --width 400 --height 250 --title "Mailer select" --text "Choose mailer for #{mailHash['to']}:" --list --column "Mailer" #{MAILERS.keys.map { |m| '"'+m+'"' }.join(' ')}`
mailer.chomp!

fatal('Unknown Mailer',"Don't know mailer selection #{mailer} or no mailer selected") unless MAILERS[mailer]

cmd = MAILERS[mailer]
cmd.each { |c|
    c.gsub!(/%([^%]+)%/) { sendInfo(mailHash,mailtoStr,$1) }
}
#p cmd
system(*cmd)
# Sometimes ssh is broken on my system...
system(*cmd) if cmd[0].match(/ssh/) && $?.exitstatus!=0

And the mailto.desktop which goes in /usr/share/applications:

[Desktop Entry]
Encoding=UTF-8
Name=Custom mailto Mail Handler
Comment=Handle mailto links
GenericName=Mail Client
Keywords=Email;E-mail
Exec=/home/dave/bin/mailto %u
Terminal=true
X-MultipleArgs=false
Type=Application
Icon=mail-send
Categories=Application;Network;Email;
MimeType=x-scheme-handler/mailto;application/x-xpinstall;
StartupNotify=true

I have "Terminal=true" because I use ssh, and that's where the ssh window goes, otherwise the terminal window disappears pretty quick. If you don't use any terminal based mailers you can set that to false.