Skip to content

Commit 77e545d

Browse files
caleblehman-robosourcecoderabbitai[bot]e11man
authored
Breezy HR - Get Candidate (#20476)
* initial breezy code * fix async options * remove unnecessary auth check * Update components/breezy_hr/actions/get-candidate/get-candidate.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: e11man <115963151+e11man@users.noreply.github.com>
1 parent 628008e commit 77e545d

3 files changed

Lines changed: 247 additions & 5 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import breezyHr from "../../breezy_hr.app.mjs";
2+
3+
export default {
4+
key: "breezy_hr-get-candidate",
5+
name: "Get Candidate",
6+
description:
7+
"Retrieve a candidate by ID for a given position. [See the documentation](https://developer.breezy.hr/reference/company-position-candidate)",
8+
version: "0.0.1",
9+
type: "action",
10+
annotations: {
11+
destructiveHint: false,
12+
openWorldHint: true,
13+
readOnlyHint: true,
14+
},
15+
props: {
16+
breezyHr,
17+
companyId: {
18+
propDefinition: [
19+
breezyHr,
20+
"companyId",
21+
],
22+
},
23+
positionId: {
24+
propDefinition: [
25+
breezyHr,
26+
"positionId",
27+
(c) => ({
28+
companyId: c.companyId,
29+
}),
30+
],
31+
},
32+
candidateId: {
33+
propDefinition: [
34+
breezyHr,
35+
"candidateId",
36+
(c) => ({
37+
companyId: c.companyId,
38+
positionId: c.positionId,
39+
}),
40+
],
41+
},
42+
},
43+
async run({ $ }) {
44+
const data = await this.breezyHr.getCandidate({
45+
$,
46+
companyId: this.companyId,
47+
positionId: this.positionId,
48+
candidateId: this.candidateId,
49+
});
50+
$.export("$summary", "Candidate retrieved successfully");
51+
return data;
52+
},
53+
};
Lines changed: 193 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,200 @@
1+
import { axios } from "@pipedream/platform";
2+
3+
const BASE_URL = "https://api.breezy.hr/v3";
4+
15
export default {
26
type: "app",
37
app: "breezy_hr",
4-
propDefinitions: {},
8+
propDefinitions: {
9+
companyId: {
10+
type: "string",
11+
label: "Company",
12+
description: "The Breezy HR company",
13+
async options() {
14+
const rows = await this.listCompanies();
15+
return rows
16+
.map((c) => {
17+
const value = this._entityId(c);
18+
const label = c?.name || value || "Company";
19+
return {
20+
label,
21+
value,
22+
};
23+
})
24+
.filter((o) => o.value);
25+
},
26+
},
27+
positionId: {
28+
type: "string",
29+
label: "Position",
30+
description: "The position that contains the candidate. (This will only show published positions)",
31+
async options({ companyId }) {
32+
if (!companyId) {
33+
return [];
34+
}
35+
const rows = await this.listPositions({
36+
companyId,
37+
});
38+
return rows
39+
.map((p) => {
40+
const value = this._entityId(p);
41+
const label = p?.name || value || "Position";
42+
return {
43+
label,
44+
value,
45+
};
46+
})
47+
.filter((o) => o.value);
48+
},
49+
},
50+
candidateId: {
51+
type: "string",
52+
label: "Candidate",
53+
description: "The candidate to retrieve",
54+
async options({
55+
companyId, positionId,
56+
}) {
57+
if (!companyId || !positionId) {
58+
return [];
59+
}
60+
const rows = await this.listPositionCandidates({
61+
companyId,
62+
positionId,
63+
});
64+
return rows
65+
.map((c) => {
66+
const value = this._entityId(c);
67+
const parts = [
68+
c?.first_name,
69+
c?.last_name,
70+
].filter(Boolean);
71+
const fullName = parts.join(" ");
72+
const label =
73+
c?.name || fullName || c?.email_address || value || "Candidate";
74+
return {
75+
label,
76+
value,
77+
};
78+
})
79+
.filter((o) => o.value);
80+
},
81+
},
82+
},
583
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
84+
_entityId(obj) {
85+
return obj?._id || obj?.id;
86+
},
87+
88+
/**
89+
* Breezy list endpoints return a JSON array; normalize if wrapped.
90+
* @param {unknown} result
91+
* @returns {object[]}
92+
*/
93+
_normalizeArray(result) {
94+
if (Array.isArray(result)) {
95+
return result;
96+
}
97+
if (Array.isArray(result?.data)) {
98+
return result.data;
99+
}
100+
return [];
101+
},
102+
103+
_accessToken() {
104+
const auth = this.$auth;
105+
const token = auth.oauth_access_token;
106+
107+
return typeof token === "string"
108+
? token
109+
: String(token);
110+
},
111+
112+
_headers() {
113+
return {
114+
Accept: "application/json",
115+
Authorization: this._accessToken(),
116+
};
117+
},
118+
119+
async _makeRequest({
120+
$ = this, path, ...opts
121+
}) {
122+
return axios($, {
123+
url: `${BASE_URL}${path}`,
124+
headers: this._headers(),
125+
...opts,
126+
});
127+
},
128+
129+
async listCompanies(opts = {}) {
130+
const result = await this._makeRequest({
131+
method: "get",
132+
path: "/companies",
133+
...opts,
134+
});
135+
return this._normalizeArray(result);
136+
},
137+
138+
/**
139+
* List positions for a company. See
140+
* https://developer.breezy.hr/reference/company-positions
141+
* @param {object} opts
142+
* @param {string} opts.companyId
143+
* @param {string} [opts.state] - `published` (default when omitted), or a
144+
* specific state
145+
*/
146+
async listPositions({
147+
companyId,
148+
state,
149+
...opts
150+
}) {
151+
const mergedParams = {
152+
...(opts.params || {}),
153+
};
154+
mergedParams.state =
155+
state === undefined || state === null || state === ""
156+
? "published"
157+
: state;
158+
const result = await this._makeRequest({
159+
method: "get",
160+
path: `/company/${encodeURIComponent(companyId)}/positions`,
161+
...opts,
162+
params: mergedParams,
163+
});
164+
return this._normalizeArray(result);
165+
},
166+
167+
async listPositionCandidates({
168+
companyId, positionId, ...opts
169+
}) {
170+
const result = await this._makeRequest({
171+
method: "get",
172+
path:
173+
`/company/${encodeURIComponent(companyId)}/position/${encodeURIComponent(positionId)}/candidates`,
174+
...opts,
175+
});
176+
return this._normalizeArray(result);
177+
},
178+
179+
/**
180+
* Retrieve a candidate by ID for a position
181+
* @param {object} opts
182+
* @param {object} opts.$ - Pipedream execution context
183+
* @param {string} opts.companyId - Breezy company ID
184+
* @param {string} opts.positionId - Position ID
185+
* @param {string} opts.candidateId - Candidate ID
186+
* @returns {Promise<object>} Candidate resource from the API
187+
*/
188+
async getCandidate({
189+
$, companyId, positionId, candidateId,
190+
}) {
191+
const res = await this._makeRequest({
192+
$,
193+
method: "get",
194+
path:
195+
`/company/${encodeURIComponent(companyId)}/position/${encodeURIComponent(positionId)}/candidate/${encodeURIComponent(candidateId)}`,
196+
});
197+
return res?.data ?? res;
9198
},
10199
},
11200
};

components/breezy_hr/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/breezy_hr",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"description": "Pipedream breezy_hr Components",
55
"main": "breezy_hr.app.mjs",
66
"keywords": [

0 commit comments

Comments
 (0)