Skip to main content

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

MethodReturnsDescription
email:id()stringUnique message ID
email:subject()string?Email subject line
email:sender()stringSender 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()booleanWhether email has been read
email:has_attachments()booleanWhether email has attachments
email:urls()string[]Extracted URLs from email body
email:received_at()number?Unix timestamp of when email was received

Helper Methods

MethodReturnsDescription
email:from_self(user_email)booleanTrue if sender matches user's email
email:to_self(user_email)booleanTrue if user's email is in recipients
email:has_links()booleanTrue if email contains any URLs
email:is_self_link_email(user_email)booleanShorthand 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

MethodReturnsDescription
meta:url()stringThe 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()booleanTrue 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

FieldTypeRequiredDescription
subjectstringYesDisplayed in list view title
senderstring?NoDisplayed as sender name
sender_namestring?NoAlternative sender display
previewstring?NoDisplayed in list view preview
body_htmlstringYesHTML 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

ActionDescription
mark-read-open-urlMark the email as read, then open the URL in default browser
open-urlOpen the URL in default browser (doesn't mark as read)
archive-and-openArchive 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 - Iteration
  • type, tostring, tonumber - Type conversion
  • print - Debug output (visible in logs)

Not Available (Security)

  • os.* - System access blocked
  • io.* - File I/O blocked
  • debug.* - Debug library blocked
  • loadfile, dofile - File loading blocked
  • require, package - External modules blocked

See Security for more details on the sandbox.