API Reference
This page documents all Lua APIs available to Gaivota plugins.
Email Object
The email object is passed to both filter() and render() functions.
Properties
| Method | Returns | Description |
|---|---|---|
email:id() | string | Unique message ID |
email:subject() | string? | Email subject line |
email:sender() | string | Sender email address |
email:sender_name() | string? | Sender display name |
email:recipients() | string[] | All recipient addresses (to, cc, bcc combined) |
email:preview() | string? | Body preview text (first ~200 chars) |
email:is_read() | boolean | Whether email has been read |
email:has_attachments() | boolean | Whether email has attachments |
email:urls() | string[] | Extracted URLs from email body |
email:received_at() | number? | Unix timestamp of when email was received |
Helper Methods
| Method | Returns | Description |
|---|---|---|
email:from_self(user_email) | boolean | True if sender matches user's email |
email:to_self(user_email) | boolean | True if user's email is in recipients |
email:has_links() | boolean | True if email contains any URLs |
email:is_self_link_email(user_email) | boolean | Shorthand for from_self AND to_self AND has_links |
Usage Examples
function filter(email, user_email)
-- Check if email is from a specific domain
if email:sender():match("@github%.com$") then
return true
end
-- Check if subject contains keywords
local subject = email:subject() or ""
if subject:match("receipt") or subject:match("invoice") then
return true
end
-- Check if it's a self-sent email with links
if email:is_self_link_email(user_email) then
return true
end
return false
end
URL Metadata Object
The metadata_list passed to render() contains URL metadata objects for each URL in the email.
Properties
| Method | Returns | Description |
|---|---|---|
meta:url() | string | The URL |
meta:title() | string? | Page title (from Open Graph or <title>) |
meta:description() | string? | Page description (from meta tags) |
meta:image() | string? | Open Graph image URL |
meta:site_name() | string? | Site name (from Open Graph) |
meta:favicon() | string? | Favicon URL |
meta:has_metadata() | boolean | True if metadata was successfully fetched |
Usage Example
function render(email, metadata_list)
local html = "<div>"
for _, meta in ipairs(metadata_list) do
if meta:has_metadata() then
html = html .. "<div class='link-card'>"
-- Show image if available
if meta:image() then
html = html .. "<img src='" .. meta:image() .. "' />"
end
-- Show title or fallback to URL
local title = meta:title() or meta:url()
html = html .. "<h3>" .. title .. "</h3>"
-- Show description if available
if meta:description() then
html = html .. "<p>" .. meta:description() .. "</p>"
end
-- Show site name
if meta:site_name() then
html = html .. "<span class='site'>" .. meta:site_name() .. "</span>"
end
html = html .. "</div>"
end
end
html = html .. "</div>"
return {
subject = email:subject(),
sender = email:sender_name() or email:sender(),
preview = email:preview(),
body_html = html
}
end
Filter Function
The filter function determines which emails appear in your virtual folder.
Signature
function filter(email, user_email)
-- email: The email object to evaluate
-- user_email: The current user's email address (string)
-- Returns: boolean (true to include, false to exclude)
end
Examples
-- Filter: Emails from GitHub
function filter(email, user_email)
return email:sender():match("@github%.com$") ~= nil
end
-- Filter: Unread emails with attachments
function filter(email, user_email)
return not email:is_read() and email:has_attachments()
end
-- Filter: Emails containing specific keywords
function filter(email, user_email)
local subject = email:subject() or ""
local preview = email:preview() or ""
local text = subject:lower() .. " " .. preview:lower()
return text:match("urgent") or text:match("important")
end
-- Filter: Self-sent links (like Instapaper/Pocket)
function filter(email, user_email)
return email:from_self(user_email)
and email:to_self(user_email)
and email:has_links()
end
Render Function
The render function transforms how emails appear in the virtual folder.
Signature
function render(email, metadata_list)
-- email: The email object
-- metadata_list: Array of URL metadata objects (may be empty)
-- Returns: table with subject, sender, preview, body_html
end
Return Value
| Field | Type | Required | Description |
|---|---|---|---|
subject | string | Yes | Displayed in list view title |
sender | string? | No | Displayed as sender name |
sender_name | string? | No | Alternative sender display |
preview | string? | No | Displayed in list view preview |
body_html | string | Yes | HTML content for detail view |
Basic Example
function render(email, metadata_list)
return {
subject = email:subject() or "No Subject",
sender = email:sender_name() or email:sender(),
preview = email:preview(),
body_html = "<div><p>" .. (email:preview() or "") .. "</p></div>"
}
end
Advanced Example with URL Metadata
function render(email, metadata_list)
-- Use first link's metadata for display
local first_meta = metadata_list[1]
local subject = email:subject() or "Link"
local sender = "Links"
local preview = ""
if first_meta and first_meta:has_metadata() then
subject = first_meta:title() or subject
sender = first_meta:site_name() or sender
preview = first_meta:description() or preview
end
-- Build HTML body
local html = [[<div style="padding: 16px;">]]
for _, meta in ipairs(metadata_list) do
html = html .. [[
<a href="#"
data-action="mark-read-open-url"
data-url="]] .. meta:url() .. [["
style="display: block; padding: 12px; margin-bottom: 8px;
border: 1px solid #e5e7eb; border-radius: 8px;
text-decoration: none; color: inherit;">
]]
if meta:image() then
html = html .. [[<img src="]] .. meta:image() .. [["
style="width: 100%; max-height: 200px;
object-fit: cover; border-radius: 4px;" />]]
end
html = html .. [[<div style="font-weight: 600; margin-top: 8px;">]]
.. (meta:title() or meta:url()) .. [[</div>]]
if meta:description() then
html = html .. [[<div style="color: #6b7280; font-size: 14px; margin-top: 4px;">]]
.. meta:description() .. [[</div>]]
end
html = html .. [[</a>]]
end
html = html .. [[</div>]]
return {
subject = subject,
sender = sender,
preview = preview,
body_html = html
}
end
Plugin Actions
Your rendered HTML can include special data-action attributes that Gaivota handles automatically.
Available Actions
| Action | Description |
|---|---|
mark-read-open-url | Mark the email as read, then open the URL in default browser |
open-url | Open the URL in default browser (doesn't mark as read) |
archive-and-open | Archive the email, then open the URL |
Usage
<!-- Mark as read and open URL -->
<a href="#" data-action="mark-read-open-url" data-url="https://example.com">
Open Link
</a>
<!-- Just open URL -->
<a href="#" data-action="open-url" data-url="https://example.com">
View
</a>
<!-- Archive and open -->
<a href="#" data-action="archive-and-open" data-url="https://example.com">
Done & Open
</a>
Lua Standard Library
The following Lua standard library functions are available:
Available
string.*- String manipulation (match, sub, gsub, etc.)table.*- Table operations (insert, remove, concat, etc.)math.*- Math functions (floor, ceil, random, etc.)ipairs,pairs- Iterationtype,tostring,tonumber- Type conversionprint- Debug output (visible in logs)
Not Available (Security)
os.*- System access blockedio.*- File I/O blockeddebug.*- Debug library blockedloadfile,dofile- File loading blockedrequire,package- External modules blocked
See Security for more details on the sandbox.