Waboodoo / HTTP-Shortcuts

Android app to create home screen shortcuts that trigger arbitrary HTTP requests
https://http-shortcuts.rmy.ch
MIT License
1.17k stars 113 forks source link

Option to filter everything except only the URL from certain apps #298

Closed kzshantonu closed 2 years ago

kzshantonu commented 2 years ago

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

Waboodoo commented 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):

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.

kzshantonu commented 2 years ago

Hmm. I get this Screenshot_20221024-162227.jpg

kzshantonu commented 2 years ago

Tested with this text JPEG of Shakespeare is also a zip file containing his complete works (2018) - https://news.ycombinator.com/item?id=33312441

Waboodoo commented 2 years ago

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.

kzshantonu commented 2 years ago

Seems to be working now. Thanks so much

Waboodoo commented 2 years ago

Glad to hear it worked 👍🏻

kzshantonu commented 1 year ago

@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
}
Waboodoo commented 1 year ago

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:

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

Waboodoo commented 1 year ago

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.

kzshantonu commented 1 year ago

Hmm, great thanks for looking into this. Definitely learned some new stuff here

Waboodoo commented 1 year ago

@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.