remarkable-cloud-js
v0.16.0
Published
reMarkable Cloud API for NodeJs
Maintainers
Readme
reMarkable-cloud-js
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
Features
- [X] Authentication
- [X] device registration
- [X] user connection
- [X] data retrieval/push
- [X] files metadata retrieval
- [X] folders tree retrieval
- [X] path exists
- [X] unlink path
- [X] create directory
- [X] move path
- [X] rename path
- [X] read/write zip
- [X] copy path
- [X] read/write pdf
- [X] read/write ePub
- [X] write from url
- [X] cloud live notifications
- [X] main data feed (all updates)
- [X] subscription data feed (specific file/folder updates)
Main usage
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)
Specifications
Device types
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
ZIP MAP data representation
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, abufferor 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 >')
}
Document 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 types
- 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
Document representation
(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 >'
}Standard reMarkable Document representation
The "un-extended document representation" lacks the _path component
Notification event types
- 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
Notification event data representation
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 */
}
Exceptions
path_not_foundoccurs if a required path cannot be foundupdate_erroroccurs if an error is thrown while updating a documentupload_request_erroroccurs if an error is thrown while uploading a documentdelete_erroroccurs if an error is thrown while deleting a documentpath_already_exists_erroroccurs if trying to create a path already existing
API
Basic data manipulation
exists (path)
- arguments
paththe path to check
- output Boolean value
trueorfalse
unlink (path)
- arguments
paththe path to trash
- output Boolean value
trueorfalse
move (from_path, to_parent)
rename (path, new_name)
File content
write_zip (path, zip_map, type)
- arguments
paththe document's path for data writing (can be existing or not)zip_mapthe ZIP MAP datatypethe document type
- output Document
read_zip (path)
mkdir (path)
copy (from_path, to_path)
- arguments
- output The copied (Document)
Specific file content
write_pdf (path, pdf_path, metadata)
- arguments
pathnewly added document's pathpdf_paththe local PDF file pathmetadata(optional,default = {}) metadata properties to add to the default PDF file's metadata
- output Document
write_pdf_from_url (path, pdf_url, metadata)
- arguments
pathnewly added document's pathpdf_urlthe remote PDF file URLmetadata(optional,default = {}) metadata properties to add to the default PDF file's metadata
- output Document
read_pdf (path)
write_epub (path, epub_path, metadata)
- arguments
pathnewly added document's pathepub_paththe local ePub file pathmetadata(optional,default = {}) metadata properties to add to the default ePub file's metadata
- output Document
write_epub_from_url (path, epub_url, metadata)
- arguments
pathnewly added document's pathepub_urlthe remote ePub file URLmetadata(optional,default = {}) metadata properties to add to the default ePub file's metadata
- output Document
read_epub (path)
Notification API
subscribe_to_notifications (handler, matching_properties)
- arguments
handlercallback function on which to pass the event datamatching_propertiessubscription properties (event object propeties to filter the incoming events)
- output Boolean value
true
Augmented reMarkable API
docs_paths ()
- output Document array
get_final_path (path)
this method verifies that the path exists
get_ID (id)
- arguments
idthe existing document's UUID
- output Document
get_name (name)
- arguments
namethe existing document's name
- output Document
get_path_content (path)
corrupted_docs ()
- output Parent missing Document array
trashed_docs ()
- output Document array
upload_zip_data (name, parent_path, type, zip_map [, doc])
- arguments
- output Document
base reMarkable API
raw_docs ()
- output reMarkable Document array
get_doc (ID [,with_blob])
- arguments
IDdocument's UUIDwith_blob(optional,default = true) indicated if the document should come with it's blob dowloading links
- output reMarkable Document
upload_request ([doc])
- arguments
doc(optional,default = null) a pre-existing reMarkable Document
- output fetch json response container this (among others)
IDandBlobURLPut
update_status (doc, changed_doc_data)
- arguments
docbase reMarkable Document data containing at minimum theIDandVersion
- output the updating sent reMarkable Document
delete (doc)
- arguments
docdeleting reMarkable Document
- output Boolean value
trueorfalse
Limitations
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.
