Mirra
BuildEvents

Telegram Events

Telegram events fire when messages or commands are received in Telegram chats where your Mirra account is active. These events support automatic content enrichment including ticker detection, sentiment analysis, and entity extraction.


Event Types

telegram.message

The telegram.message event fires when a Telegram message is received in any chat where your Mirra account is active. This event captures messages from direct chats, group chats, and channels, with support for media detection and automatic content enrichment.

Event Type:

type: 'telegram.message'
source: 'telegram'

Fields:

content.text (string)

Message content as plain text. Empty string if the message contains only media with no caption.

content.contentType (ContentType)

Always 'message' for Telegram messages.

content.timestamp (Date)

When the message was sent in the Telegram chat.

actor.id (string)

Telegram user ID of the sender.

actor.name (string)

Display name of the sender as shown in Telegram.

actor.actorType (ActorType)

Either 'user' for regular users or 'bot' for Telegram bots.

context.channelId (string)

Telegram chat ID where the message was sent. Same as telegram.chatId.

context.channelName (string)

Display name of the chat or channel.

context.channelType (ChannelType)

Either 'direct_message' for 1-on-1 chats, 'group_chat' for groups, or 'channel' for Telegram channels.

telegram.messageId (string)

Unique message ID assigned by Telegram.

telegram.chatId (string)

Telegram chat ID. Use this for sending replies via the Telegram adapter.

telegram.isGroupChat (boolean)

True if the message is from a group chat or channel, false for direct messages.

telegram.channelName (string | null)

Channel name if the message is from a Telegram channel, null otherwise.

telegram.hasMedia (boolean)

True if the message contains media attachments (photo, video, document, etc.).

telegram.mediaType ('photo' | 'video' | 'document' | 'audio' | 'sticker' | null)

Type of media attachment if hasMedia is true, null otherwise.

enrichment (EventEnrichment | null)

Content enrichment data including detected tickers, companies, topics, and sentiment analysis. Null until stream processing completes.

FieldTypeDescription
enrichment.tickersTickerMention[]Detected stock/crypto ticker symbols with confidence scores
enrichment.sentimentSentimentAnalysis | nullSentiment analysis with score (-1 to 1), label, and confidence
enrichment.companiesstring[]Detected company names
enrichment.topicsstring[]Extracted topics from message content
entity (EntityData)

Graph entity data for memory and knowledge graph integration. Always present.

Example - Basic Message Handler:

export async function handler(event, context) {
  // Access standardized fields
  console.log('Message:', event.content.text);
  console.log('From:', event.actor.name);
  console.log('Sent at:', event.content.timestamp);
  
  // Access Telegram-specific fields
  console.log('Chat ID:', event.telegram.chatId);
  console.log('Is Group:', event.telegram.isGroupChat);
  console.log('Has Media:', event.telegram.hasMedia);
  
  return { success: true };
}

Example - Ticker Mention Tracker:

export async function handler(event, context) {
  // Wait for enrichment data
  if (!event.enrichment?.tickers) {
    return { success: true, message: 'No tickers detected' };
  }
  
  // Process detected tickers
  for (const ticker of event.enrichment.tickers) {
    console.log(`Found ${ticker.symbol} (confidence: ${ticker.confidence})`);
    
    await mirra.memory.create({
      type: 'ticker_mention',
      content: `${ticker.symbol} mentioned: ${event.content.text}`,
      metadata: {
        ticker: ticker.symbol,
        confidence: ticker.confidence,
        source: 'telegram',
        chatId: event.telegram.chatId
      }
    });
  }
  
  return { 
    success: true, 
    tickersProcessed: event.enrichment.tickers.length 
  };
}

Example - Group Chat Filter:

export async function handler(event, context) {
  // Only process group messages
  if (!event.telegram.isGroupChat) {
    return { success: true, skipped: true };
  }
  
  // Forward important group messages to a channel
  if (event.content.text.includes('urgent') || event.content.text.includes('important')) {
    await mirra.telegram.sendMessage({
      chatId: 'your-notification-channel-id',
      text: `🚨 Important message from ${event.context.channelName}:\n\n${event.content.text}\n\nFrom: ${event.actor.name}`
    });
  }
  
  return { success: true };
}

Subscription Examples:

// Subscribe to all messages
{
  "eventType": "telegram.message"
}
 
// Subscribe to messages containing ticker symbols
{
  "eventType": "telegram.message",
  "conditions": [
    {
      "field": "enrichment.tickers",
      "operator": "exists"
    }
  ]
}
 
// Subscribe to group messages only
{
  "eventType": "telegram.message",
  "conditions": [
    {
      "field": "telegram.isGroupChat",
      "operator": "equals",
      "value": true
    }
  ]
}
 
// Subscribe to messages with specific keywords
{
  "eventType": "telegram.message",
  "conditions": [
    {
      "operator": "or",
      "conditions": [
        {
          "field": "content.text",
          "operator": "contains",
          "value": "urgent"
        },
        {
          "field": "content.text",
          "operator": "contains",
          "value": "important"
        }
      ]
    }
  ]
}

telegram.command

The telegram.command event fires when a Telegram bot command is received (e.g., /start, /help, /settings). This event provides parsed command name and arguments for easy command handling.

Event Type:

type: 'telegram.command'
source: 'telegram'

Fields:

content.text (string)

Full command text including arguments (e.g., "/start welcome").

telegram.command (string)

Command name without the slash (e.g., "start", "help").

telegram.commandArgs (string[])

Array of command arguments split by spaces. Empty array if no arguments.

telegram.chatId (string)

Telegram chat ID where the command was sent.

telegram.isGroupChat (boolean)

True if command was sent in a group chat.

Example - Command Router:

export async function handler(event, context) {
  const command = event.telegram.command;
  const args = event.telegram.commandArgs;
  
  switch (command) {
    case 'start':
      await mirra.telegram.sendMessage({
        chatId: event.telegram.chatId,
        text: 'Welcome to the bot! Use /help to see available commands.'
      });
      break;
      
    case 'help':
      await mirra.telegram.sendMessage({
        chatId: event.telegram.chatId,
        text: 'Available commands:\n/start - Start the bot\n/help - Show this help\n/settings - Configure settings'
      });
      break;
      
    case 'settings':
      // Handle settings command with arguments
      if (args.length > 0) {
        console.log('Settings args:', args);
      }
      break;
      
    default:
      await mirra.telegram.sendMessage({
        chatId: event.telegram.chatId,
        text: `Unknown command: /${command}`
      });
  }
  
  return { success: true, command };
}

Subscription Examples:

// Subscribe to all commands
{
  "eventType": "telegram.command"
}
 
// Subscribe to specific command
{
  "eventType": "telegram.command",
  "conditions": [
    {
      "field": "telegram.command",
      "operator": "equals",
      "value": "start"
    }
  ]
}

Common Use Cases

Auto-Reply Bot

export async function handler(event, context) {
  // Only respond to direct messages
  if (event.telegram.isGroupChat) {
    return { success: true, skipped: true };
  }
  
  // Check for specific keywords
  const text = event.content.text.toLowerCase();
  
  if (text.includes('price') || text.includes('cost')) {
    await mirra.telegram.sendMessage({
      chatId: event.telegram.chatId,
      text: 'Our pricing starts at $10/month. Visit our website for details!'
    });
  } else if (text.includes('support') || text.includes('help')) {
    await mirra.telegram.sendMessage({
      chatId: event.telegram.chatId,
      text: 'Contact our support team at support@company.com'
    });
  }
  
  return { success: true };
}

Sentiment Analysis Tracker

export async function handler(event, context) {
  if (!event.enrichment?.sentiment) {
    return { success: true, message: 'No sentiment data' };
  }
  
  const sentiment = event.enrichment.sentiment;
  
  // Track negative sentiment
  if (sentiment.label === 'negative' && sentiment.confidence > 0.7) {
    await mirra.memory.create({
      type: 'negative_sentiment',
      content: event.content.text,
      metadata: {
        score: sentiment.score,
        confidence: sentiment.confidence,
        source: 'telegram',
        chatId: event.telegram.chatId,
        sender: event.actor.name
      }
    });
    
    // Alert for very negative messages
    if (sentiment.score < -0.7) {
      await mirra.telegram.sendMessage({
        chatId: 'your-alerts-channel',
        text: `⚠️ Very negative message detected\nFrom: ${event.actor.name}\nScore: ${sentiment.score}\n\n${event.content.text}`
      });
    }
  }
  
  return { success: true };
}

Media Archiver

export async function handler(event, context) {
  // Only process messages with photos
  if (!event.telegram.hasMedia || event.telegram.mediaType !== 'photo') {
    return { success: true, skipped: true };
  }
  
  // Log photo message to database
  await mirra.memory.create({
    type: 'telegram_photo',
    content: `Photo from ${event.actor.name}: ${event.content.text}`,
    metadata: {
      messageId: event.telegram.messageId,
      chatId: event.telegram.chatId,
      chatName: event.context.channelName,
      timestamp: event.content.timestamp,
      caption: event.content.text
    }
  });
  
  return { success: true };
}

See Also

On this page