Track Content & Posts

Monitor when your prospects and accounts share content on LinkedIn to engage at the perfect moment.

Why Track LinkedIn Content?

  • Perfect timing - Engage when prospects are active and thinking about relevant topics
  • Understand interests - Learn what matters to your prospects from their content
  • Build relationships - Meaningful engagement on their content creates genuine connections
  • Trigger workflows - Automate personalized outreach based on content themes

What You'll Learn

In this tutorial, you'll learn how to:

  • Set up content monitoring for contacts and companies
  • Filter for relevant content types
  • Analyze engagement patterns
  • Automate content-based outreach
  • Build a content engagement dashboard

Content Event Types

Sales Webhooks monitors these content-related events:

Contact Content Events

Event Description Use Case
contact.post_created New post published Engage with relevant content
contact.comment_created Commented on a post Join conversations
contact.reaction_added Reacted to content Track engagement patterns

Company Content Events

Event Description Use Case
company.post_created Company shared update Track company news

Implementation Guide

Step 1: Set Up Content Monitoring

First, create subscriptions for the contacts whose content you want to track:

// Monitor content from key prospects
const prospects = [
  'https://linkedin.com/in/jane-smith',
  'https://linkedin.com/in/john-doe',
  'https://linkedin.com/in/sarah-jones'
];

// Create subscriptions
for (const linkedinUrl of prospects) {
  await client.subscriptions.create({
    entity_type: 'contact',
    linkedin_url: linkedinUrl
  });
}

// Configure webhook for content events only
await client.webhooks.configure({
  endpoint_url: 'https://your-app.com/content-webhook',
  events: [
    'contact.post_created',
    'contact.comment_created',
    'company.post_created'
  ]
});

Step 2: Process Content Webhooks

Handle incoming content notifications and analyze them:

app.post('/content-webhook', async (req, res) => {
  const event = req.body;
  
  switch (event.type) {
    case 'contact.post_created':
      await handleNewPost(event.data);
      break;
    case 'contact.comment_created':
      await handleComment(event.data);
      break;
    case 'company.post_created':
      await handleCompanyUpdate(event.data);
      break;
  }
  
  res.status(200).send('OK');
});

async function handleNewPost(data) {
  const { entity, post } = data;
  
  // Analyze post content
  const analysis = {
    contact_id: entity.linkedin_id,
    contact_name: entity.name,
    post_url: post.url,
    content: post.content,
    media_type: post.media_type,
    topics: extractTopics(post.content),
    sentiment: analyzeSentiment(post.content),
    engagement: post.engagement
  };
  
  // Store in database
  await db.content_activity.insert(analysis);
  
  // Check if content is relevant to your solution
  if (isRelevantContent(analysis)) {
    await triggerEngagementWorkflow(analysis);
  }
}

Step 3: Identify Relevant Content

Filter content based on keywords, topics, and relevance to your solution:

function isRelevantContent(analysis) {
  // Define your relevance criteria
  const relevantKeywords = [
    'sales', 'revenue', 'growth', 'pipeline',
    'crm', 'automation', 'efficiency', 'productivity'
  ];
  
  const relevantTopics = [
    'sales_technology', 'revenue_operations',
    'sales_enablement', 'digital_transformation'
  ];
  
  // Check for keyword matches
  const contentLower = analysis.content.toLowerCase();
  const hasRelevantKeyword = relevantKeywords.some(
    keyword => contentLower.includes(keyword)
  );
  
  // Check for topic matches
  const hasRelevantTopic = analysis.topics.some(
    topic => relevantTopics.includes(topic)
  );
  
  // Check engagement threshold
  const hasHighEngagement = 
    analysis.engagement.likes > 50 ||
    analysis.engagement.comments > 10;
  
  return hasRelevantKeyword || hasRelevantTopic || hasHighEngagement;
}

function extractTopics(content) {
  // Simple topic extraction - enhance with NLP
  const topics = [];
  
  if (content.match(/\b(sales|selling|revenue)\b/i)) {
    topics.push('sales');
  }
  if (content.match(/\b(tech|software|saas|digital)\b/i)) {
    topics.push('technology');
  }
  if (content.match(/\b(leader|management|strategy)\b/i)) {
    topics.push('leadership');
  }
  
  return topics;
}

Step 4: Automate Engagement

Create automated workflows based on content activity:

async function triggerEngagementWorkflow(analysis) {
  // Determine engagement strategy
  const strategy = determineStrategy(analysis);
  
  switch (strategy) {
    case 'immediate_engage':
      // High-value prospect + relevant content
      await notifySalesRep({
        type: 'urgent_engagement_opportunity',
        contact: analysis.contact_name,
        post_url: analysis.post_url,
        suggested_action: 'Comment with value-add insight',
        talking_points: generateTalkingPoints(analysis)
      });
      break;
      
    case 'nurture_sequence':
      // Add to content-based nurture campaign
      await addToNurtureCampaign({
        contact_id: analysis.contact_id,
        campaign: 'thought_leadership',
        trigger_content: analysis.content,
        personalization: {
          recent_post_topic: analysis.topics[0],
          engagement_level: analysis.engagement
        }
      });
      break;
      
    case 'research_alert':
      // Competitor or market intelligence
      await notifyProductTeam({
        type: 'market_intelligence',
        source: analysis.contact_name,
        content: analysis.content,
        insights: extractInsights(analysis)
      });
      break;
  }
}

