Gmail Events Handle incoming and outgoing emails in your scripts
Gmail events fire when emails are received or sent through your connected Gmail account. These events provide complete email details including sender, recipients, subject, body, attachments, and labels, with support for automatic content enrichment.
The gmail.email_received event fires when an email is received in your Gmail inbox. This event provides complete email details including sender, recipients, subject, body, and attachments.
Event Type:
type : 'gmail.email_received'
source : 'google-gmail'
Fields:
content.text (string)Email body content as plain text.
content.contentType (ContentType)Always 'email' for Gmail messages.
actor.id (string)Sender's email address.
actor.name (string)Sender's display name or email if no name available.
context.channelId (string)Gmail thread ID.
context.channelType (ChannelType)Always 'email_thread'.
gmail.messageId (string)Unique Gmail message ID. Use this for operations like adding labels or replying.
gmail.threadId (string)Gmail conversation thread ID. All emails in a conversation share the same thread ID.
gmail.subject (string)Email subject line. Empty string if no subject.
gmail.from (EmailAddress)Sender email address with optional display name.
Field Type Description from.emailstring Sender's email address from.namestring | null Sender's display name
gmail.to (EmailAddress[])Array of primary recipients. Empty array if none.
gmail.cc (EmailAddress[])Array of CC recipients. Empty array if none.
gmail.bcc (EmailAddress[])Array of BCC recipients. Empty array if none (usually unavailable).
gmail.date (Date)When the email was sent.
gmail.hasAttachments (boolean)True if the email has file attachments.
gmail.labels (string[])Array of Gmail labels applied to this message (e.g., ["INBOX", "IMPORTANT", "UNREAD"]).
gmail.isUnread (boolean)True if the email is unread.
enrichment (EventEnrichment | null)Content enrichment including detected tickers, companies, and sentiment. Null until processing completes.
Example - Auto-Label Important Emails:
export async function handler ( event , context ) {
const subject = event.gmail.subject. toLowerCase ();
const from = event.gmail.from.email;
// Label urgent emails
if (subject. includes ( 'urgent' ) || subject. includes ( 'asap' )) {
await mirra.gmail. addLabel ({
messageId: event.gmail.messageId,
label: 'Urgent'
});
}
// Label emails from VIPs
const vips = [ 'boss@company.com' , 'client@important.com' ];
if (vips. includes (from)) {
await mirra.gmail. addLabel ({
messageId: event.gmail.messageId,
label: 'VIP'
});
}
return { success: true };
}
Example - Email Digest to Telegram:
export async function handler ( event , context ) {
// Send email notification to Telegram
const message = `
📧 New Email
From: ${ event . gmail . from . name || event . gmail . from . email }
Subject: ${ event . gmail . subject }
${ event . content . text . substring ( 0 , 200 ) }...
${ event . gmail . hasAttachments ? '📎 Has attachments' : ''}
` . trim ();
await mirra.telegram. sendMessage ({
chatId: 'your-chat-id' ,
text: message
});
return { success: true };
}
Example - Invoice Tracker:
export async function handler ( event , context ) {
// Only process emails with "invoice" in subject
if ( ! event.gmail.subject. toLowerCase (). includes ( 'invoice' )) {
return { success: true , skipped: true };
}
// Log to spreadsheet
await mirra.google.sheets. appendRow ({
spreadsheetId: 'your-sheet-id' ,
sheetName: 'Invoices' ,
values: [
event.gmail.date. toISOString (),
event.gmail.from.email,
event.gmail.subject,
event.gmail.hasAttachments ? 'Yes' : 'No' ,
event.gmail.labels. join ( ', ' )
]
});
// Add invoice label
await mirra.gmail. addLabel ({
messageId: event.gmail.messageId,
label: 'Invoices'
});
return { success: true };
}
Subscription Examples:
// All emails
{
"eventType" : "gmail.email_received"
}
// Only unread emails
{
"eventType" : "gmail.email_received" ,
"conditions" : [
{
"field" : "gmail.isUnread" ,
"operator" : "equals" ,
"value" : true
}
]
}
// Emails with attachments
{
"eventType" : "gmail.email_received" ,
"conditions" : [
{
"field" : "gmail.hasAttachments" ,
"operator" : "equals" ,
"value" : true
}
]
}
// Emails from specific sender
{
"eventType" : "gmail.email_received" ,
"conditions" : [
{
"field" : "gmail.from.email" ,
"operator" : "equals" ,
"value" : "important@sender.com"
}
]
}
// Emails with keywords in subject
{
"eventType" : "gmail.email_received" ,
"conditions" : [
{
"operator" : "or" ,
"conditions" : [
{
"field" : "gmail.subject" ,
"operator" : "contains" ,
"value" : "invoice"
},
{
"field" : "gmail.subject" ,
"operator" : "contains" ,
"value" : "receipt"
}
]
}
]
}
// VIP emails
{
"eventType" : "gmail.email_received" ,
"conditions" : [
{
"field" : "gmail.from.email" ,
"operator" : "in" ,
"value" : [ "boss@company.com" , "client@important.com" ]
}
]
}
export async function handler ( event , context ) {
// Convert emails with [TASK] in subject to assignments
if ( ! event.gmail.subject. includes ( '[TASK]' )) {
return { success: true , skipped: true };
}
// Extract task details from subject
const taskTitle = event.gmail.subject. replace ( '[TASK]' , '' ). trim ();
// Create assignment
await mirra.assignments. create ({
title: taskTitle,
description: event.content.text. substring ( 0 , 500 ),
source: 'email' ,
metadata: {
emailId: event.gmail.messageId,
from: event.gmail.from.email,
receivedAt: event.gmail.date
}
});
// Archive the email
await mirra.gmail. archive ({
messageId: event.gmail.messageId
});
// Add task label
await mirra.gmail. addLabel ({
messageId: event.gmail.messageId,
label: 'Tasks'
});
return { success: true };
}
export async function handler ( event , context ) {
// Detect newsletters by unsubscribe link
const hasUnsubscribe = event.content.text. toLowerCase (). includes ( 'unsubscribe' );
if ( ! hasUnsubscribe) {
return { success: true , skipped: true };
}
// Auto-label as newsletter
await mirra.gmail. addLabel ({
messageId: event.gmail.messageId,
label: 'Newsletters'
});
// Mark as read
await mirra.gmail. markAsRead ({
messageId: event.gmail.messageId
});
// Archive
await mirra.gmail. archive ({
messageId: event.gmail.messageId
});
return { success: true };
}
export async function handler ( event , context ) {
// Only backup important emails
if ( ! event.gmail.labels. includes ( 'IMPORTANT' )) {
return { success: true , skipped: true };
}
// Save to memory/knowledge graph
await mirra.memory. create ({
type: 'email_backup' ,
content: event.content.text,
metadata: {
messageId: event.gmail.messageId,
threadId: event.gmail.threadId,
from: event.gmail.from.email,
subject: event.gmail.subject,
date: event.gmail.date,
labels: event.gmail.labels,
hasAttachments: event.gmail.hasAttachments
}
});
return { success: true };
}
export async function handler ( event , context ) {
// Only suggest replies for direct emails (not CC'd)
const isDirectRecipient = event.gmail.to. some (
recipient => recipient.email === 'your@email.com'
);
if ( ! isDirectRecipient || event.gmail.cc. length > 0 ) {
return { success: true , skipped: true };
}
// Check sentiment
if (event.enrichment?.sentiment) {
const sentiment = event.enrichment.sentiment;
// Generate contextual reply based on sentiment
let suggestedReply = '' ;
if (sentiment.label === 'positive' ) {
suggestedReply = `Thank you for your email! I appreciate your message about ${ event . gmail . subject }.` ;
} else if (sentiment.label === 'negative' ) {
suggestedReply = `I understand your concern regarding ${ event . gmail . subject }. Let me look into this right away.` ;
} else {
suggestedReply = `Thanks for reaching out about ${ event . gmail . subject }. I'll get back to you shortly.` ;
}
// Store suggestion in memory for later use
await mirra.memory. create ({
type: 'reply_suggestion' ,
content: suggestedReply,
metadata: {
emailId: event.gmail.messageId,
threadId: event.gmail.threadId,
sentiment: sentiment.label
}
});
}
return { success: true };
}