Request to get the list of all agents

I need help with a request to get the list of all agents. What am I doing wrong?
app.js

let client;
init();
async function init() {
  client = await app.initialized();
  client.events.on('app.activated', loadAgents);
}
async function loadAgents() {
  const params = await client.iparams.get();
  const response = await client.request.invoke("get", {
    url: `https://${params.domain}.freshdesk.com/api/v2/agents`,
    headers: {
      Authorization: "Basic " + btoa(params.api_key + ":X")
    }
  });
  const agents = JSON.parse(response.response);
  console.log(agents);
}

iparams.json

{
  "api_key": {
    "display_name": "api_key",
    "description": "Please enter your api_key",
    "type": "text",
    "required": true,
    "secure": true
  },
  "domain": {
    "display_name": "domain",
    "description": "Please enter your domain",
    "type": "text",
    "required": true
  }
}

manifest.json

{
  "platform-version": "3.0",
  "modules": {
    "common": {
      "location": {
        "full_page_app": {
          "url": "index.html",
          "icon": "styles/images/icon.svg"
        }
      },
      "requests": {}
    },
    "support_ticket": {}
  },
  "engines": {
    "node": "18.20.8",
    "fdk": "9.7.4"
  }
}```

The main problem is in your manifest.json - the requests object is empty. For Freshdesk API calls, you need to whitelist the domain you’re making requests to.

Add the Freshdesk API domain to the requests configuration:

"requests": {
  "freshdesk": {
    "scheme": "https",
    "host": "{{domain}}.freshdesk.com",
    "authorization": {
      "type": "basic",
      "username": "{{api_key}}",
      "password": "X"
    }
  }
}

Then update your app.js to use the named request:

const response = await client.request.invoke("freshdesk", {
  url: "/api/v2/agents"
});
let client;
init();

async function init() {
  client = await app.initialized();
  client.events.on('app.activated', loadAgents);
}

async function loadAgents() {
  try {
    const response = await client.request.invoke("freshdesk", {
      url: "/api/v2/agents"
    });
    
    const agents = JSON.parse(response.response);
    console.log('Agents:', agents);
  } catch (error) {
    console.error('Error loading agents:', error);
  }
}

{
  "api_key": {
    "display_name": "api_key",
    "description": "Please enter your api_key",
    "type": "text",
    "required": true,
    "secure": true
  },
  "domain": {
    "display_name": "domain",
    "description": "Please enter your domain",
    "type": "text",
    "required": true
  }
}
{
  "platform-version": "3.0",
  "modules": {
    "common": {
      "location": {
        "full_page_app": {
          "url": "index.html",
          "icon": "styles/images/icon.svg"
        }
      },
      "requests": {
        "freshdesk": {
          "scheme": "https",
          "host": "{{domain}}.freshdesk.com",
          "authorization": {
            "type": "basic",
            "username": "{{api_key}}",
            "password": "X"
          }
        }
      }
    },
    "support_ticket": {}
  },
  "engines": {
    "node": "18.20.8",
    "fdk": "9.7.4"
  }
}

Also, if you have more than 100 agents you will want to add pagination as well

let client;
init();

async function init() {
  client = await app.initialized();
  client.events.on('app.activated', loadAgents);
}

async function loadAgents() {
  try {
    let allAgents = [];
    let page = 1;
    const perPage = 100;
    let hasMorePages = true;

    while (hasMorePages) {
      const response = await client.request.invoke("freshdesk", {
        url: `/api/v2/agents?per_page=${perPage}&page=${page}`
      });
      
      const agents = JSON.parse(response.response);
      
      if (agents.length > 0) {
        allAgents = allAgents.concat(agents);
        page++;
      } else {
        hasMorePages = false;
      }
    }
    
    console.log('Total agents:', allAgents.length);
    console.log('Agents:', allAgents);
    return allAgents;
  } catch (error) {
    console.error('Error loading agents:', error);
  }
}

Thank you, this helped me move forward a lot. But in the terminal, when starting the app using the fdk run command, I had some errors. I fixed them, and now after some adjustments, I have the following code. I understand that the problem is with the getAgents function. The app starts, but I still have an error in the console.

“Requested function ‘getAgents’ not found or registered”, status: 404, errorSource: ‘APP’

manifest.json

{
  "platform-version": "3.0",
  "modules": {
    "common": {
      "location": {
        "full_page_app": {
          "url": "index.html",
          "icon": "styles/images/icon.svg"
        }
      },
      "requests": {
        "freshdesk_request": {}
      }
    },
    "support_ticket": {}
  },
  "engines": {
    "node": "18.20.8",
    "fdk": "9.7.4"
  },
  "app": {
    "tracking_id": "aixfa4rlutw791e3iubp"
  }
}

app.js

let client;

init();

async function init() {
  client = await app.initialized();
  client.events.on('app.activated', loadAgents);
}

async function loadAgents() {
  try {
    const response = await client.request.invoke("getAgents", {});
    
    const agents = JSON.parse(response.response);
    console.log('Agents:', agents);
  } catch (error) {
    console.error('Error loading agents:', error);
  }
}

request.json

{
    "freshdesk_request": {
        "schema": {
            "method": "GET",
            "host": "<%= iparam.domain %>.freshdesk.com",
            "path": "/api/v2/agents",
            "headers": {
                "Authorization": "Bearer <%= iparam.api_key %>",
                "Content-Type": "application/json"
            }
        }
    }
}

You are calling a serverless function but, you haven’t shown an exported getAgents function in server/server.js

So, you can either change to invoke the request template directly client.request.invokeTemplate(“freshdesk_request”, {}) or if you want to keep the current call make sure you export a function with the exact name from server.server.js


exports.getAgents = async function (args) {
  try {
    const resp = await $request.invokeTemplate("freshdesk_request", {});
    return resp;
  } catch (err) {
    throw {
      message: err?.message || "Failed to fetch agents",
      status: err?.status || 500
    };
  }
};

Thank you for your help! I’ve figured it out. Maybe it will be useful to someone.

App.js

let client;
init();
async function init() {
  client = await app.initialized();
  client.events.on('app.activated', listAgents);
}

async function listAgents() {
  try {
    const res = await client.request.invokeTemplate("listAgents", {
      context: {},
      query: {}
    });
    const agents = JSON.parse(res.response);
    console.log("Agents list:", agents);
  } catch (error) {
    console.error("Error fetching agents:", error);
  }
}

request.json

{
    "listAgents": {
        "schema": {
            "protocol": "https",
            "method": "GET",
            "host": "<%= iparam.domain %>.freshdesk.com",
            "path": "/api/v2/agents",
            "headers": {
                "Authorization": "Basic <%= encode(iparam.api_key) %>",
                "Content-Type": "application/json"
            }
        }
    }
}

manifest.json

{
  "platform-version": "3.0",
  "modules": {
    "common": {
      "location": {
        "full_page_app": {
          "url": "index.html",
          "icon": "styles/images/icon.svg"
        }
      },
      "requests": {
        "listAgents": {}
      }
    },
    "support_ticket": {}
  },
  "engines": {
    "node": "18.20.8",
    "fdk": "9.7.4"
  }
}

iparams.json

{
  "api_key": {
    "display_name": "api_key",
    "description": "Please enter your api_key",
    "type": "text",
    "required": true,
    "secure": true
  },
  "domain": {
    "display_name": "domain",
    "description": "Please enter your domain",
    "type": "text",
    "required": true
  }
}