Triggers

From Memento Database Wiki
Revision as of 13:04, 6 October 2016 by UnConnoisseur (talk | contribs)
Jump to navigation Jump to search
« Page as of 2016-10-06, editions Mobile 4.0.0, Desktop 1.0.5 »

This page is incomplete, incorrect, in the midst of translation, and under development.

A Trigger is a script that defines the processing of an entry based on an Event that has taken place. Trigger scripts are written in JavaScript. When a trigger script is executed, it may change an existing entry, create a new entry, execute an http request, create a file, perform 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
Event or Phase
One of a predefined set of moments (Event type & Phase) during entry processing during which the user can intervene via a trigger script. See the table of events below.
The Event and the Phase are essentially synonymous.
Depending upon context, either term may be more appropriate than the other.
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
implies the application suspends user interaction and then executes the script. It is not recommended to perform time-consuming operations in this case.
Asynchronous script execution mode
results in the script running 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. To see the list of triggers, open the library, open the menu, and then select Triggers.

To create a trigger, open the library's list of triggers and click +. You must then identify the Event and write a trigger script that performs the necessary actions.

Events

These are the defined Event types, Phases, and their corresponding moves of execution.

THE DEFINED EVENT TYPES & THEIR PHASES
Event type Phase Execution mode
Creating an entry Opening an Entry Edit card for add synchronous
Before saving the entry synchronous
After saving the entry asynchronous
Updating an entry Opening an Entry Edit card for update 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 permissions
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() method.
Read permissions
grants the script read access to a file
Write permissions
grants the script write access to a file
Network
grants to the script the right to execute http requests

Libraries and Entries

Global Methods

entry()

Get the entry of the Event. For example, if script is triggered by an Update Entry event, this method will return the entry being updated.
This method 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 method 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 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 method provides the ability to update existing entries and create new ones.

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
valuesObject 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

Methods

set(name, value)
Set the value of the field
Arguments
name — the name of the field
value — the value of the field

Examples

Data Validation

Using scripts, you can check the correctness of input data. For example, perhaps a field integer values ​​are allowed only from 0 to 200.

var num = entry().field("Number") // Get the value of field Number
if (num < 0 || num > 200) {       // Test for value matching allowable range
 message("Wrong range");          // If the value is outside the range, display message "Wrong range"
 cancel();                        // Cancel the operation
}

This script should be used for the Event Create entry or Update entry in the phase Before Saving the Entry.

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 the current library and an array of its entries
if (entries.length > 0) {                           // Check that the array is not empty; otherwise exit,
                                                    // since there is no previous entry.
prevMileage = entries[0].field("Mileage");          // The array is sorted from newest to oldest,
                                                    // so the newest entry already in the array
                                                    // will be on top with index of 0.
entryDefault().set("StartMileage" , prevMileage )   // Set the value of the field Mileage from the previous entry
                                                    // as the default value for the field StartMileage.
}

The script must be set for Event Creating an entry phase Open the Entry Edit card for Add.

Beginning of the next day

If you need to identify the beginning of a new day in the Date/Time field, the script requires to connect 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 for Add.

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 through a method call file().

To work with the files, the library should have read/write file access.

Global Functions

file(name)

Open a file for read or write operations

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 file() method and provides access to the requested file. If the file with the specified name does not exist yet, it will be created. After reading or writing, the file should be closed using the method close().

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
Returns
The line
readLines()
Reads the remaining lines in the file
Returns
Array containing the remaining lines of the file
readChar()
Reads the next character
Returns
The character
write(text)
Write string(s). This function takes a variable number of arguments, converts each argument to a string, and writes that string to the file.
writeLine(text)
Write strings and a newline to the file
close()
Close the file. It can be subsequently 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

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 into 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 method http().

HTTP requests must fulfill two requirements:

  1. Script execution should be asynchronous, because processing of the request on the network can take a long time. Therefore, HTTP requests of the last Event phase.
  2. The library should have permission - Network.

Object Http

Interface for processing HTTP requests.

Methods

get(url)
Execute 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 is 200).
body
The response in text form

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 Entry to Add and phaase After Saving Entry.

result = http().get("http://api.fixer.io/latest?base=USD")       // Use service http://fixer.io/
                                                                 // to get conversion rate in JSON format
usdToEur = JSON.parse(result.body)["rates"]["Eur"]               // Use standard JavaScript object JSON
                                                                 // to parse the result
entry().set("PriceEUR" , entry().field( "PriceUSD") * usdToEur ) // Multiply PriceUSD by the conversion rate
                                                                 // to determine the 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.

