Custom jql functions

how can we create a custom jql function where we can take two arguments? i have updated the arguments fields in my manifest as follows -

key: commentedByUser-function
      name: "commentedByUser"
      arguments:
        - name: jqlQuery
          required: true
          type: string
        - name: userId
          required: true
          type: string
      types:
        - issue
      operators:
        - in
        - not in
      function: commentedByUser

and my function is

export const commentedByUser = async (args) => {
  const { clause } = args; // Extracting the input arguments from the clause
  const jqlQuery = clause.arguments[0]; // First argument is the JQL query
  const userId = clause.arguments[1]; // Second argument is the Account ID
   console.log(jqlQuery, "my query")
   console.log(userId, "id of user")
   console.log(clause, "clause")
  // Validate inputs
  if (!jqlQuery || !userId) {
    return { jql: 'id in (-1)' }; // Return empty if no valid arguments
  }

i am also not able to see the console logs for debugging

Hi @Ankitkharola,

There are a couple of things to note here:

  1. The type inside the arguments property is not defined in the docs. You can remove that.
  2. Regarding not being able to see the logs, how are you calling your JQL function? Based on your manifest, it can be called via issue in commentedByUser("<jqlQuery>", "userId" ).

Kindly try it out and let us know how it goes.

Cheers,
Ian

hi @ianRagudo thank you for the help i am trying to validate the queries that user is entering in the jira jql search bar for eg-

issue IN commentedByUser("project=forge-learning AND status=Done", "712020:22b5ce4f-196a-4316-9f35-a5a48788e32a")

NOTE" if i am using single query project=forge-learning it works for me bur when i am combinig two of them i cant validate the queries i am using

const validateJQLQueries = async (queries) => {
  // Assuming `queries` is a single string and not an array of multiple queries
  const bodyData = JSON.stringify({
    queries: [queries]
  });

  
    const response = await api.asUser().requestJira(route`/rest/api/3/jql/parse?validation=true`, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: bodyData
    });
  console.log(response, "res")
    const result = await response.json();
    console.log(result, "check my result");

    if (response.ok) {
      return { valid: true, results: result };
    } else {
      console.error('Validation failed:', result);
      return { valid: false, errors: result.errors || [] };
    }
  
};

this endpoint to parse the query also if i just write assignee=currentUser() it also wont work and yes if i add spaces betweeb each word and operator it wont work that is why i amnot using spaces n jql query

@Ankitkharola the reason you’re not seeing any debug logs might be because your JQL function is getting cached via precomputations. Try updating your subquery (white spaces will do).

Hi @Ankitkharola,

Running your code, it gives me an HTTP 400 response. Inspecting it further, the cause of the problem is this call:

// the query parameter "validator" only accepts the values 'strict', 'warn', and 'none' 

await api.asUser().requestJira(route`/rest/api/3/jql/parse?validation=true`, {...

Using your code and fixing the query parameter (validation) value, this is not the case for me. After fixing the HTTP 400 response, spaces should be fine.

Can you try fixing the REST API call and let us know how that goes?

Cheers,
Ian

@ianRagudo Thank you for your response i tried to fix the api here is the function const validateJQLQueries = async (queries) => {
const bodyData = JSON.stringify({
queries : queries
})
const validation = “strict”

const response = await api.asUser().requestJira(route`/rest/api/3/jql/parse?validation=${validation}`, {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: bodyData
});

console.log(response, “res”)
const result = await response.json();
console.log(result, “check my result”);

if (response.ok) {
  return { valid: true, results: result };
} else {
  console.error('Validation failed:', result);
  return { valid: false, errors: result.errors || [] };
}

};
when using this JQL project=forge-learning i get the results but if i add space between keywords and operator i get to see error in console 10:48:20.213 70fa9a94-142b-40e6-b2fe-16a87a279be4 project = forge-learning my query
INFO 10:48:20.214 70fa9a94-142b-40e6-b2fe-16a87a279be4 712020:22b5ce4f-196a-4316-9f35-a5a48788e32a id of user
INFO 10:48:21.044 70fa9a94-142b-40e6-b2fe-16a87a279be4 Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: ‘https://jira/rest/api/3/jql/parse?validation=strict’,
status: 400,
statusText: ‘Bad Request’,
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
} res
INFO 10:48:21.051 70fa9a94-142b-40e6-b2fe-16a87a279be4 {
errorMessages: [
‘Invalid request payload. Refer to the REST API documentation and try again.’
]
} check my result
ERROR 10:48:21.051 70fa9a94-142b-40e6-b2fe-16a87a279be4 Validation failed: {
errorMessages: [
‘Invalid request payload. Refer to the REST API documentation and try again.’
]
}
ERROR 10:48:21.052 70fa9a94-142b-40e6-b2fe-16a87a279be4 Invalid JQL query:

is my api still the issue? am i accepting the args array correctly this is how i am doing it const { clause } = args;
const jqlQuery = clause.arguments[0].trim();
const userId = clause.arguments[1];

console.log(jqlQuery, “my query”);
console.log(userId, “id of user”);

Hi @Ankitkharola,

I can’t find any glaring issues but it seems there’s something wrong with your payload.

I implemented this in a different way; it should be the same without the trim():

  const { clause } = args;
  const { operator } = clause;
  const [jqlQuery, userId] = clause.arguments;

Cheers,
Ian