Creating an mailto handler app on Mac OSX

半腔热情 提交于 2019-12-13 15:35:00

问题


I am using mu4e in Emacs as my mail client, but I cannot figure out how to create a script that can pass on the mailto url to the following shell script:

#!/bin/sh
# emacs-mailto-handler

mailto=$1
mailto="mailto:${mailto#mailto:}"
mailto=$(printf '%s\n' "$mailto" | sed -e 's/[\"]/\\&/g')
elisp_expr="(mu4e~compose-browse-url-mail \"$mailto\")"

emacsclient -a \"\" --create-frame -n --eval "$elisp_expr" \
        '(set-window-dedicated-p (selected-window) t)'

When I call this script on my command line it opens up a new frame in Emacs with the correct address and subject:

$ emacs-mailto-handler "mailto:webmonkey@wired.com?subject=I-love-cats-too%21"

The problem is that I need to create an app that can be configured to be the default mail client in Mac OSX. I have tried to use Automator and Platypus to call my shell script, but I cannot get them to pass the argument they are receiving to the shell script. (I have see this question: OS X: how to make command-line script appear as helper application to handle mailto?, but that does not do the trick for me.)

At the end of the day I just have to be able to get the app to do this script call: emacs-mailto-handler "mailto:webmonkey@wired.com?subject=I-love-cats-too%21" where the mailto link is what is coming from the browser.

Any clues on this would be most welcome!

Thanks in advance, Torben


回答1:


This will require a bundled app of some sort.

When an app handles URLs, it does not receive them among its command-line arguments (the argv argument array of main()). In fact, the app can receive requests to open URLs at any time during its run, not just at launch. So, it definitely requires a mechanism other than command-line arguments to receive them. That precludes a script from receiving the URL in its arguments.

Instead, it receives the request to open or get a URL as an Apple Event of class kInternetEventClass and ID kAEGetURL. The app sets up a handler for that Apple Event and the handler is invoked by the frameworks. In order for the frameworks to receive and dispatch the Apple Event, the app has to a) be using those frameworks, and b) provide an opportunity for the frameworks to monitor the inter-process communication mechanism they use internally to pass events around. Again, this is not something a shell script can do.

In a Cocoa app, this would entail putting code like the following in the early startup code of the app, such as the -applicationWillFinishLaunching: method of the app delegate:

    NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];

Then one would add a method whose name matches the selector passed above; in this case -handleGetURLEvent:withReplyEvent::

- (BOOL)handleGetURLEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSAppleEventDescriptor* directObjectDescriptor = [event paramDescriptorForKeyword:keyDirectObject];
    NSString* urlString = [directObjectDescriptor stringValue];
    NSURL* url = [NSURL URLWithString:urlString];
    // ... do something with url ...
}

In addition to that code, the app would have to declare its ability to handle URLs of particular schemes in its Info.plist file, under the CFBundleURLTypes key. An entry such as the following would declare the ability to handle mailto: URLs:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>Email Address URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>mailto</string>
            </array>
        </dict>
    </array>

It is conceivable that the applications generated by either Platypus or Automator could have the above URL-support code in them. That much is general-purpose. Declaring support for specific URL schemes is something that they'd have to let you configure. There's no way to generally declare support for any/all schemes.

I hacked on the Info.plist file of an app generated by Automator to see if I could make it handle URLs. It didn't work. However, I'm testing with an app generated by Automator from OS X 10.6. It's possible that newer versions of Automator added support. That would explain the success reported in that other question you cited.

I haven't checked with Platypus.




回答2:


For Emacs I managed to make it work for me using AppleScript:

on open location mailtostr
    do shell script "/usr/local/Cellar/emacs/26.1_1/bin/emacsclient -c --eval '(browse-url-mail \"" & mailtostr & "\")' > /dev/null 2>&1 &"
    tell application "Emacs" to activate
end open location


来源:https://stackoverflow.com/questions/22848223/creating-an-mailto-handler-app-on-mac-osx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!