Skip to content

Instantly share code, notes, and snippets.

@TfTHacker
Last active October 14, 2023 21:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TfTHacker/fc076269d5ad93c691b1b5409537e475 to your computer and use it in GitHub Desktop.
Save TfTHacker/fc076269d5ad93c691b1b5409537e475 to your computer and use it in GitHub Desktop.
Scriptable - Readwise random highlights
// Widget for iOS using the Scriptable app
// Uses Readwise API for pulling back random highlights.
// This duplicates the Readwise widget, so there is no additional value
// I did this as a learning exercize.
let accessToken = args.widgetParameter ? args.widgetParameter : "Your token here if you are testing, otherwise add it in the widget"
let headers = { "Authorization": "Token " + accessToken };
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
const getRandomHighlight = async ()=> {
let req = new Request("https://readwise.io/api/v2/highlights/?page_size=1000");
req.headers = headers;
const response = await req.loadJSON();
if(!response.results) return null; // failed, probably authentication issue with access token
const randomIndex = getRandomInt(response.results.length);
return response.results[randomIndex];
}
const getBookInfoById = async (bookID)=> {
let req = new Request(`https://readwise.io/api/v2/books/${bookID}`);
req.headers = headers;
return await req.loadJSON();
}
const highlight = await getRandomHighlight();
if(highlight===null) {
let widget = new ListWidget()
widget.url = "https://readwise.io/access_token";
widget.addText("The widget cannot authenticate with Readwise, please confirm that your access token in the parameter field of this widget is correct. Click me to get your access token from the Readwise website.");
Script.setWidget(widget);
return;
}
const bookInfo = await getBookInfoById( highlight.book_id );
let widget = new ListWidget()
widget.url = `https://readwise.io/open/${highlight.id}`;
widget.setPadding(11, 12, 11, 12);
let stack = widget.addStack();
stack.topAlignContent();
let imageStack = stack.addStack();
imageStack.layoutVertically();
imageStack.topAlignContent();
if(bookInfo.cover_image_url != null) {
let imgReq = new Request(bookInfo.cover_image_url)
let img = await imgReq.loadImage();
let imageWidget = imageStack.addImage(img);
imageWidget.imageSize = new Size(80,80);
imageWidget.cornerRadius = 3;
}
let spacer = stack.addSpacer();
spacer.length=10;
let textStack = stack.addStack();
textStack.setPadding(0,0,0,0);
textStack.layoutVertically();
let textWidget = textStack.addText(highlight.text.replaceAll("\n\n","\n"));
textWidget.minimumScaleFactor = .7;
textWidget.font = new Font("Futura New", 17);
let bio = textStack.addText("- " + bookInfo.author + " - " + bookInfo.title);
bio.lineLimit = 2;
bio.font = new Font("Arial",12);
bio.minimumScaleFactor = .8;
bio.textOpacity = 0.5;
Script.setWidget(widget);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment