Jump to content

leahcim

Member
  • Posts

    15
  • Joined

  • Last visited

Posts posted by leahcim

  1. Thanks @Vero! Yes, UTIs can be dragged & dropped which is very convenient - however, in my case I want to make it dynamic so that I can specify the extension from Alfred's input box. Therefore, I cannot pre-set any extension filter in the File Filter node, but need to dynamically retrieve it from the input and then set it in the node via a JSON update. And the only solution I've found is to parse the available UTIs from MacOS.

  2. Hello all

     

    as I understand

    1. the default in keyword allows to search contents of a file, but cannot be limited to a certain extension (all parts of the search expression will be used to match against the contents)
    2. the File Filter node in custom workflows allows to filter by extension, but requires to provide the UTI and does not allow to simply search for ".txt" as an extension. Determining the list of available UTIs and their respective extensions is not trivial

     

    Is my understanding of above behaviour correct?

  3.  

     

    For all fellow ClickUp users - let me know in case of questions or if you have ideas to improve this workflow!

     

     

    ClickUp 2.0 Alfred Workflow

    This workflow allows you to use Alfred to quickly add tasks and search tasks within ClickUp 2.0.

    Note: This is the first public release - bugs may be numerous. Let me know if you find any!

    Installation & Requirements

    For this workflow you need

    To install, download the latest release and open the .alfredworkflow file.

    Configuration

    Before being able to connect to ClickUp, certain parameters need to be configured. Configuration can be initiated via the cu:config command in Alfred, or by simply typing cu when starting the workflow for the first time. See ClickUp Terminology for an explanation of terms.

    The following parameters are required:

    • ClickUp API key: API token generated in ClickUp (either a public token or a private SSO token). Allows us to connect to your ClickUp account. Example: pk_12345_sdhu2348...
      • Can be retrieved from ClickUp app > Profile Icon (bottom left) > Apps > Generate API key
      • Note: Treat this key as your password. It will be stored in the MacOS Keychain.
    • Id for ClickUp Workspace: Id of the Workspace your tasks reside in. Example: 2181159
    • Id for ClickUp Space: Id of the Space that defines your available Labels and Priorities. Example: 2288348
    • Id for default ClickUp List: Id of the List you want new tasks to be added to by default. Example: 4696187
    • Default Tag: Name of the tag you want to attach to all new tasks (this is only required for the cul command). Example: to_review

    Note: Your ClickUp user account must be authorized for the specified workspace, space, folder and list.

    The following parameters are optional:

    • Id for ClickUp Folder: Id of the Folder your List is part of. Example: 2844542
    • Default Due Date: If no Due date is specified when creating a task (via @), this Due date is used. Example: h2
    • Hierarchy Levels to limit Search Results: When searching (cus, cul) you can limit the tasks returned by Space, Folder, List or a combination of those. For example, limiting by space,folder would use the Id for ClickUp Space and Id for ClickUp Folder to limit the search results by. If you do not provide a value, all tasks for your Workspace will be returned.
    • Show Notification: Whether to show a notification after creating a task.

    You can validate all parameters via cu:config validate. This should be your first step if anything does not work.

    Usage & Commands

    Creating Tasks

    Creating a task

    Tasks can be created by providing a title and optional commands.

       cu <Title> [:<Description>] [#<Tag>] [@<Due Date>] [!<Priority>] [+<List>]
    
    • Press Enter to create the task.
    • Press ? + Enter to open the created task in ClickUp (web)

    Commands let you add additional information to your task:

    • Commands are added via one-character shortcuts
      • : Description of a task (max. 1 possible)
      • # Tag of a task (N possible). A list of available tags will be provided and can be filtered by typing e.g. #myLa. Additional tags are specified via another command shortcut, e.g. cu Task #Tag1 #Tag2. If you have specified a default tag, it will always be added. Tags may contain spaces. To create a new tag, simply type its name and press Space. Tags are cached for 10 minutes.
      • @ Due date of a task (max. 1 possible).
        • m<number> Task is due in <number> minutes
        • h<number> Task is due in <number> hours
        • d<number> Task is due in <number> days
        • w<number> Task is due in <number> weeks
      • ! Priority of a task (max. 1 possible). A list of available priorities will be provided and can be filtered by typing e.g. !1 or !Urge. If not specified, priority is Normal.
        • !1 Task has priority of Urgent
        • !2 Task has priority of High
        • !3 Task has priority of Normal
        • !4 Task has priority of Low
      • + List a task is assigned to (max. 1 possible). A list of available lists (ha) will be provided and can be filtered by typing e.g. +myLi. If you do not specify a List, your default will be used. Lists are cached for 2 hours.
    • Commands are optional
    • Commands are separated by space
    • Commands can be in any sequence
    • If no Due date or List is specified via a command, default values are used (see Configuration)
    • Caveat: If you want to use @, ! or + in either title or content, do not use a space before. Otherwise the character will be identified as a command signifier.

    Examples

    cu Clean the kitchen :Before my wife gets angry #Housework @h4 !1
    

    Creates a task titled "Clean the kitchen", with description "Before my wife gets angry", tagged with "Housework", having a priority of "Urgent" and due in 4 hours , assigned to your default list.

    cu Clean the kitchen #Housework #Wife +Personal
    

    Creates a task titled "Clean the kitchen", tagged with "Housework" and "Wife" due in 2 hours (your default) and assigned to List "Personal".

    Searching Tasks

    You can search through all of your tasks within your ClickUp workspace. All open tasks matching your search term will be returned. The search uses fuzzy matching, so Test will find Test Task and Ted rest. You can use cus [<status>] to filter tasks by status, e.g. cus [Open].

    cus <search terms>
    
    • Press Enter to open the task in ClickUp (web).
    • Press ? + Enter to close the selected task (Status = Closed).

    Listing Created Tasks

    You can list all of your tasks created via Alfred. This might be convenient if you created tasks in a hurry and want to go through them later in detail.

    cul
    
    • Press Enter to open the task in ClickUp (web).
    • Press ? + Enter to close the selected task (Status = Closed).

    Note: This only works if you defined a default tag via cu:config defaultTag as the tasks are filtered by this tag.

  4. 2 hours ago, vitor said:

     

    No, they aren’t, because you’re not giving their changing input as the argument to the script, you’re giving the fixed value from the variable you set up.

     

    That would call the Script Filter with the same input on each keystroke, but is easily avoided by ticking the Alfred filters results checkbox, making it run only once.

    Yes, that is what I meant - the user could "change" his input i.e. repeat it by typing anything.

     

    I found out about the checkbox as well, its effect is well hidden!

     

    Thanks a lot, all is working now - API gets called only once, user is redirected to web page where their input is displayed.

  5. 15 hours ago, deanishe said:

    No, it doesn't. You collect the user's query with a Keyword element, pass it to a Script Filter as a variable, and just use the Script Filter to retrieve and show the results.

     

    Good point. Having a Keyword node and a Script Filter node would mean that

    • the user enters the keyword and text
    • the input is passed to the Script Filter
    • the user is still able to enter/change his input, causing the Script Filter to be re-started for each keystroke, causing multiple callouts

    Is there a way to block the input field in the Script Filter? I've tried setting an environment var that is changed when the script is called, however as the Script Filter is restarted with each keystroke, also this var's value is reset...

  6. Thank you, @vitor!

    On 1/27/2020 at 12:37 AM, vitor said:

    No, but some people used to make Script Filters in a way they would only run after you typed a period. Make your script exit early unless the last character is a period. When the caracter is a period, strip it from the argument and run the rest of the script.

     

    I have seen that as well. Unfortunately, that seems a bit cumbersome from a user's perspective - as a user, I simply want to hit 'Enter' once I am done entering my text. As a developer, I don't know whether the user is done - or just waiting a few seconds.

     

    On 1/27/2020 at 12:37 AM, vitor said:

    After you connect two nodes, you’ll see some connecting lines will have a circle in the middle. Double-click it and tick Don’t close the Alfred window on actioning result to keep the window open.

     

    Good to know!

     

    On 1/27/2020 at 12:37 AM, vitor said:

    Stick an Argument and Variables Utility node in between them and delete the Argument.

    That works, good to know as well - however, this also means that my Script Filter no longer has any input to display the list item, as {query} is now empty. Is there a way to have the Script Filter use the {query} to display a list item, but without populating Alfred's input box? Here is an example workflow: Example Workflow - v1 After the Args&Vars node, {query} will be empty (as intended, to clear the input field) - unfortunately, this also means the Script Filter receives no input for showing the list items:

    14:25:12.385] MyWF[Run Script]  Passing output '{
    	"items": [
    		{
    			"title": "Created task - test",
    			"valid": true,
    			"arg": "www.test.de",
    			"icon": {
    				"path": "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarInfo.icns"
    			}
    		}
    	]
    }
    ' to Arg and Vars
    [14:25:12.388] MyWF[Arg and Vars] Processing complete
    [14:25:12.389] MyWF[Arg and Vars] Passing output '' to Script Filter

    I've tried storing the {query} value before clearing via Args&Vars in a variable, and then use this to iterate over in Script Filter to show it as list items, but it did not work, as I run into the same problem again that the input field is populated with JSON - see here for an example: Example Workflow - v2

  7. I am looking to implement a workflow that calls an API after a user has entered some text. In order to not reach certain API call limits, the callout should only be performed once the user presses Enter (one time - not after every key stroke). The webservice will then return a response to be displayed to the user as an Alfred list item. The user may press Enter on the displayed list item to open a certain URL that the API responded with.

     

    This is the concept I came up with (note: No workflow that I can export yet):
    1. [Keyword] User enters a keyword and then some text (e.g. 'mywf some text')
    2. User presses 'Enter'
    3. [Run Script] API is called
    4. [Run Script] API returns response, passed as input to Script Filter
    5. [Script Filter] Response is shown as list items in Alfred

    • Issue 1: Step 2 would close the Alfred launcher, I want to keep it open to wait for the response via 4. My assumption is, this would only possible using a Script Filter at 1? Unfortunately, this would hit the API call limits.
    • Issue 2: As Alfred is closed at 2, and reopened at 4, the "input" field of Alfred would be cleared of the user's input (as Run Script ended), and instead the output of the previous node would be shown (Run Script). However, as this output is a JSON string - to show the list items in Alfred -, this would now show as text in the input field (i.e. { "items" ... }).

    6. [Script Filter] User presses 'Enter' on selected list item
    7. [Script Filter] URL is opened in browser

     

    Due to Issue 1 & 2 this approach does not seem to work in theory. My questions are:
    1) Is there any way to only execute a Script Filter upon pressing 'Enter'? This would allow me to have a Script Filter only, instead of an additional Run Script filter before.
    2) How can I keep the Alfred launcher open due all of this?
    3) How can I prevent the Alfred launcher input field from being filled with the output of the previous node?

  8. Thanks @deanishe, that works!

    It seems to be an issue with Alfy then, as it prevents me from witing to STDERR instead of STDOUT.

     

    The following works:

    console.error('TEST1') // Writes to STDERR, not shown in notification 
    console.error('TEST2') // Writes to STDERR, not shown in notification 
    console.log('TEST3') // Writes to STDOUT, shown in notification 

    But once I import Alfy it no longer works:

    const alfy = require("alfy");
    console.error('TEST1') // Writes to STDOUT as JSON
    console.error('TEST2') // Writes to STDOUT as JSON
    console.log('TEST3') // Writes to STDOUT as plain text

    I will need to check the Alfy doc once again.

  9. Hi @deanishe, thank you! 

     

    Sure, I've uploaded the workflow here: https://gofile.io/?c=QkslSS

    Regarding Alfy, the example is similar even without, just using NodeJS' standard console.log():

    console.log('TEST1')
    console.log('TEST2') 

    With this code, while indeed no JSON structure will be displayed (apparently alfy.output() is only for JSON structures, unlike alfy.log()), the notification will still display all console.log() statements at once: TEST1 TEST2. How can I only pass TEST2, i.e. the last log element to the notification?

  10. Hello
     
    I seem to have trouble understanding how outputs from scripts are digested by follow-up nodes.
     
    I have the following example:
    • A NodeJS script (index.js) that is executed when entering a keyword (cut <text>)
    • The script uses the Alfy package (same issue without the package)
    • The script uses alfy.output('TEST') to write to STDOUT (same as console.error())
    • The script then passes its output on to a Post Nofification node which shows {query}
    • The notification is displayed as:
    {
    	"items": [
    		{
    			"title": "ABC\n",
    			"subtitle": "Press ⌘L to see the full error and ⌘C to copy it.",
    			"valid": false,
    			"text": {
    				"copy": "```\nABC\n```\n\n-\nScript Output - Example 1.0.1\nAlfred 4.0.8\ndarwin 18.7.0",
    				"largetype": "ABC"
    			},
    			"icon": {
    				"path": "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns"
    			}
    		}
    	]
    }
    {
    	"items": "TEST"
    }

     

    This can also be seen in debug, as the whole output, i.e. all calls to STDOUT that happened within the script, are concatenated into a list of items. Then this list, formatted as JSON, is passed to the notification.

    My expectation was, that a) only the last alfy.output() (or console.error()) would be passed to the Notification node and b) the Notification node would display the text as is (e.g. 'TEST'), and not as a JSON string

    Obviously my understanding is incorrect. How can I simply display the 'TEST' output from the script in the notification?

     

    Apparently I cannot attach the complete workflow, so please find below screenshots:

    image.png.76f019eff372ec98e91213d72c04bf21.png

     

    Keyword

    image.png.8a610ad26a57961eeb54de40cf3ebd7a.png

    Run Script

    image.png.a287ff292bdddde55aa370dee8e0c40a.png

    Post Notification

    image.png.b44c884e2923ac5e36c9a4439a6c7465.png

    index.js

    const alfy = require("alfy");
    
    alfy.log('ABC') // Is also part of the JSON string - why? I only need the last alfy.output() / log()
    alfy.output('TEST') // Will be shown as { "items" ... } in notification

     

×
×
  • Create New...