Trilium provides a mechanism for scripts to open a public REST endpoint. This opens a way for various integrations with other services - a simple example would be creating new note from Slack by issuing a slash command (e.g. /trilium buy milk
).
Let’s take a look at an example. The goal is to provide a REST endpoint to which we can send title and content and Trilium will create a note.
We’ll start with creating a JavaScript backend code note containing:
const {req, res} = api;
const {secret, title, content} = req.body;
if (req.method == 'POST' && secret === 'secret-password') {
// notes must be saved somewhere in the tree hierarchy specified by a parent note.
// This is defined by a relation from this code note to the "target" parent note
// alternetively you can just use constant noteId for simplicity (get that from "Note Info" dialog of the desired parent note)
const targetParentNoteId = api.currentNote.getRelationValue('targetNote');
const {note} = api.createTextNote(targetParentNoteId, title, content);
const notePojo = note.getPojo();
res.status(201).json(notePojo);
}
else {
res.send(400);
}
This script note has also following two attributes:
#customRequestHandler
with value create-note
~targetNote
pointing to a note where new notes should be savedLet’s test this by using an HTTP client to send a request:
POST http://my.trilium.org/custom/create-note
Content-Type: application/json
{
"secret": "secret-password",
"title": "hello",
"content": "world"
}+++++++++++++++++++++++++++++++++++++++++++++++
Notice the /custom
part in the request path - Trilium considers any request with this prefix as “custom” and tries to find a matching handler by looking at all notes which have customRequestHandler
label. Value of this label then contains a regular expression which will match the request path (in our case trivial regex “create-note”).
Trilium will then find our code note created above and execute it. api.req
, api.res
are set to request and response objects from which we can get details of the request and also respond.
In the code note we check the request method and then use trivial authentication - keep in mind that these endpoints are by default totally unauthenticated, and you need to take care of this yourself.
Once we pass these checks we will just create the desired note using Script API.
Another common use case is that you want to just expose a file note - in such case you create label customResourceProvider
(value is again path regex).
Note: The file that is supposed to be exposed needs to have a label #customResourceProvider="fonts/myFont.woff
For example, your file is in custom/fonts, you can call it via custom/fonts/myFont.woff
.
api.req
and api.res
are Express.js objects - you can always look into its documentation for details.
REST request paths often contain parameters in the URL, e.g.:
http://my.trilium.org/custom/notes/123
The last part is dynamic so the matching of the URL must also be dynamic - for this reason the matching is done with regular expressions. Following customRequestHandler
value would match it:
notes/([0-9]+)
Additionally, this also defines a matching group with the use of parenthesis which then makes it easier to extract the value. The matched groups are available in api.pathParams
:
const noteId = api.pathParams[0];
Often you also need query params (as in e.g. http://my.trilium.org/custom/notes?noteId=123
), you can get those with standard express req.query.noteId
.