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:
- Setting up company intelligence tracking
- Building a complete CRM integration
- Implementing best practices for scale
Ready to track content?
Start monitoring LinkedIn content from your prospects and engage at the perfect moment.
Get Started in Console →