reMarkable Cloud API for NodeJS
Inspired by
- Alexander Keil's unofficial reMarkable Cloud API documentation
- jmptable's ReMarkable Tablet Cloud API
- ogdentrod's reMarkable-typescript
- Authentication
- device registration
- user connection
- data retrieval/push
- files metadata retrieval
- folders tree retrieval
- path exists
- unlink path
- create directory
- move path
- rename path
- read/write zip
- copy path
- read/write pdf
- read/write ePub
- write from url
- cloud live notifications
- main data feed (all updates)
- subscription data feed (specific file/folder updates)
First time authentication
const RmCJS = require('remarkable-cloud-js')
let rm_api = new RmCJS()
let device_token = await rm_api.register_device('< one time code >', RmCJS.device_desc.desktop.linux)
// save the device_token to be reused later
await rm_api.refresh_token() // auto authentication once registration is done
Common connection
const RmCJS = require('remarkable-cloud-js')
// using the saved device token + refreshing the user token
let rm_api = new RmCJS('< device token >')
await rm_api.refresh_token()
Sample storage usage
const RmCJS = require('remarkable-cloud-js')
let rm_api = new RmCJS('< device token >')
await rm_api.refresh_token()
if(!(await rm_api.exists('/My projects/blueprints'))) {
await rm_api.mkdir('/My projects/blueprints')
}
let blueprints = await rm_api.get_path_content('/My projects/Articles')
for(let blueprint of blueprints) {
if(blueprint.VissibleName.includes('to delete')) {
await rm_api.delete(blueprint._path)
}
}
await rm.write_pdf('/My projects/Articles/a really cool pdf', './pdfs/article.pdf')
Sample notifications usage
const RmCJS = require('remarkable-cloud-js')
let rm_api = new RmCJS('< device token >')
await rm_api.refresh_token()
function notification_handler(event) {
console.log('update on', event.document.VissibleName)
}
// ---- event matcher making sure all recieved event come from the remarkable tablet
let notification_matcher = {
sourceDeviceDesc: 'remarkable'
}
await rm_api.subscribe_to_notifications(notification_handler, notification_matcher)
To use on registration
- desktop
- windows (
desktop-windows
) - macos (
desktop-macos
) - linux (
desktop-linux
)
- windows (
- mobile
- android (
mobile-android
) - ios (
mobile-ios
)
- android (
- browser
- chrome (
browser-chrome
)
- chrome (
found here
const RmCJS = require('remarkable-cloud-js')
RmCJS.device_desc
RmCJS.device_desc.desktop
RmCJS.device_desc.desktop.windows
RmCJS.device_desc.desktop.macos
RmCJS.device_desc.desktop.linux
RmCJS.device_desc.mobile
RmCJS.device_desc.mobile.android
RmCJS.device_desc.mobile.ios
RmCJS.device_desc.browser
RmCJS.device_desc.browser.chrome
In the reMarkable case, ZIP data representing file content often uses the document's ID as a path component. As it is (most of the time) impossible to know this ID in advance, we propose the following zip data representation to use in some APIs arguments:
- the ZIP MAP object is reprenseted by a flat JSON object.
- each property represents a path.
- a path containing the ID uses the
{ID}
string to indicate its position in the path
- a path containing the ID uses the
- each value can be either a
string
, abuffer
or aJSON object
ZIP MAP sample
const fs = require('fs')
let pdf_zip_map = {
'{ID}.content': {
extraMetadata: {},
fileType: file_type,
lastOpenedPage: 0,
lineHeight: -1,
margins: 180,
pageCount: 0,
textScale: 1,
transform: {}
},
'{ID}.pagedata': [],
'{ID}.pdf': fs.readFileSync('< pdf file path >')
}
The reMarkable document path are absolute and starts with the root folder /
- Sample folder:
/My project/blueprint
- Sample document:
/My project/blueprint/project one
Note that no extension are used in the reMarkable filesystem
- document type (
DocumentType
) represent a "file" (notebook, pdf, epub, etc.) - collection type (
CollectionType
) represent a "folder"
found here
const RmCJS = require('remarkable-cloud-js')
RmCJS.type
RmCJS.type.document
RmCJS.type.collection
(extended from the standard reMarkable representation)
{
ID: '< document UUID >',
Version: 1,
Message: '',
Success: true,
BlobURLGet: '',
BlobURLGetExpires: '0001-01-01T00:00:00Z',
ModifiedClient: '< last modification date string >',
Type: '< document type >',
VissibleName: '< document name >',
CurrentPage: 0,
Bookmarked: false,
Parent: '< document parent UUID >',
_path: '< detected absolute path >'
}
The "un-extended document representation" lacks the _path
component
- document added (
DocAdded
) when a document is added, updated (its content) or moved (including to the trash) - document deleted (
DocDeleted
) when a document is removed from the cloud (not only trashed)
found here
const RmCJS = require('remarkable-cloud-js')
RmCJS.notification.event
RmCJS.notification.event.document_added
RmCJS.notification.event.document_deleted
found here
{
auth0UserID: '< unknown data >',
bookmarked: false,
event: '< event types >',
id: '< updating Document UUID >',
parent: '< updating Document parent UUID >',
sourceDeviceDesc: '< source device description >',
sourceDeviceID: '< source device id >',
type: '< updating Document type >',
version: '1',
vissibleName: '< updating Document name >',
publish_time: '< event occuring time string >',
document: /* Document representation if event = DocAdded */
}
path_not_found
occurs if a required path cannot be foundupdate_error
occurs if an error is thrown while updating a documentupload_request_error
occurs if an error is thrown while uploading a documentdelete_error
occurs if an error is thrown while deleting a documentpath_already_exists_error
occurs if trying to create a path already existing
- arguments
path
the path to check
- output Boolean value
true
orfalse
- arguments
path
the path to trash
- output Boolean value
true
orfalse
- arguments
path
the document's path for data writing (can be existing or not)zip_map
the ZIP MAP datatype
the document type
- output Document
- arguments
- output The copied (Document)
- arguments
path
newly added document's pathpdf_path
the local PDF file pathmetadata
(optional,default = {}
) metadata properties to add to the default PDF file's metadata
- output Document
- arguments
path
newly added document's pathpdf_url
the remote PDF file URLmetadata
(optional,default = {}
) metadata properties to add to the default PDF file's metadata
- output Document
- arguments
path
newly added document's pathepub_path
the local ePub file pathmetadata
(optional,default = {}
) metadata properties to add to the default ePub file's metadata
- output Document
- arguments
path
newly added document's pathepub_url
the remote ePub file URLmetadata
(optional,default = {}
) metadata properties to add to the default ePub file's metadata
- output Document
- arguments
handler
callback function on which to pass the event datamatching_properties
subscription properties (event object propeties to filter the incoming events)
- output Boolean value
true
- output Document array
this method verifies that the path exists
- arguments
id
the existing document's UUID
- output Document
- arguments
name
the existing document's name
- output Document
- output Parent missing Document array
- output Document array
- arguments
- output Document
- output reMarkable Document array
- arguments
ID
document's UUIDwith_blob
(optional,default = true
) indicated if the document should come with it's blob dowloading links
- output reMarkable Document
- arguments
doc
(optional,default = null
) a pre-existing reMarkable Document
- output fetch json response container this (among others)
ID
andBlobURLPut
- arguments
doc
base reMarkable Document data containing at minimum theID
andVersion
- output the updating sent reMarkable Document
- arguments
doc
deleting reMarkable Document
- output Boolean value
true
orfalse
Cloud functionalities are not 100% reliable on the tablet and the application, it is thus recommended to use the cloud api with care and if possible with the tablet turned on and connected.