I tried to build my own widget but i couldn’t get it to work.
Is here anybody who worked with Scriptable and could help me displaying a card directly on my homescreen?
I tried to build my own widget but i couldn’t get it to work.
Is here anybody who worked with Scriptable and could help me displaying a card directly on my homescreen?
I quickly made a little script to display your first “pinned” card on Supernotes as a widget with Scriptable, it looks like this:
And here’s the script:
const API_KEY = args.widgetParameter
const cardCollection = await loadPinnedCards()
const cards = Object.values(cardCollection)
const widget = await createCardWidget(cards[0])
Script.setWidget(widget)
Script.complete()
async function createCardWidget(card) {
const date = new Date(Date.parse(card.data.modified_when))
const dateFormatter = new DateFormatter()
dateFormatter.useMediumDateStyle()
dateFormatter.useShortTimeStyle()
const strDate = dateFormatter.string(date)
const gradient = new LinearGradient()
gradient.locations = [0, 1]
gradient.colors = [
new Color("#ff607e"),
new Color("#ff6682")
]
const widget = new ListWidget()
widget.backgroundColor = new Color("#ff6682")
widget.backgroundGradient = gradient
// name
const nameElement = widget.addText(card.data.name)
nameElement.font = Font.boldSystemFont(16)
nameElement.textColor = Color.white()
nameElement.minimumScaleFactor = 0.75
widget.addSpacer(6)
// content
contentElement = widget.addText(card.data.markup)
contentElement.font = Font.mediumSystemFont(12)
contentElement.textColor = Color.white()
widget.addSpacer(6)
// date modified
const footerStack = widget.addStack()
const dateElement = footerStack.addText(strDate)
dateElement.font = Font.mediumSystemFont(12)
dateElement.textColor = Color.white()
dateElement.textOpacity = 0.8
// open the card directly in Supernotes app when clicking
widget.url = createCardUrl(card.data.id)
return widget
}
async function loadPinnedCards() {
const req = new Request("https://api.supernotes.app/v1/user/pins")
req.method = "get"
req.headers = {"Content-Type": "application/json", "Api-Key": API_KEY};
const jsonResponse = await req.loadJSON();
return jsonResponse;
}
function createCardUrl(cardId) {
return `supernotes://?cardId=${cardId}`
}
And finally the config setting on the home screen, where the Parameter is a Supernotes API key:
Hope that helps!
Wow! Thank you so much - I will play around with this code and see what I can get.
Could you add an example for the Homescreen widget? I am not sure what the base code should be and where to put those information which should be displayed …
@tobias thanks for sharing that - I didn’t realize what that was for when I saw it in the dev docs.
@isaiur it looks like it’s a widget for displaying pinned notes. Which is really cool.
I tried it, but got this error:
Error on line 9:45: TypeError: undefined is not an object (evaluating ‘card.data.modified_when’)
Also wasn’t super clear where the API key goes - I put it here within quotes but it didn’t help with that error either way:
req.headers = { “Content-Type”: “application/json”, “Api-Key”: API_KEY };
I found where the API has to go. When you add a Scriptable Widget you have to long press on it. Then a little context menu comes up where you can choose which Script you want to choose. The API-Key goes next to parameter … that’s why there is a const API_KEY = args.widgetParameter;
I’m getting this error when replacing API_KEY:
Error on line 45:73: ReferenceError: Can’t find variable: API_KEY
What should I do?
You need to replace API_KEY
with your own API key, which you can get from the API & Integrations menu within the Supernotes app.
As @isaiur mentioned (and as is done in the example), if you don’t want to store your API Key directly in the script, you can store it as a parameter on the Scriptable widget, which you do from the widget configuration page.
After adding the widget you have to hold down on it to configure.
Then you see this:
The API Key goes next to “Parameter”
Ok it worked with my API pasted into “Parameter” of the Scriptable widget, thank you!
Glad to hear everyone has got this up and running! I’ve moved this to a previous Scriptable thread so everything is in one place. We will also update the Developer Docs so that the Scriptable part is more clear. And if you have any further questions, let us know and we will be happy to help
Thanks for that. I totally forgot that this thread exists …
I played around with the code now and it’s much clearer now where to put what. So I managed to display a specific card based on the ID for example.
Haha we’ve updated the Developer Docs now so everything is in one place
@Itsben can you send us the line where the error occurs, or better yet the whole Scriptable script (with API Keys and any additional id / values redacted). If you prefer not to share this publicly you are welcome to send this via the in-app messenger and we can help you directly
I just used it copy and pasted from the developer site - used the API key as the widget parameter.
It says the error starts on line 9 which is const date = new Date(Date.parse(card.data.modified_when));
TypeError: undefined is not an object (evaluating ‘card.data.modified_when’)
const API_KEY = args.widgetParameter;
const cardCollection = await loadPinnedCards();
const cards = Object.values(cardCollection);
const widget = await createCardWidget(cards[0]);
Script.setWidget(widget);
Script.complete();async function createCardWidget(card) {
const date = new Date(Date.parse(card.data.modified_when));
const dateFormatter = new DateFormatter();
dateFormatter.useMediumDateStyle();
dateFormatter.useShortTimeStyle();
const strDate = dateFormatter.string(date);
const gradient = new LinearGradient();
gradient.locations = [0, 1];
gradient.colors = [new Color(“#ff607e”), new Color(“#ff6682”)];
const widget = new ListWidget();
widget.backgroundColor = new Color(“#ff6682”);
widget.backgroundGradient = gradient;
// name
const nameElement = widget.addText(card.data.name);
nameElement.font = Font.boldSystemFont(16);
nameElement.textColor = Color.white();
nameElement.minimumScaleFactor = 0.75;
widget.addSpacer(6);
// content
contentElement = widget.addText(card.data.markup);
contentElement.font = Font.mediumSystemFont(12);
contentElement.textColor = Color.white();
widget.addSpacer(6);
// date modified
const footerStack = widget.addStack();
const dateElement = footerStack.addText(strDate);
dateElement.font = Font.mediumSystemFont(12);
dateElement.textColor = Color.white();
dateElement.textOpacity = 0.8;
// open the card directly in Supernotes app when clicking
widget.url = createCardUrl(card.data.id);
return widget;
}async function loadPinnedCards() {
const req = new Request(“https://api.supernotes.app/v1/user/pins”);
req.method = “get”;
req.headers = { “Content-Type”: “application/json”, “Api-Key”: API_KEY };
const jsonResponse = await req.loadJSON();
return jsonResponse;
}function createCardUrl(cardId) {
returnsupernotes://?cardId=${cardId}
;
} const API_KEY = args.widgetParameter;
const cardCollection = await loadPinnedCards();
const cards = Object.values(cardCollection);
const widget = await createCardWidget(cards[0]);
Script.setWidget(widget);
Script.complete();async function createCardWidget(card) {
const date = new Date(Date.parse(card.data.modified_when));
const dateFormatter = new DateFormatter();
dateFormatter.useMediumDateStyle();
dateFormatter.useShortTimeStyle();
const strDate = dateFormatter.string(date);
const gradient = new LinearGradient();
gradient.locations = [0, 1];
gradient.colors = [new Color(“#ff607e”), new Color(“#ff6682”)];
const widget = new ListWidget();
widget.backgroundColor = new Color(“#ff6682”);
widget.backgroundGradient = gradient;
// name
const nameElement = widget.addText(card.data.name);
nameElement.font = Font.boldSystemFont(16);
nameElement.textColor = Color.white();
nameElement.minimumScaleFactor = 0.75;
widget.addSpacer(6);
// content
contentElement = widget.addText(card.data.markup);
contentElement.font = Font.mediumSystemFont(12);
contentElement.textColor = Color.white();
widget.addSpacer(6);
// date modified
const footerStack = widget.addStack();
const dateElement = footerStack.addText(strDate);
dateElement.font = Font.mediumSystemFont(12);
dateElement.textColor = Color.white();
dateElement.textOpacity = 0.8;
// open the card directly in Supernotes app when clicking
widget.url = createCardUrl(card.data.id);
return widget;
}async function loadPinnedCards() {
const req = new Request(“https://api.supernotes.app/v1/user/pins”);
req.method = “get”;
req.headers = { “Content-Type”: “application/json”, “Api-Key”: API_KEY };
const jsonResponse = await req.loadJSON();
return jsonResponse;
}function createCardUrl(cardId) {
returnsupernotes://?cardId=${cardId}
;
}
Hey @Itsben, looks like your API key is still incorrect.
But just to be sure I’ve fleshed out the Scriptable script with some rudimentary error handling that should make debugging a bit easier.
const widget = await pinnedCardWidget();
Script.setWidget(widget);
Script.complete();
function createCardUrl(cardId) {
return `supernotes://card_id=${cardId}`;
}
async function createCardWidget(card) {
const date = new Date(Date.parse(card.data.modified_when));
const dateFormatter = new DateFormatter();
dateFormatter.useMediumDateStyle();
dateFormatter.useShortTimeStyle();
const strDate = dateFormatter.string(date);
const gradient = new LinearGradient();
gradient.locations = [0, 1];
gradient.colors = [new Color('#ff607e'), new Color('#ff6682')];
const widget = new ListWidget();
widget.backgroundColor = new Color('#ff6682');
widget.backgroundGradient = gradient;
// name
const nameElement = widget.addText(card.data.name);
nameElement.font = Font.boldSystemFont(16);
nameElement.textColor = Color.white();
nameElement.minimumScaleFactor = 0.75;
widget.addSpacer(6);
// content
contentElement = widget.addText(card.data.markup);
contentElement.font = Font.mediumSystemFont(12);
contentElement.textColor = Color.white();
widget.addSpacer(6);
// date modified
const footerStack = widget.addStack();
const dateElement = footerStack.addText(strDate);
dateElement.font = Font.mediumSystemFont(12);
dateElement.textColor = Color.white();
dateElement.textOpacity = 0.8;
// open the card directly in Supernotes app when clicking
widget.url = createCardUrl(card.data.id);
return widget;
}
async function createErrorWidget(errorText) {
const gradient = new LinearGradient();
gradient.locations = [0, 1];
gradient.colors = [new Color('#b92426'), new Color('#ad2527')];
const widget = new ListWidget();
widget.backgroundColor = new Color('#ff6682');
widget.backgroundGradient = gradient;
const errorTitleElement = widget.addText('Error');
errorTitleElement.font = Font.boldSystemFont(14);
errorTitleElement.textColor = Color.white();
const errorMessageElement = widget.addText(errorText);
errorMessageElement.font = Font.mediumSystemFont(12);
errorMessageElement.textColor = Color.white();
return widget;
}
async function pinnedCardWidget() {
const req = new Request('https://api.supernotes.app/v1/user/pins');
req.method = 'get';
req.headers = { 'Content-Type': 'application/json', 'Api-Key': args.widgetParameter };
const jsonBody = await req.loadJSON();
if (req.response.statusCode !== 200) {
return await createErrorWidget(jsonBody.detail);
}
const cards = Object.values(jsonBody)
if (cards.length === 0) {
return await createErrorWidget('No pinned cards');
}
return await createCardWidget(cards[0]);
}
If the request to the Supernotes API fails, this version will replace the text of the widget with whatever the error message from the API was.
I’m getting this error with the updated script from Developer Docs
You cannot run the script from directly within Scriptable. This is a widget script so you need to create a Scriptable Widget on your home screen, and then set the Supernotes script to be the script.