โดยสรุป
Hootsuite API ช่วยให้นักพัฒนาสามารถรวมระบบเข้ากับเวิร์กโฟลว์การจัดการโซเชียลมีเดียได้โดยใช้โปรแกรม โดยใช้การยืนยันตัวตน OAuth 2.0, ปลายทาง RESTful สำหรับโปรไฟล์ โพสต์ การวิเคราะห์ และการจัดการทีม พร้อมกับข้อจำกัดอัตราการเรียกใช้งานที่ 50-200 คำขอต่อนาที ขึ้นอยู่กับแผนบริการ คู่มือนี้ครอบคลุมการตั้งค่าการยืนยันตัวตน การตั้งเวลาโพสต์ การดึงข้อมูลวิเคราะห์ การจัดการทีม และกลยุทธ์การรวมระบบสำหรับการใช้งานจริง
หมายเหตุ: Hootsuite ได้ยกเลิก Public API ของตนเองแล้วตั้งแต่ปี 2024 คู่มือนี้ครอบคลุมแนวทางทางเลือกอื่น ๆ รวมถึงการผสานรวมพันธมิตรของ Hootsuite, Webhooks และ API การจัดการโซเชียลมีเดียของบุคคลที่สามที่ให้ฟังก์ชันการทำงานที่คล้ายกัน
บทนำ
Hootsuite จัดการบัญชีโซเชียลมีเดียมากกว่า 30 ล้านบัญชีสำหรับธุรกิจกว่า 200,000 แห่งในกว่า 175 ประเทศ สำหรับนักพัฒนาที่สร้างเครื่องมือโซเชียลมีเดีย แพลตฟอร์มการตลาด หรือแดชบอร์ดการวิเคราะห์ การผสานรวม API โซเชียลมีเดียเป็นสิ่งจำเป็นในการเข้าถึงกลุ่มธุรกิจขนาดใหญ่นี้
นี่คือความจริง: ผู้จัดการโซเชียลมีเดียที่ดูแลบัญชีมากกว่า 20 บัญชีสูญเสียเวลา 25-35 ชั่วโมงต่อสัปดาห์ไปกับการโพสต์ด้วยตนเอง การติดตามการมีส่วนร่วม และการสร้างรายงาน การผสานรวม API โซเชียลมีเดียที่ดีจะช่วยให้การเผยแพร่เนื้อหา การตรวจสอบการมีส่วนร่วม การวิเคราะห์ความรู้สึก และการรายงานประสิทธิภาพเป็นไปโดยอัตโนมัติ
สถานะ API ของ Hootsuite และทางเลือกอื่น
สถานการณ์ API ปัจจุบัน
ตั้งแต่ปี 2024 เป็นต้นไป Hootsuite ได้ยกเลิกการใช้งาน Public API ของตนเองแล้ว ตัวเลือกสำหรับการเชื่อมต่อมีดังนี้:
| แนวทาง | คำอธิบาย | เหมาะสมที่สุดสำหรับ |
|---|---|---|
| Native Platform APIs | การเชื่อมต่อโดยตรงกับ Facebook, Twitter, LinkedIn เป็นต้น | ควบคุมได้เต็มที่, โซลูชั่นที่ปรับแต่งเอง |
| Audiense | ระบบวิเคราะห์ข้อมูลผู้ชม (Audience Intelligence) ที่เป็นของ Hootsuite | การวิเคราะห์กลุ่มเป้าหมาย |
| HeyOrca | API สำหรับการตั้งเวลาโพสต์โซเชียลมีเดีย | ปฏิทินเนื้อหา |
| Buffer API | การจัดการโซเชียลมีเดีย | ทีมขนาดเล็ก |
| Sprout Social API | การจัดการโซเชียลมีเดียระดับองค์กร | องค์กรขนาดใหญ่ |
| Agorapulse API | CRM สำหรับโซเชียลมีเดีย | การจัดการชุมชน |
แนวทางที่แนะนำ: Native Platform APIs
สำหรับกรณีการใช้งานส่วนใหญ่ การเชื่อมต่อโดยตรงกับแพลตฟอร์มโซเชียลจะให้ความยืดหยุ่นสูงสุด:
| แพลตฟอร์ม | ชื่อ API | คุณสมบัติหลัก |
|---|---|---|
| Facebook/Instagram | Graph API | โพสต์, ข้อมูลเชิงลึก, ความคิดเห็น |
| Twitter/X | API v2 | ทวีต, การวิเคราะห์, สตรีม |
| Marketing API | โพสต์, เพจบริษัท, โฆษณา | |
| API v5 | พิน, บอร์ด, การวิเคราะห์ | |
| TikTok | Display API | วิดีโอ, ข้อมูลผู้ใช้ |
| YouTube | Data API | วิดีโอ, เพลย์ลิสต์, การวิเคราะห์ |
เริ่มต้นใช้งาน: การยืนยันตัวตนสำหรับหลายแพลตฟอร์ม
ขั้นตอนที่ 1: ลงทะเบียนแอปพลิเคชันสำหรับนักพัฒนา
สร้างบัญชีนักพัฒนาสำหรับแต่ละแพลตฟอร์มและจัดเก็บ credentials อย่างปลอดภัย:
// Store credentials securely
const SOCIAL_CREDENTIALS = {
facebook: {
appId: process.env.FB_APP_ID,
appSecret: process.env.FB_APP_SECRET,
redirectUri: process.env.FB_REDIRECT_URI
},
twitter: {
apiKey: process.env.TWITTER_API_KEY,
apiSecret: process.env.TWITTER_API_SECRET,
redirectUri: process.env.TWITTER_REDIRECT_URI
},
linkedin: {
clientId: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
redirectUri: process.env.LINKEDIN_REDIRECT_URI
},
instagram: {
appId: process.env.FB_APP_ID, // Uses Facebook Login
appSecret: process.env.FB_APP_SECRET
}
};
ขั้นตอนที่ 2: ใช้กระบวนการ OAuth 2.0
สร้างฟังก์ชันรวมสำหรับขอ Authorization และแลกเปลี่ยน Access Token:
const getAuthUrl = (platform, state) => {
const configs = {
facebook: {
url: 'https://www.facebook.com/v18.0/dialog/oauth',
params: {
client_id: SOCIAL_CREDENTIALS.facebook.appId,
redirect_uri: SOCIAL_CREDENTIALS.facebook.redirectUri,
scope: 'pages_manage_posts,pages_read_engagement,instagram_basic,instagram_content_publish',
state
}
},
twitter: {
url: 'https://twitter.com/i/oauth2/authorize',
params: {
client_id: SOCIAL_CREDENTIALS.twitter.apiKey,
redirect_uri: SOCIAL_CREDENTIALS.twitter.redirectUri,
scope: 'tweet.read tweet.write users.read offline.access',
state,
response_type: 'code'
}
},
linkedin: {
url: 'https://www.linkedin.com/oauth/v2/authorization',
params: {
client_id: SOCIAL_CREDENTIALS.linkedin.clientId,
redirect_uri: SOCIAL_CREDENTIALS.linkedin.redirectUri,
scope: 'w_member_social r_basicprofile',
state,
response_type: 'code'
}
}
};
const config = configs[platform];
const params = new URLSearchParams(config.params);
return `${config.url}?${params.toString()}`;
};
// Handle OAuth callback
const handleOAuthCallback = async (platform, code) => {
const tokenEndpoints = {
facebook: 'https://graph.facebook.com/v18.0/oauth/access_token',
twitter: 'https://api.twitter.com/2/oauth2/token',
linkedin: 'https://www.linkedin.com/oauth/v2/accessToken'
};
const response = await fetch(tokenEndpoints[platform], {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: SOCIAL_CREDENTIALS[platform].apiKey || SOCIAL_CREDENTIALS[platform].appId || SOCIAL_CREDENTIALS[platform].clientId,
client_secret: SOCIAL_CREDENTIALS[platform].appSecret || SOCIAL_CREDENTIALS[platform].apiSecret,
redirect_uri: SOCIAL_CREDENTIALS[platform].redirectUri,
code,
grant_type: 'authorization_code'
})
});
return response.json();
};
ขั้นตอนที่ 3: จัดเก็บโทเค็นอย่างปลอดภัย
จัดเก็บ Access Token อย่างปลอดภัย พร้อมข้อมูลการหมดอายุและ Scope:
// Database schema for social tokens
const SocialToken = {
userId: 'user_123',
platform: 'facebook',
accessToken: 'encrypted_token_here',
refreshToken: 'encrypted_refresh_token',
tokenExpiry: Date.now() + 5183999, // 60 days
scopes: ['pages_manage_posts', 'pages_read_engagement'],
pageId: 'page_456', // For Facebook/Instagram
pageName: 'My Business Page'
};
การตั้งเวลาและเผยแพร่โพสต์
การสร้างโพสต์สำหรับหลายแพลตฟอร์ม
เผยแพร่โพสต์พร้อมกันบนหลายแพลตฟอร์มด้วยฟังก์ชันเดียว:
const createSocialPost = async (postData) => {
const results = {};
// Facebook Page Post
if (postData.platforms.includes('facebook')) {
results.facebook = await postToFacebook({
pageId: postData.facebookPageId,
message: postData.message,
link: postData.link,
photo: postData.photo
});
}
// Twitter Post
if (postData.platforms.includes('twitter')) {
results.twitter = await postToTwitter({
text: postData.message,
media: postData.photo
});
}
// LinkedIn Post
if (postData.platforms.includes('linkedin')) {
results.linkedin = await postToLinkedIn({
authorUrn: postData.linkedinAuthorUrn,
text: postData.message,
contentUrl: postData.link
});
}
// Instagram Post
if (postData.platforms.includes('instagram')) {
results.instagram = await postToInstagram({
igAccountId: postData.igAccountId,
imageUrl: postData.photo,
caption: postData.message
});
}
return results;
};
// Facebook posting
const postToFacebook = async (postData) => {
const token = await getFacebookPageToken(postData.pageId);
const params = new URLSearchParams({
message: postData.message,
access_token: token
});
if (postData.link) {
params.append('link', postData.link);
}
if (postData.photo) {
params.append('photo', postData.photo);
}
const response = await fetch(
`https://graph.facebook.com/v18.0/${postData.pageId}/feed?${params.toString()}`,
{ method: 'POST' }
);
return response.json();
};
// Twitter posting
const postToTwitter = async (postData) => {
const token = await getTwitterToken();
let mediaIds = [];
if (postData.media) {
// Upload media first
const mediaUpload = await uploadTwitterMedia(postData.media, token);
mediaIds = [mediaUpload.media_id_string];
}
const response = await fetch('https://api.twitter.com/2/tweets', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: postData.text,
media: mediaIds.length > 0 ? { media_ids: mediaIds } : undefined
})
});
return response.json();
};
// LinkedIn posting
const postToLinkedIn = async (postData) => {
const token = await getLinkedInToken();
const post = {
author: postData.authorUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: {
text: postData.text
},
shareMediaCategory: postData.contentUrl ? 'ARTICLE' : 'NONE',
media: postData.contentUrl ? [{
status: 'READY',
media: postData.contentUrn,
description: { text: postData.text }
}] : []
}
},
visibility: {
'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
}
};
const response = await fetch('https://api.linkedin.com/v2/ugcPosts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'X-Restli-Protocol-Version': '2.0.0'
},
body: JSON.stringify(post)
});
return response.json();
};
// Instagram posting
const postToInstagram = async (postData) => {
const token = await getInstagramToken();
// Step 1: Create media container
const containerResponse = await fetch(
`https://graph.facebook.com/v18.0/${postData.igAccountId}/media`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({
image_url: postData.imageUrl,
caption: postData.caption
})
}
);
const container = await containerResponse.json();
// Step 2: Publish
const publishResponse = await fetch(
`https://graph.facebook.com/v18.0/${postData.igAccountId}/media_publish`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({ creation_id: container.id })
}
);
return publishResponse.json();
};
การตั้งเวลาโพสต์
บันทึกโพสต์ลงฐานข้อมูลและใช้ job queue เพื่อเผยแพร่:
const schedulePost = async (postData, scheduledTime) => {
// Store in database for later execution
const scheduledPost = await db.scheduledPosts.create({
message: postData.message,
platforms: postData.platforms,
scheduledTime: scheduledTime,
status: 'pending',
media: postData.media,
link: postData.link
});
// Set up job queue
await jobQueue.add('publish-social-post', {
postId: scheduledPost.id
}, {
delay: scheduledTime - Date.now()
});
return scheduledPost;
};
// Job processor
jobQueue.process('publish-social-post', async (job) => {
const post = await db.scheduledPosts.findById(job.data.postId);
try {
const result = await createSocialPost(post);
await db.scheduledPosts.update(post.id, {
status: 'published',
publishedAt: new Date(),
results: result
});
return result;
} catch (error) {
await db.scheduledPosts.update(post.id, {
status: 'failed',
error: error.message
});
throw error;
}
});
การวิเคราะห์และรายงาน
การดึงข้อมูลวิเคราะห์ข้ามแพลตฟอร์ม
รวบรวมข้อมูลวิเคราะห์จากแต่ละแพลตฟอร์มแล้วรวมผลลัพธ์:
const getSocialAnalytics = async (accountId, dateRange) => {
const analytics = {
facebook: await getFacebookAnalytics(accountId.facebook, dateRange),
twitter: await getTwitterAnalytics(accountId.twitter, dateRange),
linkedin: await getLinkedInAnalytics(accountId.linkedin, dateRange),
instagram: await getInstagramAnalytics(accountId.instagram, dateRange)
};
// Aggregate metrics
const totals = {
impressions: sum(analytics, 'impressions'),
engagement: sum(analytics, 'engagement'),
clicks: sum(analytics, 'clicks'),
shares: sum(analytics, 'shares'),
comments: sum(analytics, 'comments'),
newFollowers: sum(analytics, 'newFollowers')
};
return { analytics, totals };
};
// Facebook Insights
const getFacebookAnalytics = async (pageId, dateRange) => {
const token = await getFacebookPageToken(pageId);
const metrics = [
'page_impressions_unique',
'page_engaged_users',
'page_post_engagements',
'page_clicks',
'page_fan_adds'
];
const params = new URLSearchParams({
metric: metrics.join(','),
since: dateRange.from,
until: dateRange.until,
access_token: token
});
const response = await fetch(
`https://graph.facebook.com/v18.0/${pageId}/insights?${params.toString()}`
);
return response.json();
};
// Twitter Analytics
const getTwitterAnalytics = async (userId, dateRange) => {
const token = await getTwitterToken();
const response = await fetch(
`https://api.twitter.com/2/users/${userId}/metrics/private`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
};
// LinkedIn Analytics
const getLinkedInAnalytics = async (organizationId, dateRange) => {
const token = await getLinkedInToken();
const response = await fetch(
`https://api.linkedin.com/v2/organizationalEntityFollowerStatistics?q=organizationalEntity&organizationalEntity=${organizationId}`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
};
// Instagram Insights
const getInstagramAnalytics = async (igAccountId, dateRange) => {
const token = await getInstagramToken();
const metrics = [
'impressions',
'reach',
'engagement',
'profile_views',
'follower_count'
];
const params = new URLSearchParams({
metric: metrics.join(','),
period: 'day',
since: dateRange.from,
until: dateRange.until
});
const response = await fetch(
`https://graph.facebook.com/v18.0/${igAccountId}/insights?${params.toString()}`,
{
headers: { 'Authorization': `Bearer ${token}` }
}
);
return response.json();
};
function sum(analytics, metric) {
return Object.values(analytics).reduce((total, platform) => {
return total + (platform.data?.[metric] || 0);
}, 0);
}
การจัดการทีม
การควบคุมการเข้าถึงตามบทบาท (Role-Based Access Control)
กำหนด Role และ Permission สำหรับแต่ละสมาชิกในทีม:
const TEAM_ROLES = {
ADMIN: 'admin',
MANAGER: 'manager',
CONTRIBUTOR: 'contributor',
VIEWER: 'viewer'
};
const ROLE_PERMISSIONS = {
[TEAM_ROLES.ADMIN]: ['create', 'read', 'update', 'delete', 'manage_team', 'billing'],
[TEAM_ROLES.MANAGER]: ['create', 'read', 'update', 'approve_posts'],
[TEAM_ROLES.CONTRIBUTOR]: ['create', 'read'],
[TEAM_ROLES.VIEWER]: ['read']
};
const checkPermission = (userRole, requiredPermission) => {
const permissions = ROLE_PERMISSIONS[userRole] || [];
return permissions.includes(requiredPermission);
};
การจำกัดอัตราการเรียกใช้งาน (Rate Limiting)
การจำกัดอัตราการเรียกใช้งานของแต่ละแพลตฟอร์ม
| แพลตฟอร์ม | ขีดจำกัด | ช่วงเวลา |
|---|---|---|
| Facebook Graph | 200 ครั้ง | ต่อชั่วโมงต่อผู้ใช้ |
| Twitter API v2 | 300 ทวีต | ต่อ 15 นาที |
| 100-500 ครั้ง | ต่อวัน | |
| 200 ครั้ง | ต่อชั่วโมง |
การใช้งานการจัดการการจำกัดอัตราการเรียกใช้งาน
สร้าง Rate Limiter สำหรับแต่ละแพลตฟอร์ม:
class SocialMediaRateLimiter {
constructor() {
this.limits = {
facebook: { limit: 200, window: 3600000 },
twitter: { limit: 300, window: 900000 },
linkedin: { limit: 500, window: 86400000 },
instagram: { limit: 200, window: 3600000 }
};
this.counters = {};
}
async request(platform, endpoint, options) {
await this.waitForCapacity(platform);
const response = await fetch(endpoint, options);
this.incrementCounter(platform);
return response;
}
async waitForCapacity(platform) {
const limit = this.limits[platform];
const counter = this.counters[platform] || { count: 0, resetTime: Date.now() };
if (Date.now() > counter.resetTime + limit.window) {
counter.count = 0;
counter.resetTime = Date.now();
}
if (counter.count >= limit.limit) {
const waitTime = counter.resetTime + limit.window - Date.now();
await new Promise(resolve => setTimeout(resolve, waitTime));
}
this.counters[platform] = counter;
}
incrementCounter(platform) {
if (!this.counters[platform]) {
this.counters[platform] = { count: 0, resetTime: Date.now() };
}
this.counters[platform].count++;
}
}
รายการตรวจสอบการปรับใช้งานจริง
ก่อนใช้งานจริง ตรวจสอบให้แน่ใจว่าได้ดำเนินการดังนี้:
- [ ] ใช้งาน OAuth 2.0 สำหรับทุกแพลตฟอร์ม
- [ ] จัดเก็บโทเค็นอย่างปลอดภัยด้วยการเข้ารหัส
- [ ] ตั้งค่าการรีเฟรชโทเค็นอัตโนมัติ
- [ ] ใช้งานการจำกัดอัตราการเรียกใช้งานของแต่ละแพลตฟอร์ม
- [ ] เพิ่มการจัดการข้อผิดพลาดที่ครอบคลุม
- [ ] ตั้งค่าการบันทึก (logging) สำหรับการเรียกใช้ API ทั้งหมด
- [ ] สร้างขั้นตอนการอนุมัติโพสต์
- [ ] ใช้งานการดูแลเนื้อหา (content moderation)
- [ ] ตั้งค่าการรวมข้อมูลวิเคราะห์
- [ ] สร้างกลไกการโพสต์สำรอง
กรณีศึกษาจริง
แดชบอร์ดโซเชียลมีเดีย
เอเจนซี่การตลาดสร้างแดชบอร์ดรวม:
- ความท้าทาย: การจัดการบัญชีลูกค้ากว่า 50 บัญชีในหลายแพลตฟอร์ม
- โซลูชั่น: แดชบอร์ดกลางพร้อมการโพสต์ข้ามแพลตฟอร์ม
- ผลลัพธ์: ประหยัดเวลาได้ 60%, การแสดงตนของแบรนด์ที่สอดคล้องกัน
การเผยแพร่เนื้อหาอัตโนมัติ
ผู้เผยแพร่ข่าวสารทำให้การแชร์บทความเป็นไปโดยอัตโนมัติ:
- ความท้าทาย: การแชร์เนื้อหาใหม่ด้วยตนเอง
- โซลูชั่น: โพสต์บทความใหม่ทั้งหมดไปยังทุกแพลตฟอร์มโดยอัตโนมัติ
- ผลลัพธ์: การเผยแพร่ทันที, การเข้าชมจากโซเชียลเพิ่มขึ้น 3 เท่า
บทสรุป
แม้ว่า Public API ของ Hootsuite จะถูกยกเลิกไปแล้ว แต่ Native Platform APIs ยังคงมอบความสามารถในการจัดการโซเชียลมีเดียที่ครอบคลุม ประเด็นสำคัญที่ควรทราบ:
- ใช้งาน OAuth 2.0 แยกกันสำหรับแต่ละแพลตฟอร์ม
- ข้อจำกัดอัตราการเรียกใช้งานแตกต่างกันอย่างมากในแต่ละแพลตฟอร์ม
- การโพสต์แบบรวมศูนย์ต้องใช้การใช้งานเฉพาะแพลตฟอร์ม
- การรวมข้อมูลวิเคราะห์ให้ข้อมูลเชิงลึกข้ามแพลตฟอร์ม
- Apidog ช่วยให้การทดสอบ API และการทำงานร่วมกันเป็นทีมมีประสิทธิภาพยิ่งขึ้น
คำถามที่พบบ่อย
Hootsuite ยังมี API อยู่หรือไม่?
Hootsuite ได้ยกเลิก Public API ของตนเองในปี 2024 คุณควรใช้ Native Platform APIs หรือแพลตฟอร์มจัดการอื่น ๆ เช่น Buffer, Sprout Social หรือ Agorapulse แทน
ฉันจะโพสต์ไปยังหลายแพลตฟอร์มพร้อมกันได้อย่างไร?
ใช้งาน OAuth สำหรับแต่ละแพลตฟอร์ม และสร้างฟังก์ชันการโพสต์แบบรวมศูนย์ที่เรียกใช้ API ของแต่ละแพลตฟอร์มพร้อมกัน
ข้อจำกัดอัตราการเรียกใช้งานสำหรับ API โซเชียลมีเดียคืออะไร?
ข้อจำกัดแตกต่างกันไป: Facebook (200/ชั่วโมง), Twitter (300/15 นาที), LinkedIn (100-500/วัน), Instagram (200/ชั่วโมง)
ฉันจะตั้งเวลาโพสต์ได้อย่างไร?
จัดเก็บโพสต์ไว้ในฐานข้อมูลพร้อม scheduled_time จากนั้นใช้คิวงาน (เช่น Bull, Agenda) เพื่อเผยแพร่ตามเวลาที่กำหนด
ฉันสามารถรับข้อมูลวิเคราะห์จากทุกแพลตฟอร์มได้หรือไม่?
ได้ แต่ละแพลตฟอร์มมี API สำหรับข้อมูลวิเคราะห์ รวบรวมข้อมูลเพื่อจัดทำรายงานข้ามแพลตฟอร์ม
Top comments (0)