Jump to content

Trigger macOS Service from Alfred


Recommended Posts

Hi Alfred team, is there a way to trigger macOS service from Alfred

 

Use case:

=========

I plan to use TextBuddy (for text transformations) and it has mac services to push text toward it and then it shows a popup to perform actions on it. However, macOS services are not available in all applications e.g. Obsidian, which makes it less useful there.

 

What I am trying

=========

Since some apps dont have services support, I can to capture the text from these applications via Alfred Universal Action (or keywords), and then push it towards TextBuddy. But TextBuddy services use the text selected on the screen, not what was in Alfred. Is there a way to select this text inside alfred, and then trigger the TextBuddy service from alfred (alfred app does have service support)

 

Workflow I tried: https://www.dropbox.com/s/93ke3egp503cwcw/tb.alfredworkflow?dl=0

 

Link to comment

Thanks @vitor. I tried this, it does popup a few services, but is not showing "Process With TextBuddy", which is surprising since it shows "Send to TextBuddy" and both those services are applicable to text. Anything wrong I am doing?
 

CCing @deanishe in case they might be able to help with this

 

 

Screen Shot 2021-11-24 at 7.33.10 PM.png

 

EDIT1: In case this helps, I noticed a behavior where adding the shortcut "Send to TextBuddy" removes it from this list and removing it brings it back 🤔.

Edited by andy4222
Link to comment
9 minutes ago, deanishe said:

 

Have you tried reading the documentation and actually looking at the workflow?

My bad 🤦‍♂️. I went into the rabbit hole of figuring out the service now showing up issue so missed the "red" workflow. It solves my second problem.

 

The first one still seems weird (TextBuddy services not showing up, and another one missing when a shortcut is assigned to it in services menu). It is also not triggering when specifying the name via the "red" workflow

Link to comment
4 hours ago, andy4222 said:

It is also not triggering when specifying the name via the "red" workflow

 

No. If the service doesn't show up in the search, the workflow probably isn't finding. I don't have TextBuddy or an OS it supports, so I can't say much more than that unless you want to dig out its service definitions for me.

 

Note: The workflow only supports services that define their input as pasteboard types. Services that define input as filetypes are ignored.

Link to comment

@deanishe Understood.

 

How do I pass in the macOS selection instead of the clipboard content when executing specific service with this workflow? I see this line fetches the clipboard data.

 

let ret = $.NSPerformService(service, $.NSPasteboard.generalPasteboard)

 

I could maybe modify it as:

 

//argv[0] has service name
//argv[1] has macOS selection
let ret = $.NSPerformService(service, argv[1])


 

But I am not sure how do I send in two args to this script, since "Keyword" object only allows one and the current workflow uses "Text" param to set the Service name. Any suggestions?

 

 

EDIT:

====

After spending more time on this, I did some changes that seem to be working. Took a while though, since I couldn't find any docs on this and the IDE didn't suggest anything.

 

ObjC.import('Cocoa')
ObjC.import('stdlib');

function run(argv) {
	let service = $.getenv('service');	//variable set via args utility
	let text = $.getenv('input');		//variable set via args utility

	$.NSPasteboard.generalPasteboard.clearContents;
	$.NSPasteboard.generalPasteboard.writeObjects([text]);

	console.log("performing service %s", service)
	console.log("performing on text %s", $.NSPasteboard.generalPasteboard.pasteboardItems[0])

	let ret = $.NSPerformService(service, $.NSPasteboard.generalPasteboard)
	if (!ret) return `Service “${service}” failed`
}

 

 

What language is this? JXA or Objective C or both? Where do I find the docs for it since it was a nightmare finding dev docs 🧐.

I also wanted to log the pasteboard content for debugging if needed but "$.NSPasteboard.generalPasteboard.pasteboardItems" seems to be some sort of object. How can I get the clipboard content out of it?

 

 

 

 

 

 

Edited by andy4222
Link to comment
3 hours ago, andy4222 said:

After spending more time on this, I did some changes that seem to be working.

 

Not optimal. You're losing a lot of the workflow's functionality by relying on Alfred to give you the current selection. The clipboard can hold lots of different types (URLs, files, text, rich text, etc.) and different macOS services respond to different ones. Alfred's "macOS clipboard contents" input throws away everything but text.

 

Look at the top-left corner of the workflow (Run with current selection). You need to copy that little section to your custom Hotkey and let the workflow do the copying itself if you want to use the current selection.

 

3 hours ago, andy4222 said:

What language is this? JXA or Objective C or both?

 

I'm using Cocoa libraries from JXA, so it's Objective-C twisted up to fit JavaScript.

 

3 hours ago, andy4222 said:

it was a nightmare finding dev docs 🧐.

 

Welcome to the party :(

 

JXA is a poorly-documented nightmare.

 

3 hours ago, andy4222 said:

$.NSPasteboard.generalPasteboard.pasteboardItems" seems to be some sort of object. How can I get the clipboard content out of it?

 

See the WaitForPasteboard.js script referenced above.

Link to comment
4 minutes ago, deanishe said:

Look at the top-left corner of the workflow (Run with current selection). You need to copy that little section to your custom Hotkey and let the workflow do the copying itself if you want to use the current selection.

 

Yes, I tried that initially, unfortunately as I mentioned in my initial question, I cannot see the "Process with TextBuddy" and "Send to TextBuddy" services (and many more services) after using the "Run with current selection" flow. Not sure why, but I suspect that "Filter macOS services" is not fetching that services from the list of services. This only happens for apps that don't support services.

 

In the "Execute service" flow though (red workflow), since we mention the service name,I suspect it is forcefully running it, but it works. The good thing is, it is also executing services for apps that don't have services support like Obsidian.

 

 

 

 

 

Link to comment
13 minutes ago, andy4222 said:

Yes, I tried that initially, unfortunately as I mentioned in my initial question

 

We're not talking about the same things. The top-left corner of the workflow only puts the current selection on the pasteboard. It has nothing to do with finding or listing or running services.

 

Bottom line, if you let Alfred get the selection for you, it will not work properly with files.

Link to comment
Just now, deanishe said:

Bottom line, if you let Alfred get the selection for you, it will not work properly with files.

 

Understood. I will keep this in mind if I have to trigger services for anything other than text.

 

 

BTW, why would the services not list in "Filter macOS services" but be executable directly (by providing a name)? Is it because the way services register themselves?

Link to comment
25 minutes ago, andy4222 said:

Is it because the way services register themselves?

 

I would imagine it's because of the hacky way the workflow finds the list of services. There is no (public) API for enumerating services, and the workflow doesn't fully understand the undocumented private files it digs through.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...