var commands='[{"uuid":"' + guid() + '","temp_id":"' + guid() + '","type":"item_add","args":{"content":"' + entry().field("Task") + '"}}]'
result = http().get("https://todoist.com/API/v7/sync?token=15281e8e4d499dаff817af0b14112eac3176f9dc&commands=" + encodeURIComponent(commands))
if (result.code == 200) message('Task has been successfully created")
  1. Составляем команду в json формате для создания задачи в todoist, формат команды описан здесь: https://developer.todoist.com/#add-an-item. В команде должны присутствовать уникальные идентификаторы, для их получения используем глобальную функцию guid().
  2. Выполняем http запрос. Атрибут token используется для авторизации в todoist, его можно получить в Настройках Todoist вкладка Аккаунт. Так как текст задачи может содержать символы недопустимые в URL-запроса, то экранируем их с помощью стандартной функции encodeURIComponent().
  3. Выводим пользователю сообщение об успешно созданной задачи.

Взаимодействие с системой

Глобальные Функции

message(text)

Отобразить пользователю небольшое всплывающее сообщение.
Параметры: text - текст для отображения.

cancel()

Отменить операцию вызвавшую данный триггер. Многие действия возникают при каких либо операциях с записями (создание, модификация, удаление и .д.). Если фаза действия предшествует операции, то возможно отменить эту операцию с помощью данной функции. Например, применять эту функцию можно при проверки корректности вводимых данных перед сохранением записи.

system()

Получить информацию о системе.
Результат: Объект System с информацией о системе.

log(text)

Вывести строку в лог-файл выполнения скрипта. Функция будет полезна для отладки скриптов.
Параметры: Text - текст который будет выведен в лог.

guid()

Генерация случайного текстового идентификатора.
Результат: Случайная строка-идентификатор.

intent(action)

Создать объект обмена сообщениями - Intent. С помощью данного объекта можно передать данные другому приложению, или заставить другое приложение выполнить какое-либо действие.
Функция доступна только для Android.
Параметры: action - Строка, определяющая стандартное действие, которое требуется выполнить (например, view (просмотр) или pick (выбор)).
Результат: Intent - объект обмена сообщениями.
После получения объекта требуется добавить в него отправляемые данные и вызывать метод send().
В Android есть множество встроенных действий, список и описание которых вы можете найти здесь.

Object System

Данный объект содержит информацию о системе.

Свойства

os
имя операционной системы на которой запущен скрипт.

Object Intent

Объект обмена сообщениями. Объект создается с помощью вызова глобальной функции intent().

Methods

data(uri)
Установить URI ссылающийся на данные.
Параметры:uri - URI, ссылающийся на данные, с которыми будет выполняться действие. Это может быть идентификатор контакта, путь к файлу, номер телефона и т.д.
mimeType(mime)
Установить MIME тип данных.
Параметры:mime - MIME тип данных с которыми будет выполняться действие.
extra(key, value)
Установить дополнительные данные в виде ключ-значение, которые необходимы для выполнения запрошенного действия. Точно так же, как некоторые действия используют определенные виды URI данных, некоторые действия используют определенные дополнительные данные.
Параметры:
extraLong(key, value)
Установить дополнительные данные в виде ключ-значение, где значение должно быть типом Long.
send()
Отправить сообщение.

Примеры

Скрипт открывающий окно набора номера

В библиотеке должно быть поле Phone, содержащие номер телефона.

i = intent("android.intent.action.DIAL")
i.data("tel:"+entry().field("Phone"))
i.send()
  1. Создаем объект обмена сообщениями Intent и указываем действие которое откроет окно набора номера - android.intent.action.DIAL.
  2. В качестве данных требуется указать номер телефона в формате tel:номер. Номер телефона берем из поля записи Phone.
  3. Отправляем сообщение.

Скрипт открывающий приложение для отправки смс-сообщения

Номер телефона будет определяться полем записи - Phone, а текст сообщения составляется из полей ContactName и Notes.

msg = "Dear, " + entry().field("ContactName") + "\n" + entry().field("Notes")
i = intent("android.intent.action.SENDTO")
i.data("smsto:"+entry().field("Phone"))
i.extra("sms_body" , msg)
i.send()
  1. Составляем сообщение из значений полей ContactName и Notes
  2. Создаем объект обмена сообщениями Intent и указываем действие которое откроет приложение для отправки сообщений- android.intent.action.SENDTO.
  3. В качестве данных требуется указать номер телефона в формате smsto:номер. Номер телефона берем из поля записи Phone.
  4. Текст сообщение передаем в дополнительный параметр sms_body.
  5. Отправляем сообщение.

Скрипт открывающий форму создания события в Гугл-Календаре.

Время события и название события будут определяться полями записи.

i = intent("android.intent.action.INSERT")
i.data("content://com.android.calendar/events")
i.extra("title", entry().field("Title"))
i.extra("description" , entry().field("Description"))
i.extraLong("beginTime" , entry().field("Begin").getTime())
i.extraLong("endTime" , entry().field("End").getTime())
i.send()
  1. Создаем объект обмена сообщениями Intent и указываем действие которое требуется выполнить, а именно создание объекта - android.intent.action.INSERT.
  2. Для события android.intent.action.INSERT в data требуется передать базовый Uri создаваемого объекта. Событие в Google-календаре имеет базовый Uri - content://com.android.calendar/events.
  3. Устанавливаем название события, которое берем из поля Title.
  4. Устанавливаем описание события, которое берем из поля Description.
  5. Устанавливаем время начала события, которое берем из поля Begin. Поле Begin должно иметь тип Date/Time. Дополнительный параметр beginTime должен иметь тип Long, поэтому используется метод extraLong.
  6. Устанавливаем время окончания события, которое берем из поля End. Поле End должно иметь тип Date/Time. Дополнительный параметр endTime должен иметь тип Long, поэтому используется метод extraLong.
  7. Отправляем сообщение.

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