Closed kzshantonu closed 2 years ago
This can be achieved with JavaScript, by using a regular expression.
Assuming you have created a variable named myInputVariable
, into which you are sharing, and another variable called myOutputVariable
which receives the URL, then your JavaScript code could look like this:
const sharedValue = getVariable('myInputVariable')
const matches = sharedValue.match(/\bhttps?:\/\/\S+/gi);
const url = matches[0];
setVariable('myOutputVariable', url);
Essentially what this does it (line by line):
myInputVariable
into a JavaScript variableundefined
if there isn't one)myOutputVariable
, which you can then use elsewhere in your shortcut, e.g. in the request body.Regular expressions can be a tricky topic, especially when used to extract something as complex and laden with edge cases as URLs, so there's a good chance that this approach will not work for every case. A more suited regular expression might be needed, but there's likely none that would cover every case.
Hmm. I get this
Tested with this text JPEG of Shakespeare is also a zip file containing his complete works (2018) - https://news.ycombinator.com/item?id=33312441
Sorry, I had a typo in my code snippet (line 2 should have used "sharedValue" instead of "string"). I updated it now, please try again.
Seems to be working now. Thanks so much
Glad to hear it worked 👍🏻
@Waboodoo Hi, sorry to bother again. I'm writing a new guide for linkding, this time with multiple choices for tags.
This POSTs the previous cleaned_url
and not the one shared from share sheet.
Would you like to take a look at my JSON and see what I'm doing wrong?
{
"categories": [
{
"id": "e260b423-db01-4743-a671-2cd38594c63c",
"layoutType": "wide_grid",
"name": "Shortcuts",
"shortcuts": [
{
"bodyContent": "{{7b26d228-4ad6-4b1c-8b7b-076dc03385cc}}",
"codeOnPrepare": "const sharedValue \u003d getVariable(\u0027text_and_url\u0027)\nconst matches \u003d sharedValue.match(/\\bhttps?:\\/\\/\\S+/gi);\nconst url \u003d matches[0];\nsetVariable(\u0027cleaned_url\u0027, url);",
"contentType": "application/json",
"description": "bookmark link",
"headers": [
{
"id": "b66dd9b9-13e8-4802-b527-6e32f3980f4b",
"key": "Authorization",
"value": "Token {{908e3a30-ae82-400d-93c8-561c36d11d6d}}"
}
],
"iconName": "flat_grey_pin",
"id": "871c3219-9e9f-46bb-8a7f-78f1496f78fc",
"method": "POST",
"name": "Linkding",
"responseHandling": {
"failureOutput": "simple",
"uiType": "toast"
},
"url": "{{26253fe2-d202-4ce8-acd1-55c1ad3ae7d1}}/api/bookmarks/"
}
]
}
],
"variables": [
{
"id": "26253fe2-d202-4ce8-acd1-55c1ad3ae7d1",
"key": "linkding_instance",
"value": "https://your.linkding.host.no.slashed.end"
},
{
"id": "6c7bad39-dc69-4993-9661-9cc834a2c929",
"key": "linkding_tag_default",
"value": "your_default_tag"
},
{
"id": "a3c8efa2-3e3a-4bb4-8919-3e831f95fe6a",
"jsonEncode": true,
"key": "linkding_tag",
"message": "Comma separated",
"title": "One or more tags",
"type": "text"
},
{
"id": "908e3a30-ae82-400d-93c8-561c36d11d6d",
"key": "linkding_api_key",
"value": "your_api_key_here"
},
{
"id": "d76696e7-1ee1-4d98-b6f9-b570ec69ef40",
"key": "cleaned_url"
},
{
"flags": 1,
"id": "da66cdad-8118-4a87-9581-4db33852b610",
"key": "text_and_url",
"message": "Any text that contains one URL",
"title": "URL",
"type": "text"
},
{
"data": "{\"select\":{\"multi_select\":\"false\",\"separator\":\",\"}}",
"id": "7b26d228-4ad6-4b1c-8b7b-076dc03385cc",
"key": "tag_yes_no_default",
"options": [
{
"id": "bc81b3e1-ad62-4170-9ac2-e25f27ece1fe",
"label": "Yes",
"value": "{{5be61e61-d8f5-475b-b1b1-88ddaebf8fd5}}"
},
{
"id": "61204f52-e952-4a41-b55e-b192d7fd77df",
"label": "No",
"value": "{{71ac9c4d-c03e-4b6f-ad75-9c112a591c50}}"
},
{
"id": "2c09a721-ceef-4057-8d4c-46757ce2f444",
"label": "Use default tag",
"value": "{{541ae647-2f5e-4e70-ae99-f4f846e2fb79}}"
}
],
"title": "Tagged?",
"type": "select"
},
{
"id": "5be61e61-d8f5-475b-b1b1-88ddaebf8fd5",
"key": "request_body_tagged",
"value": "{ \"url\": \"{{d76696e7-1ee1-4d98-b6f9-b570ec69ef40}}\", \"tag_names\": [ \"{{a3c8efa2-3e3a-4bb4-8919-3e831f95fe6a}}\" ] }"
},
{
"id": "71ac9c4d-c03e-4b6f-ad75-9c112a591c50",
"key": "request_body_untagged",
"value": "{ \"url\": \"{{d76696e7-1ee1-4d98-b6f9-b570ec69ef40}}\" }"
},
{
"id": "541ae647-2f5e-4e70-ae99-f4f846e2fb79",
"key": "request_body_default_tagged",
"value": "{ \"url\": \"{{d76696e7-1ee1-4d98-b6f9-b570ec69ef40}}\", \"tag_names\": [ \"{{6c7bad39-dc69-4993-9661-9cc834a2c929}}\" ] }"
}
],
"version": 54
}
I see you are using variables within variables. The problem with that is that the order in which these are resolved is not in your favor. Basically, a variable's value is resolved at the beginning of the shortcut's execution. That means that when you trigger your shortcut, the app will try to determine the value of request_body_tagged
, request_body_untagged
and request_body_default_tagged
, and because these depend on the value of cleaned_url
, cleaned_url
is also resolved at that point. So afterwards, all of these variables have their known value and won't be resolved again for the rest of the execution. Now at some point, with your script, you're changing the value of cleaned_url
, but at this point it's too late for the other 3 variables to care about this change, since they already have a value.
This is a bit of an edge case that I wasn't sure if anyone would even use, but it looks like you found it. Currently there's no straightforward solution for this. You basically have 2 choices:
cleaned_url
after you've update its value, by calling setVariable
for each of them.cleaned_url
accordingly. This would be the shortcut that you trigger/share into. This shortcut would then trigger a second shortcut (using the enqueueShortcut()
function), which is only concerned with making the actual HTTP request using the variables prepared by the first one.I'll do a bit of investigation to see if I could change the behavior of the app here, so that it only resolves the variable values after the initial Scripting. That would enable your current approach to work out-of-the-box. But I can't yet say whether that is possible, or when I'll be able to make this change, if at all.
Alternatively: Instead of using a Multiple Choice Variable, you could also handle that entirely using Scripting, via the showSelection()
function (although, it won't allow you to show a title on the selection dialog).
Your selection would then look like this in code:
const tagged = showSelection({
'yes': 'Tagged',
'no': 'Not tagged',
'default': 'Use default tag',
});
if (tagged == 'yes') {
setVariable('request_body', getVariable('request_body_tagged'));
} else if (tagged == 'no') {
setVariable('request_body', getVariable('request_body_untagged'));
} else {
setVariable('request_body', getVariable('request_body_default_tagged'));
}
More on that here: https://http-shortcuts.rmy.ch/scripting#show-selection
Alright, looks like I was able to make the change, which means that once the next version (2.27.0) is released, you should be able to go with your original approach. I have yet to do some more testing though, and I don't have a date set for this release yet, so you might still want to go with some of the workarounds/alternatives I suggested above.
Hmm, great thanks for looking into this. Definitely learned some new stuff here
@kzshantonu Version 2.27.0 is now available for beta testing. It includes the change I mentioned above, which should make your original approach work out-of-the-box. If you want to give it a try, you can join the beta program here: https://play.google.com/apps/testing/ch.rmy.android.http_shortcuts After that you can install the latest beta version from the Play Store.
Is your feature request related to a problem? Please describe. Hi, really love your work. I wrote a guide to help users add URLs to linkding bookmark manager using this app. Some apps however, share some extra text along with the URL (eg: title, promo, etc) hence my guide don't apply to those apps.
Describe the solution you'd like An option to filter out only the URL from a bunch of text.
I'm aware that there is JavaScript support. I unfortunately know nothing about JavaScript. If JavaScript can do what I want to do, please let me know how to