1 | |
2 | type Personio = { |
3 | clientId: string; |
4 | clientSecret: string; |
5 | }; |
6 | |
7 | * Create a new Person and Employment. |
8 | * - This endpoint enables the creation of a Person resource and an associated Employment resource. |
9 | - The endpoint requires the personio:persons:write scope. |
10 |
|
11 | */ |
12 | export async function main( |
13 | auth: Personio, |
14 | body: { |
15 | email?: string; |
16 | first_name?: string; |
17 | preferred_name?: string; |
18 | last_name?: string; |
19 | gender?: "MALE" | "FEMALE" | "DIVERSE" | "UNKNOWN" | "UNDEFINED"; |
20 | language_code?: "en" | "de" | "es" | "fr" | "nl" | "it" | "sv" | "fi"; |
21 | custom_attributes?: { id?: string; value?: string | string[] }[]; |
22 | } & { |
23 | employments?: { |
24 | supervisor?: { id: string }; |
25 | office?: { id: string }; |
26 | org_units?: { type: string; id: string }[]; |
27 | subcompany?: { id: string }; |
28 | legal_entity?: { id: string }; |
29 | position?: { title: string }; |
30 | status?: "ACTIVE" | "INACTIVE" | "ONBOARDING" | "LEAVE"; |
31 | employment_start_date?: string; |
32 | type?: "INTERNAL" | "EXTERNAL"; |
33 | contract_end_date?: string; |
34 | probation_end_date?: string; |
35 | probation_period_length?: number; |
36 | weekly_working_hours?: number; |
37 | full_time_weekly_working_hours?: number; |
38 | cost_centers?: { id: string; weight: number }[]; |
39 | }[]; |
40 | } & {}, |
41 | ) { |
42 | const url = new URL(`https://api.personio.de/v2/persons`); |
43 |
|
44 | const response = await fetch(url, { |
45 | method: "POST", |
46 | headers: { |
47 | "Content-Type": "application/json", |
48 | Authorization: "Bearer " + await getOAuthToken(auth, "https://api.personio.de/oauth2/token"), |
49 | }, |
50 | body: JSON.stringify(body), |
51 | }); |
52 | if (!response.ok) { |
53 | const text = await response.text(); |
54 | throw new Error(`${response.status} ${text}`); |
55 | } |
56 | return await response.json(); |
57 | } |
58 |
|
59 | async function getOAuthToken(auth: Personio, tokenUrl: string): Promise<string> { |
60 | const params = new URLSearchParams({ |
61 | grant_type: 'client_credentials', |
62 | client_id: auth.clientId, |
63 | client_secret: auth.clientSecret, |
64 | }); |
65 | |
66 | const response = await fetch(tokenUrl, { |
67 | method: 'POST', |
68 | headers: { |
69 | 'Authorization': 'Basic ' + btoa(`${auth.clientId}:${auth.clientSecret}`), |
70 | 'Content-Type': 'application/x-www-form-urlencoded', |
71 | }, |
72 | body: params.toString(), |
73 | }); |
74 |
|
75 | if (!response.ok) { |
76 | const text = await response.text(); |
77 | throw new Error(`OAuth token request failed: ${response.status} ${text}`); |
78 | } |
79 |
|
80 | const data = await response.json(); |
81 | return data.access_token; |
82 | } |
83 |
|