A Drafts URL Factory?

I do occasionally find myself creating URLs for actions, enough that I’ve got a LazyBoard snippet for a Drafts action URL (though that still requires me to encode an action’s title…)

Not sure I see myself using the others that often, but I still do think it’d be useful to have a URL factory as you describe, even if it only serves as a starting point for other uses we can’t yet anticipate. So if you’re asking for expressions of interest, it’s a yes from me.

1 Like

I would find this useful.

1 Like

So I spent a happy hour confecting this:

// Confect URL to open the current draft, using its UUID
URL = "drafts://x-callback-url/open?uuid="+draft.uuid

// Prompt for action name - for Launcher
var p = Prompt.create();

p.title = "For Launcher";
p.message = "Type in launcher name. (Not needed to copy URL to the clipboard.)";

p.addTextField("LauncherName", "Launcher Name", "");

p.addButton("Create Launcher")
p.addButton("Copy To Clipboard")

var didSelect = p.show();

var launcherName = p.fieldValues["LauncherName"];

if (p.buttonPressed == "Create Launcher") {
  // do something
  app.openURL("launcher://x-callback-url/addnew?name=" + encodeURI(launcherName) + "&url=" + encodeURIComponent(URL))
}else if(p.buttonPressed == "Copy To Clipboard"){
  // Copy URL to clipboard
  app.setClipboard(URL)
}

If you place this in a 1-step action it enables you to create a URL to open the current draft.

You can either create a Launcher launcher (sic) with a name you specify, or copy the generated URL to the clipboard.

For the launcher the app prompts you as to which widget to add this launcher to.

Tweaks gratefully received.

2 Likes

Minor point, but at least in the case of a draft, it would be preferred to use the draft.permalink property (docs).

1 Like

Thanks. Works nicely and is much simpler.

So I updated that script per @agiletortoise’s suggestion:

// Confect URL to open the current draft, using its UUID
URL = draft.permalink

// Prompt for action name - for Launcher
var p = Prompt.create();

p.title = "For Launcher";
p.message = "Type in launcher name. (Not needed to copy URL to the clipboard.)";

p.addTextField("LauncherName", "Launcher Name", "");

p.addButton("Create Launcher")
p.addButton("Copy To Clipboard")

var didSelect = p.show();

var launcherName = p.fieldValues["LauncherName"];

if (p.buttonPressed == "Create Launcher") {
  // do something
  app.openURL("launcher://x-callback-url/addnew?name=" + encodeURI(launcherName) + "&url=" + encodeURIComponent(URL))
}else if(p.buttonPressed == "Copy To Clipboard"){
  // Copy URL to clipboard
  app.setClipboard(URL)
}
1 Like

And here’s a similar one to create a link to select the current workspace:

// Confect URL to open the current workspace, using its name
URL = "drafts://x-callback-url/workspace?name=" + app.currentWorkspace.name

// Prompt for action name - for Launcher
var p = Prompt.create();

p.title = "For Launcher";
p.message = "Type in launcher name. (Not needed to copy URL to the clipboard.)";

p.addTextField("LauncherName", "Launcher Name", "");

p.addButton("Create Launcher")
p.addButton("Copy To Clipboard")

var didSelect = p.show();

var launcherName = p.fieldValues["LauncherName"];

if (p.buttonPressed == "Create Launcher") {
  // do something
  app.openURL("launcher://x-callback-url/addnew?name=" + encodeURI(launcherName) + "&url=" + encodeURIComponent(URL))
}else if(p.buttonPressed == "Copy To Clipboard"){
  // Copy URL to clipboard
  app.setClipboard(URL)
}

I’m almost at the point of replicating my large Drafts widget in Launcher - using these scripts. Just a few more to go.

The advantage will be that Launcher can be denser and I might get away with a smaller widget - or one with both my favourite workspaces and actions in.

1 Like

I’m stuck on something:

Ideally I’d like to get a reference to the current Action Group - if that’s meaningful.

Failing that I’d like a list of the installed action group names.

Failing that a list of all the installed action names.

I don’t know if I can do any of the above.

The idea is to automate the creation of a URL to run an action. I’d hate to ask the user to type in the name of an action group. I think if I did I could still get a list of action names in that group.

Thoughts?

Second two can definitely be done.

1 Like

So something like:

let groups = ActionGroup.getAll()
// let groups = TA_actionGroupNames()

let p = Prompt.create()
	p.title = "Select action group"
	p.message = "Choose action group for selection of action"
	
	let ix = 0
	for (let gs of groups) {
		p.addButton(gs.name, ix)
		// p.addButton(gs[ix], ix)
		ix++;
	}

let didSelect = p.show()

let group = ActionGroup.find(groups[p.buttonPressed].name)
let actions = group.actions

let pAc = Prompt.create()
	pAc.title = "Select action"
	pAc.message = "select action to link"
	
	let ax = 0
	for (let action of actions) {
		pAc.addButton(action.name, ax)
		ax++
	}

