Triggers
A Trigger is a script that defines the processing of an entry based on an event that is takimg place. Trigger scripts are written in JavaScript. When a trigger script is executed, it may perform actions like changing an existing entry, creating a new entry, executing an http request, creating a file, performing data validation, etc.
Terminology
So, we define the following terms:
- Event type
- One of the following:
- Creating an entry
- Updating an entry
- Deleting an entry
- Opening an Entry Edit card
- Adding an entry to Favorites
- Removing an entry from Favorites
- Phase of an Event
- One of a predefined set of moments during entry processing during which the user can intervene via a trigger script. See the table of events and phases below.
The Event type and the Phase determine the trigger script to be run.
- Trigger or Trigger Script
- A script that may be defined to run when an event occurs for an entry
The trigger (Event type & Phase) and the corresponding trigger script are one-to-one.
When referring specifically to the script, it is called the trigger script. When referring to the Event type & Phase and its listing in the trigger list, it is referred to merely as a trigger.
Mode of script execution
The phase in which the trigger is activated defines its mode of execution — synchronous or asynchronous.
- Synchronous script execution mode
- The application suspends user interaction and then executes the script. Time-consuming operations are not recommended in this mode.
- Asynchronous script execution mode
- The script runs in the background; user interaction is not suspended. Usually, asynchronous scripts are used in the last phases of the action.
Creating a trigger
Each library can have a number of triggers — up to one for each Event type & Phase. To see the list of triggers, open the library, open the menu, and then select Triggers.
To create a trigger, press the 3-dot icon in the upper-right corner of the screen to open the Action Menu; then press Triggers to open the list of existing triggers; then click +. You must then identify the Event type & Phase and write a trigger script that performs the necessary actions.
Events
These are the defined Event types, Phases, and their corresponding modes of execution.
Event type | Phase | Execution mode |
---|---|---|
Creating an entry | Opening an Entry Edit card | synchronous |
Before saving the entry | synchronous | |
After saving the entry | asynchronous | |
Updating an entry | Opening an Entry Edit card | synchronous |
Before saving the entry | synchronous | |
After saving the entry | asynchronous | |
Deleting an entry | Before deleting an entry | synchronous |
After deleting an entry | asynchronous | |
Opening an Entry View card | Before window display | synchronous |
After window display | asynchronous | |
Adding entries to Favorites | Before the operation | synchronous |
After the operation | asynchronous | |
Deleting an entry from Favorites | Before the operation | synchronous |
After the operation | asynchronous |
Security
Since the scripts have access to more actions than a user does, they require additional permissions.
The user must define these permissions manually for each library.
To open the dialog to set permissions for scripts, open the library triggers list and click Shield on the toolbar. Permissions must be set separately on each device. Permissions are not synchronized between devices.
Permissions for scripts
- Library permission
- determines which other libraries can be affected by the script. You can grant access to all libraries or select only certain libraries. This authorization is required for the libByName() function.
- Read permission
- grants the script read access to a file
- Write permission
- grants the script write access to a file
- Network
- grants to the script the right to execute HTTP requests
Libraries and Entries
Library Global Functions
entry()
- Get the entry of the Event. For example, if script is triggered by an Update Entry event, this function will return the entry being updated.
- This function is available to all Events and Phases, with the exception of Creating a file > Opening an Entry Edit card for add; for this action, use the function entryDefault().
- Result
- Entry object — the current entry
entryDefault()
- Get the Entry object containing the default field values for the entry not yet created. This feature is available for the Event Creating an entry > Opening an Entry Edit card.
- Result
- The DefaultEntry object
lib()
- Get the library of the triggering event
- Result
- Library object — the current library
libByName(name)
- Find the library by name. Permission to use the library is required, based on security settings.
- Argument
- The name of the library to find
- Result
- Library object — the library identified by the argument name
Object Library
This object provides access to library entries. You can work with the current library — the lib() — or any other library in the database — libByName(). This function provides the ability to update existing entries and create new ones.
Library Methods
entries()
- Get all the entries of the library
- Result
- Array object containing entries, sorted by the time of their creation, from newest to oldest
find(query)
- Search field values within entries in the library matching the given query. This search is similar to searching via Memento's user interface.
- Argument
- query — the search string
- Result
- Array object containing matching entries. Entries are sorted by the time of their creation, from newest to oldest.
findByKey(name)
- Search all entries by the Entry Name. The library must be set for unique Entry Names.
- Argument
- name — the Entry Name field value
- Result
- Entry object
create(values)
- Create a new entry in the library
- Argument
- values — Object containing the field values
- Result
- Entry object — the new entry in the library
Properties
- Title — The name of the library
Object Entry
This object holds an entry of the current library, allowing the setting of field values
Entry Methods
set(name, value)
- Set the value of the named field. Calling this method results in immediate writing of the value to the library.
- Arguments
- name — name of the field
- value — the value of the field
field(name)
- Get the value of the named field
- Argument
- name — name of the field
- Result
- The value of the field. The type of the result depends on the type of the field.
Entry Properties
- Title — entry name
- Description — entry description
- Favorites — true, if the entry is in Favorites
- Deleted — true, if the record is deleted (it is in the Recycle Bin)
Object DefaultEntry
Template with default values for a new entry
DefaultEntry Methods
set(name, value)
- Set the value of the field
- Arguments
- name — the name of the field
- value — the value of the field
Libraries Examples
Data Validation
Using scripts, you can check the correctness of input data and deny saving of data that fail the test. For example, perhaps a field integer values are allowed only from 0 to 200.
var num = entry().field("Number"); // Get value of field Number
if (num < 0 || num > 200) { // Test for value matching allowable range
message("Wrong range"); // If value is outside range, display message
cancel(); // Cancel the operation
}
This script should be used for the Event type Creating an entry or Updating an entry in the Phase Before saving the entry. It will run synchronously.
Set default values
If default values cannot be set in normal fashion, it can be done using a script.
Previous value of another field
Suppose there is a library containing daily mileage of daily walks or use of a car or bicycle. Suppose the library has a StartingMileage field and a Mileage field. When an entry is created, the field StartMileage must get data from the field Mileage in the previous entry.
var entries = lib().entries(); // Get current library & array of its entries
if (entries.length > 0) { // Check that array is not empty;
// otherwise exit,
// since there is no previous entry.
prevMileage = entries[0].field("Mileage"); // The array is sorted newest to oldest,
// so newest entry in the array
// on top with index of 0.
entryDefault().set("StartMileage", prevMileage); // Set value of field Mileage
// from the previous entry
// as default value for field StartMileage.
}
The script must be set for Event Creating an entry Phase Open the Entry Edit card. It will run synchronously.
Beginning of the next day
Suppose you need to identify the beginning of a new day in the DateTime field. (The script requires connection of the JavaScript library moment.js moment.js.)
var m = moment().add(1,'d'); // Using the moment.js library function moment(),
// get the current time, and add 1 day
m.hour(8).minute(0); // Set the time to hour 8 and minute 0
entryDefault().set("Date",
m.toDate().getTime()); // Use that as the default value for the field Date
The script must be set for Event Creating an entry and Phase Opening an Entry Edit card. It will run synchronously.
Working with files
With scripts, you can read or write files located in the device's internal memory or on the SD card. All file operations are performed by the File object, which is obtained via a global function called file().
To work with the files, the library should have read/write file access.
File Global Functions
file(name)
Open a file for read or write operations. If the file with the specified name does not exist yet, it will be created.
- Argument
- name — The name and the full path to the file. For example, if the file is located on the SD card, the path should be something like /sdcard/example.txt.
- Result
- File object
Object File
This object is returned by the global function file() and provides access to the requested file. After reading or writing, the file should be closed using the method close().
File Methods
- readAll()
- Reads all lines of the file, and then closes the file
- Returns
- Array containing the lines of the file
- readLine()
- Reads the next line from the file stream
- Returns
- The line
- readLines()
- Reads the remaining lines from the file stream
- Returns
- Array containing the remaining lines of the file
- readChar()
- Reads the next character from the file stream
- Returns
- The character
- write(text)
- Write string(s). Take a variable number of arguments, converts each argument to a string, and writes that string to the file stream.
- writeLine(text)
- Write strings and a newline to the file stream
- close()
- Close the file. It can subsequently be reopened.
Properties
- exists
- true — if and only if the file exists; false otherwise
- length
- The length, in bytes, of the file, or 0L if the file does not exist.
- getLineNumber
- Get the current line number
- Returns
- The line number, or position, in the file
Files Examples
Writing & reading from a file
f = file("/sdcard/myfile.txt"); // Open the myfile.txt file on the SD card. If the file does not exist,
// it will be created.
f.writeLine("one"); // Write the string "one" as a line to the file
f.writeLine("two");
f.writeLine("three");
f.close(); // Close the file, saving the data to the file. Until the file is closed,
// the disk file is still empty.
var a = f.readLines(); // Read all lines of the file into the array a
Save an entry to a file in XML format
The entry includes fields: id , title , date.
var xml = '<record id="' + entry().field("id") + '">' + // Format XML record from the entry field values
'<title>' + entry().field("title") + '</title>' +
'<date>' + entry().field("date") + '</date>' +
'</record>';
f = file("/sdcard/" + entry().field("title") + ".xml"); // Open file with same name as Entry Name
f.write(xml); // Save XML data into the file
f.close(); // Close the file
Processing an HTTP request
Scripts can send HTTP requests to Web services through their APIs. Processing for HTTP requests allows integration between Memento and the system. All file operations use the Http object, which works through global function http().
HTTP requests must fulfill two requirements:
- Script execution should be asynchronous, because processing of the request on the network can take a long time — HTTP requests of the last Phase of an Event.
- The library should have the permission Network.
Object Http
Interface for processing HTTP requests
Http Methods
get(url)
- Execute HTTP get request
- Argument
- url — HTTP address, starting with http or https
- Result
- HttpResult — Object containing the result of the execution of the HTTP request
Object HttpResult
Result of the execution of the HTTP request
Properties
- code — HTTP code of the response, if the request is successful (usually 200).
- body — The response in text form
Http Examples
Currency Conversion
Suppose the library contains two fields: PriceUSD and PriceEUR. The user will enter the value in PriceUSD and the value in Euros will appear in PriceEUR according to the current exchange rate.
We will create a Trigger on Event Create an entry to Add and Phase After saving the entry.
result = http().get("http://api.fixer.io/latest?base=USD"); // Use http://fixer.io/ for
// conversion rate in JSON
usdToEur = JSON.parse(result.body)["rates"]["Eur"]; // Use JavaScript object JSON
// to parse the result
entry().set("PriceEUR",
entry().field( "PriceUSD") * usdToEur ); // PriceUSD * conversion rate
// for value for PriceEUR
Creating a Task in the Todoist App
Todoist — A Web service and mobile app for task management. Todoist allows task creation via API [1]. In the following example of task creation, text will be taken from the Memento library entry.
// Create a JSON command for Todoist task creation
// using the format described in [https://develop.todoist.com/#add-an-item].
// This command should include a unique identifier
// created using the guid() global function.
var commands='[{"uuid":"' + guid() + '","temp_id":"' + guid() +
'","type":"item_add","args":{"content":"' + entry().field("Task") + '"}}]';
// Execute the HTTP request. An attribute called '''token''' is used
// for authorization in Todoist.
// It is available in the Todoist Account setting.
// Since the text of the task can include symbols
// not allowed in a URL request,
// use the standard function encodeURIComponent() to filter them out.
result = http().get("https://todoist.com/API/v7/sync?token=15281e8e4d499dаff817af0b14112eac3176f9dc&commands=" +
encodeURIComponent(commands));
// Show the user a message indicating successful creation of the task.
if (result.code == 200) message('Task has been successfully created");
Interaction with the System
System Global Functions
message(text)
- Shows the user a brief notification
- Argument
- text — Text of the notification
cancel()
- Stop the system operation that caused the event. Many triggers can be a result of an entry manipulation (create, update, delete, etc). The cancel() function can be used during the phases that precede the system operation. For example, this function can be used during data validation before the entry is saved.
system()
- Obtain information about the system
- Result
- System object
log(text)
- Write a line to the log file
- Argument
- text — text to be written to the log
guid()
- Generates random text identifier
- Result
- Random string identifier
intent(action)
- Create an information exchange object — Intent. This function can send a request for action to another application.
- This function is available only on Android.
- Argument
- action — Line that defines standard action (eg, view, pick)
- Result
- Intent — Information exchange object
- After the object is received, the data will be added to it, and then sent via send().
- Android has many built-in actions. A list of these actions can be found here.
Object System
This object contains information about the system.
Properties
- os — Name of the operating system executing the script
Object Intent
Information exchange object. This object is created by using the global function intent().
Intent Methods
data(uri)
- Define URI to reference the data
- Argument
- uri — URI referencing data to which the action will be applied. It can be contact ID, path to the file, phone number, etc.
mimeType(mime)
- Define MIME type of the data
- Argument
- mime — MIME type of the data on which the operation will be performed
extra(key, value)
- Define additional data as key-value pairs, as necessary for execution of the required action. Similar to how URI data can be required for certain actions, other actions may require extra data in this format.
- Arguments
- key and value
extraLong(key, value)
- Define additional data as key-value pairs, where data type needs to be Long
- Arguments
- key and value
send()
- Send a message
System Examples
Script to open a screen for dialing a number
Suppose a library contains a field called Phone containing a phone number.
i = intent("android.intent.action.DIAL"); // Create information exchange object Intent
// with the action of DIAL
i.data("tel:"+entry().field("Phone")); // The data will be the phone number obtained
// from the field Phone
i.send(); // Send the message
Script to open app to send SMS message
The phone number will be obtained from the field Phone and the text of the message will be obtained from the fields ContactName and Notes.
msg = "Dear, " +
entry().field("ContactName") +
"\n" + entry().field("Notes"); // Form the message from ContactName & Notes
i = intent("android.intent.action.SENDTO"); // Create intent object to open the app for sending
i.data("smsto:"+entry().field("Phone")); // Provide the phone number in format smsto:number
i.extra("sms_body" , msg); // Insert the text of the message to sms_body
i.send(); // Send the message
Script to insert an appointment into Google Calendar
Suppose a library contains the time and name of an appointment.
i = intent("android.intent.action.INSERT"); // Create Intent object
i.data("content://com.android.calendar/events"); // Data contains Google Calendar URI
i.extra("title", entry().field("Title")); // Get event name from field Title
i.extra("description",
entry().field("Description")); // Get description from field Description
i.extraLong("beginTime",
entry().field("Begin").getTime()); // Get start time from field Begin
// Begin is of type DateTime
// Additional parameter is of type Long,
// so extraLong() is used for conversion.
i.extraLong("endTime",
entry().field("End").getTime()); // Get end time from the field End
// Requires same conversion as above
i.send(); // Send the message
JavaScript links
W3Schools | |
---|---|
JavaScript Tutorial | A pleasant, fairly complete, and useful tutorial on JavaScript Best on a computer or tablet in landscape. On a phone or tablet in portrait, scroll to the bottom for navigation. |
Mozilla Developer Network | |
JavaScript Guide | Shows you how to use JavaScript, gives an overview of the language, and presents its capabilities & features |
JavaScript Reference | The entire JavaScript language described in detail |
Introduction to JavaScript | Introduces JavaScript and discusses some of its fundamental concepts |
JavaScript Tutorial | A re-introduction. JavaScript is often derided as being a toy, but beneath its simplicity, powerful language features await. |
JavaScript 1.7 | The JavaScript release upon which Memento is currently based |
About JavaScript | Jumping off point in learning about JavaScript |