Warning
This project is currently broken. Personio keeps changing their login process from time to time, and I don't have the energy to keep updating this code. So this code once knew how to authenticate and get a login token, but not anymore with Personio's most recent updates.
Accessing Personio's API requires API credentials which does not scope to the employee level, meaning you can only get official API access as an admin user, where you get access to the sensitive information of all the employees in your company.
Instead, this package uses a different API: the same API as your web browser. This is done by pretending to be a browser and logging in normally using email and password.
Thanks to the new EU ruling, time tracking is now even more mandatory than it was before. Some companies, like where I work, have first now started enforcing time tracking.
Initially this didn't bother me though, as I've been tracking my time for years on my own. But now we must start reporting our tracked time to our HR system: Personio.
So that sparked me to somehow access Personio's API, because I do NOT want to sit there and manually transfer the tracked time via that slow (albeit not the slowest) HR web interface.
There is a CLI available that exposes some of the features found in the Go library.
Currently, installing requires that you have Go 1.20 (or later) installed. Then you can run the following:
go install github.com/applejag/rootless-personio@latest
$ rootless-personio --help
Access Personio via your own employee credentials,
instead of obtaining admin/root API credentials.
Usage:
rootless-personio [command]
Available Commands:
attendance Group of commands for interacting with attendance
completion Generate the autocompletion script for the specified shell
config Prints the parsed config
help Help about any command
raw Send a raw HTTP request to the API
Flags:
--auth.email string Email used when logging in
--config string Config file (default is $HOME/.rootless-personio.yaml)
-h, --help Show this help text
--log.format log-format Sets the logging format (default pretty)
--log.level log-level Sets the logging level (default warn)
--no-login Skip logging in before the request
-o, --output out-format Sets the output format (default pretty)
-q, --quiet Disables logging (same as "--log.level disabled")
--url string Base URL used to access Personio
-v, --verbose count Shows verbose logging (-v=info, -vv=debug, -vvv=trace)
Use "rootless-personio [command] --help" for more information about a command.
You need to specify your attendance periods as a JSON stream in a JSON file, for example:
{
"start": "2023-01-18T08:00:00Z",
"end": "2023-01-18T12:00:00Z",
"comment": "Work before lunch",
"period_type": "work"
}
{
"start": "2023-01-18T12:00:00Z",
"end": "2023-01-18T13:00:00Z",
"comment": "Lunch break",
"period_type": "break"
}
{
"start": "2023-01-18T13:00:00Z",
"end": "2023-01-18T17:00:00Z",
"comment": "Work after lunch",
"period_type": "work"
}
Then let rootless-personio
update your attendance periods by running the
following command:
rootless-personio attendance set --file file-with-stream.json
By "JSON stream", I mean where the JSON objects are defined one after each other, instead of wrapping all objects in a big array.
If you have your attendance periods in an array, you can convert it into a JSON stream with the following
jq
command:jq '.[]' file-with-array.json > file-with-stream.json
This operation can be combined with other time-tracking tools, such as dinkur, as long as you figure out how to export your time tracking data, and reshape it to look like the above JSON:
dinkur ls -r all -o json \
| jq '.[] | .comment=.name | del(.id, .createdAt, .updatedAt, .name)' \
| rootless-personio attendance set -f -
Or something like this, if you're using timetrap:
timetrap display --format json \
| jq '.[] | .comment=.note | del(.id, .sheet, .note)' \
| rootless-personio attendance set -f -
The CLI is configured via YAML files.
See personio.yaml
for the default values.
Certmgmt looks for config files in multiple locations, where the latter overrides config fields from the former.
On Linux:
- Default values (see
personio.yaml
) /etc/personio/personio.yaml
~/.config/personio.yaml
~/.personio.yaml
.personio.yaml
(in current directory)
On Windows:
- Default values (see
personio.yaml
) %APPDATA%/personio.yaml
%USERPROFILE%/.personio.yaml
.personio.yaml
(in current directory)
On Mac:
- Default values (see
personio.yaml
) /etc/personio/personio.yaml
~/Library/Application Support/personio.yaml
~/.personio.yaml
.personio.yaml
(in current directory)
There's also a JSON Schema for the config file, which gives you warnings and completion support inside your IDE.
Make use of it via e.g:
-
YAML extension for VS Code.
-
coc-yaml plugin for coc.nvim, an extension framework for both Vim and NeoVim.
To make use of it, add the following comment to the beginning of your config file:
# yaml-language-server: $schema=https://github.com/applejag/rootless-personio/raw/main/personio.schema.json
This repository was created by @jorie1234 under the MIT license, but has been forked and is now maintained by Kalle Fagerberg (@applejag) under a new license.
The code in this project is licensed under GNU General Public License v3.0 or later (LICENSES/GPL-3.0-or-later.txt), and documentation is licensed under Creative Commons Attribution 4.0 International (LICENSES/CC-BY-4.0.txt).
Code in this repository is heavily inspired by:
-
the upstream work from @jorie1234: https://github.com/jorie1234/goPersonio
-
Eduardo Sánchez's (@Whipshout) Rust implementation: https://github.com/Whipshout/personio_tool