Story programming cheatsheet
Table of contents
JavaScript
export const onArrive = async (api) => {
}
export const onMessage = async (msg, api) => {
}
api.moveTo("node1")
api.moveTo("node1", {channelKey: "board2"})
api.sendText("hello")
api.sendImage("f00ba420-0123-4567-89abcdef012356789")
api.sendAudio("e4770840-3c2e-4eeb-b59b-a0e15e14190b")
api.sendVideo("b94eb8f3-72ef-476d-ad61-64adc18204e7")
api.sendImage("f00ba420-0123-4567-89abcdef012356789", { objectFit: "contain" })
api.sendImage("f00ba420-0123-4567-89abcdef012356789", { zoomable: false })
api.sendLink("https://docs.interkit.app/")
api.sendLink("Docs", { url: "https://docs.interkit.app/" })
api.sendImage("f00ba420-0123-4567-89abcdef012356789", { url: "https://docs.interkit.app/" })
api.sendText("hello", {label: "bot"})
if(msg.payload.text == "foo") {
}
api.sendChoice({
a: "option a",
b: "option b"
})
if(msg.payload.key == "a") {
}
api.sendSystem("Someone entered the channel")
api.sendSystemImage("f00ba420-0123-4567-89abcdef012356789")
api.sendSystemImage("f00ba420-0123-4567-89abcdef012356789", {width: "200px"})
api.sendSystemImage("f00ba420-0123-4567-89abcdef012356789", {placement: "me"})
api.sendSystemImage("f00ba420-0123-4567-89abcdef012356789", {placement: "other"})
api.sendText("hello", {delay: 10})
api.sendText("hello", {delay: {hours: 1, minutes: 30}})
api.sendText("hello", {delay: {nextHour: 13}})
api.sendText("hello", {delay: {nextHour: 13, randomHours: 1}})
api.echo(msg)
await api.getUserVar("name")
await api.setUserVar("name", "alice")
await api.setElementProperty("f00ba420-0123-4567-89abcdef012356789", "discovered", true)
await api.getElementProperty("f00ba420-0123-4567-89abcdef012356789", "discovered")
await api.setChannelProperty("board1", "unlisted", true)
await api.getRows("elements")
await api.addRow("elements", {title: "hello"})
await api.updateRow("elements", "rowKey", {title: "bye"})
api.setInterface({text: false})
api.setInterface({text: true})
api.setInterface({text: true, photo: true})
api.setInterface({text: false, photo: true})
api.setInterface({photo: true, cameraFacingMode: "environment"})
api.sendText('Give me a photo', { setInterface: { photo: true, text: false } })
api.requestLocation("Send Location", {cancel: "Cancel"})
if(msg.payload.type == "locationResponse") {
if(api.distance(msg.payload.location, {lat: 56, lng: 12}) < 100) {
api.sendText("you're close!")
}
}
if(msg.payload.type == "locationRequestCanceled") {
api.sendText("ok")
}
api.sendImage("f00ba420-0123-4567-89abcdef012356789", {action: {trigger: "triggerName", payload: payloadObject}})
api.sendImage("f00ba420-0123-4567-89abcdef012356789", {customClass: "special"})
api.sendText('your language: ' + api.userLang)
api.sendText('your language, index: ' + api.userLangIndex)
api.setLang('de', 1)
if (api.userLang === 'en') ...
if (api.userLangIndex === 1) ...
let text1 = ['Deutsch', 'Englisch'][api.userLangIndex]
let text2 = {de: 'Deutsch', en: 'Englisch'}[api.userLang]
export const onMessage = async (msg, api, t) => {
api.sendChoice({ a: t('Ja|Yes'), b: t('Nein|No') })
}
api.sendText(t('Ja|Yes'))
api.sendText(t(['Ja', 'Yes']))
api.sendText(t({ de: 'Ja', en: 'Yes' }))
api.sendTextT('Tschüß|Bye')
api.sendChoiceT({ a: 'Ja|Yes', b: ['Nein', 'No'] })
api.sendSystemT('Chat verlassen|Left the chat')
Twine-ish syntax
`ignore this first line
Hi! This is a message.
An empty newline separates paragraphs = message.
[script]console.log('This tag lets you passthru JS code');
console.log('It's good to indent the next line.');
// and backticks are currently not supported here!
A Twine link, like [[nodeName]],
will become a choice with moveTo to nodeName.
We also support Twine aliases/renames:
[[Go Home|home]] [[Go Home->home]] [[home<-Go Home]]
...with i18n:
[[Nach Hause|To home|homeNode]]
[[homeNode<-Nach Hause|To home]] etc.
All other text in paragraphs with links,
like this sentence, will be ignored.
Twine paragraphs can be explicit, immediate moveTos:
[->To home]
Twine paragraphs (message+moveTos) can take options:
Hello world[{"delay":10}]
[->To home][{"delay":{"hours":1}]
Give me a photo[{"setInterface":{"photo":true}}]
`