Nobody Pays (for) Magazines

    remarkable-cloud-js

    0.16.0 • Public • Published

    reMarkable-cloud-js

    reMarkable Cloud API for NodeJS

    Inspired by

    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)
    • mobile
      • android (mobile-android)
      • ios (mobile-ios)
    • browser
      • chrome (browser-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
    • each value can be either a string, a buffer or a JSON 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_found occurs if a required path cannot be found
    • update_error occurs if an error is thrown while updating a document
    • upload_request_error occurs if an error is thrown while uploading a document
    • delete_error occurs if an error is thrown while deleting a document
    • path_already_exists_error occurs if trying to create a path already existing

    API

    Basic data manipulation

    exists (path)

    • arguments
      • path the path to check
    • output Boolean value true or false

    unlink (path)

    • arguments
      • path the path to trash
    • output Boolean value true or false

    move (from_path, to_parent)

    • arguments
      • from_path the moving document's path
      • to_parent the parent folder's path
    • output Document

    rename (path, new_name)

    • arguments
      • path the renaming document's path
      • new_name the document's new name
    • output Document

    File content

    write_zip (path, zip_map, type)

    read_zip (path)

    • arguments
      • path the document's path to read
    • output ZIP MAP data

    mkdir (path)

    • arguments
      • path the new folder's path
    • output Folder (Document)

    copy (from_path, to_path)

    • arguments
      • from_path the copying document's path
      • to_path the new copyed document's path
    • output The copied (Document)

    Specific file content

    write_pdf (path, pdf_path, metadata)

    • arguments
      • path newly added document's path
      • pdf_path the local PDF file path
      • metadata (optional, default = {}) metadata properties to add to the default PDF file's metadata
    • output Document

    write_pdf_from_url (path, pdf_url, metadata)

    • arguments
      • path newly added document's path
      • pdf_url the remote PDF file URL
      • metadata (optional, default = {}) metadata properties to add to the default PDF file's metadata
    • output Document

    read_pdf (path)

    • arguments
      • path the existing PDF document's path
    • output PDF Buffer file data

    write_epub (path, epub_path, metadata)

    • arguments
      • path newly added document's path
      • epub_path the local ePub file path
      • metadata (optional, default = {}) metadata properties to add to the default ePub file's metadata
    • output Document

    write_epub_from_url (path, epub_url, metadata)

    • arguments
      • path newly added document's path
      • epub_url the remote ePub file URL
      • metadata (optional, default = {}) metadata properties to add to the default ePub file's metadata
    • output Document

    read_epub (path)

    • arguments
      • path the existing ePub document's path
    • output ePub Buffer file data

    Notification API

    subscribe_to_notifications (handler, matching_properties)

    • arguments
      • handler callback function on which to pass the event data
      • matching_properties subscription properties (event object propeties to filter the incoming events)
    • output Boolean value true

    Augmented reMarkable API

    docs_paths ()

    get_final_path (path)

    this method verifies that the path exists

    get_ID (id)

    • arguments
      • id the existing document's UUID
    • output Document

    get_name (name)

    • arguments
      • name the existing document's name
    • output Document

    get_path_content (path)

    • arguments
      • path existing folder's path
    • output Document array

    corrupted_docs ()

    trashed_docs ()

    upload_zip_data (name, parent_path, type, zip_map [, doc])

    • arguments
      • name the "new or not" document's name
      • parent_path the "new or not" document's parent's path
      • type the "new or not" document's type
      • zip_map the ZIP MAP data to upload
      • doc (optional, default = null) a pre-existing Document
    • output Document

    base reMarkable API

    raw_docs ()

    get_doc (ID [,with_blob])

    • arguments
      • ID document's UUID
      • with_blob (optional, default = true) indicated if the document should come with it's blob dowloading links
    • output reMarkable Document

    upload_request ([doc])

    • arguments
    • output fetch json response container this (among others) ID and BlobURLPut

    update_status (doc, changed_doc_data)

    delete (doc)

    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.

    Install

    npm i remarkable-cloud-js

    DownloadsWeekly Downloads

    1

    Version

    0.16.0

    License

    MIT

    Unpacked Size

    36.4 kB

    Total Files

    6

    Last publish

    Collaborators

    • avatar