function determineStrategy(analysis) {
  // High-value prospect with buying signals
  if (analysis.topics.includes('sales_technology') && 
      analysis.sentiment === 'frustrated') {
    return 'immediate_engage';
  }
  
  // Active thought leader in your space
  if (analysis.engagement.likes > 100) {
    return 'nurture_sequence';
  }
  
  // Competitor or analyst content
  if (analysis.topics.includes('market_analysis')) {
    return 'research_alert';
  }
  
  return 'nurture_sequence';
}

Step 5: Build Engagement Dashboard

Create a dashboard to track content engagement opportunities:

// API endpoint for content analytics
app.get('/api/content-analytics', async (req, res) => {
  const timeframe = req.query.days || 7;
  
  const analytics = await db.query(`
    SELECT 
      DATE(created_at) as date,
      COUNT(*) as total_posts,
      COUNT(DISTINCT contact_id) as active_contacts,
      AVG(engagement_score) as avg_engagement,
      COUNT(CASE WHEN is_relevant THEN 1 END) as relevant_posts,
      COUNT(CASE WHEN action_taken THEN 1 END) as posts_engaged
    FROM content_activity
    WHERE created_at > NOW() - INTERVAL '${timeframe} days'
    GROUP BY date
    ORDER BY date DESC
  `);
  
  const topContent = await db.query(`
    SELECT 
      contact_name,
      post_url,
      content_preview,
      topics,
      engagement_score,
      created_at
    FROM content_activity
    WHERE is_relevant = true
    AND created_at > NOW() - INTERVAL '${timeframe} days'
    ORDER BY engagement_score DESC
    LIMIT 10
  `);
  
  res.json({
    summary: {
      total_posts: analytics.reduce((sum, day) => sum + day.total_posts, 0),
      active_contacts: new Set(analytics.map(d => d.active_contacts)).size,
      engagement_rate: calculateEngagementRate(analytics),
      trending_topics: await getTrendingTopics(timeframe)
    },
    daily_metrics: analytics,
    top_content: topContent,
    engagement_opportunities: await getOpenOpportunities()
  });
});

Advanced Content Strategies

🎯 Pro Tips

  • Timing matters - Engage within 2 hours for maximum visibility
  • Add value - Don't just like; comment with insights
  • Track patterns - Note posting frequency and topics
  • Personalize outreach - Reference their content in your messages

Content Scoring Model

Prioritize which content to engage with using a scoring model:

function calculateContentScore(post, contact) {
  let score = 0;
  
  // Contact value (0-40 points)
  score += contact.deal_size_potential / 10000; // Up to 30 points
  score += contact.engagement_history * 2; // Up to 10 points
  
  // Content relevance (0-30 points)
  const relevanceScore = calculateRelevance(post.content);
  score += relevanceScore * 30;
  
  // Timing (0-20 points)
  const hoursAgo = (Date.now() - post.created_at) / (1000 * 60 * 60);
  score += Math.max(0, 20 - hoursAgo * 2); // Decay over time
  
  // Engagement potential (0-10 points)
  if (post.engagement.comments < 5) {
    score += 10; // Early engagement opportunity
  }
  
  return Math.min(100, score);
}

Integration Examples

Slack Notifications

async function sendSlackAlert(opportunity) {
  await slack.chat.postMessage({
    channel: '#sales-signals',
    blocks: [
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `🔥 *Content Engagement Opportunity*\n${opportunity.contact_name} just posted about ${opportunity.topic}`
        }
      },
      {
        type: 'section',
        fields: [
          {
            type: 'mrkdwn',
            text: `*Relevance Score:*\n${opportunity.score}/100`
          },
          {
            type: 'mrkdwn',
            text: `*Current Engagement:*\n${opportunity.likes} likes, ${opportunity.comments} comments`
          }
        ]
      },
      {
        type: 'actions',
        elements: [
          {
            type: 'button',
            text: { type: 'plain_text', text: 'View Post' },
            url: opportunity.post_url,
            style: 'primary'
          },
          {
            type: 'button',
            text: { type: 'plain_text', text: 'View Contact' },
            url: opportunity.contact_crm_url
          }
        ]
      }
    ]
  });
}

CRM Activity Logging

async function logContentActivity(data) {
  // Find CRM contact
  const crmContact = await crm.contacts.findByLinkedIn(
    data.entity.linkedin_url
  );
  
  if (crmContact) {
    // Log activity
    await crm.activities.create({
      contact_id: crmContact.id,
      type: 'linkedin_content',
      subject: `Posted on LinkedIn: ${data.post.content.substring(0, 50)}...`,
      description: data.post.content,
      metadata: {
        post_url: data.post.url,
        engagement: data.post.engagement,
        topics: data.topics
      }
    });
    
    // Update contact score
    await crm.contacts.update(crmContact.id, {
      engagement_score: crmContact.engagement_score + 5,
      last_activity: new Date(),
      custom_fields: {
        linkedin_active: true,
        recent_topics: data.topics.join(', ')
      }
    });
  }
}

Next Steps

Now that you're tracking content, consider:

Ready to track content?

Start monitoring LinkedIn content from your prospects and engage at the perfect moment.

Get Started in Console →