let didSelectAction = pAc.show()

alert(actions[pAc.buttonPressed].name)

…or an MGCheckListPrompt using a TA_actionNames() array so you could filter down the list by tapping in the first few letters of an action’s name?

1 Like

Thank you. That’s encouragement @sylumer.

And thanks @jsamlarose

… I didn’t realise there was a getAll() method for ActionGroup.

BTW I think there is a selection control in Prompt that I can use, though buttons might work better. Tomorrow I’ll experiment.

1 Like

Let me know how you get on if you use a selection control— that would obviously make for a more compact prompt. I think I mocked this up with buttons simply because it was slightly easier.

That said, I know I refer to it often, but my money would still be on an MGCheckListPrompt for filtering. Invoke, tap a few letters, select, boom.

1 Like

Actually I got started. What I found with Prompt.selection is it doesn’t return the index of the selected item.

So I prepended each selection item with the index (+1).

Then, on return from the dialog I took the item value and hacked the index (+1) off the front.

I have duplicate action groups - so I was in a position to need index number.

I would love to be able to get the selection index directly but never mind.

Prompt’s selection control does look pretty.

1 Like

So I’m not wowed by this one - as I think there’s something missing from the Drafts URL Scheme…

… You will see fragments of an attempt to run an action using its UUID. Unfortunately /runAction Doesn’t supporter a uuid= parameter.

I’ve ended up with two “Basic” action groups and I’m very sure these contain duplicate action names. I’ve had to use the action name in the URL. I don’t know which will actually run.

@agiletortoise any chance of runAction getting a uuid= parameter?

Anyhow this action prompts you for an Action Group. Based on the one you select it prompts you with a list of actions. In common with the previous two actions it then gives you the choice of copying the generated URL to the clipboard or creating a Launcher launcher.

actionGroups = ActionGroup.getAll()
actionGroupNames = []
for(i = 0; i < actionGroups.length;i++){
  actionGroupNames.push((i+1).toString()+ " " + actionGroups[i].name)
}

// Prompt for action group name - for Launcher
var p1 = Prompt.create();

p1.title = "For Launcher";

p1.addSelect("ActionGroups","Action Groups",actionGroupNames,[],false)
p1.addButton("Use Action Group")

var didSelect1 = p1.show()


if (p1.buttonPressed == "Use Action Group") {
  // We've selected an action group and maybe a launcher name - so pick an action
  var launcherName = p1.fieldValues["LauncherName"];
  var actionGroup =p1.fieldValues["ActionGroups"]
  actionGroupIndex = Number(actionGroup.toString().split(" ")[0].trim()) - 1

  actionGroup = actionGroups[actionGroupIndex]
  actionNames = []
  actions = actionGroup.actions

  for(i=0; i < actions.length; i++){
    actionNames.push((i + 1).toString() + " " + actions[i].name)
  }

  var p2 = Prompt.create()

  p2.message = "Type in launcher name. (Not needed to copy URL to the clipboard.)";

  p2.addTextField("LauncherName", "Launcher Name", "");

  p2.addSelect("Actions", "Actions", actionNames,[],false)
  p2.addButton("Create Launcher")
  p2.addButton("Copy To Clipboard")

  var didSelect2 = p2.show()
  var actions2 = p2.fieldValues["Actions"]
  //actionIndex = Number(actions2.toString().split(" ")[0].trim()) - 1

  actionNameArray = actions2.toString().split(" ")
  actionNameArray.shift()
  
  URL = "drafts://x-callback-url/runAction?text=&action=" + encodeURIComponent(actionNameArray.join(" "))
  if(p2.buttonPressed == "Create Launcher"){
    var launcherName = p2.fieldValues["LauncherName"]

    app.openURL("launcher://x-callback-url/addnew?name=" + encodeURI(launcherName) + "&url=" + encodeURIComponent(URL))
  }else if(p2.buttonPressed == "Copy To Clipboard"){
    // Copy URL to clipboard
    app.setClipboard(URL)
  }
}

Flip it around. /open supports both UUID and action together.

Sorry, I meant the action’s UUID - which it certainly has. Not the draft’s.

1 Like

I don’t remember seeing a UUID for actions in the JSON they get exported to. I was pretty sure I added them all the properties (at the time at least) in for the TA_populateMore action function.

It sounds like it might just be a case of doing some housekeeping and tidying up your action names if they are not currently unique.

1 Like

Right; I probably will tidy up.

However the action object in Drafts javascript has a UUID. It would be better - for uniqueness - if Drafts supported it as part of the URL scheme. A nit, I know.

Actions do not have persistent, portable UUIDs. They should be identified by unique name.

1 Like

Thanks. Now I know.

BTW here’s my prototype Drafts-related widget in Launcher:

It doesn’t have counts - like the real Drafts large widget does.

Blue is non-Action actions. Green will be Action actions. Black is workspaces.

One advantage is I can add up to 35 items in the large widget.