Blog

Instagram Comment Moderation API: Automatisiere deine Kommentare

Lerne, wie du Instagram-Kommentare mit der Graph API automatisierst. Erstelle Moderationssysteme, antworte programmatisch und verwalte Kommentare im großen Maßstab mit TypeScript.

Von

+8

Überall posten. Eine API.

Try Free

Das Verwalten von Kommentaren über mehrere Instagram-Posts hinweg wird überwältigend, wenn dein Publikum wächst. Instagram-Kommentarmoderation über die Graph API ermöglicht es dir, automatisierte Systeme zu erstellen, die Kommentare programmatisch abrufen, filtern, beantworten und moderieren. Diese Anleitung führt dich durch die Implementierung einer vollständigen Kommentarverwaltungslösung mit TypeScript.

Ob du ein Social-Media-Dashboard, ein Kundensupport-Tool oder ein automatisiertes Engagement-System erstellst – das Verständnis der Instagram Comment API ist essentiell. Wir behandeln alles von der grundlegenden Authentifizierung bis hin zu fortgeschrittenen Moderations-Workflows mit Sentiment-Analyse.

API-Zugriffsanforderungen

Bevor du Instagram-Kommentare automatisieren kannst, benötigst du einen ordnungsgemäß konfigurierten API-Zugang. Die Instagram Graph API erfordert ein Facebook-Entwicklerkonto und eine genehmigte App mit spezifischen Berechtigungen.

Erforderliche Berechtigungen

Deine App benötigt diese OAuth-Scopes, um mit Kommentaren zu arbeiten:

const INSTAGRAM_SCOPES = [
  'instagram_business_basic',           // Basic account access
  'instagram_business_content_publish', // Publish content
  'instagram_business_manage_comments', // Read and manage comments
  'instagram_business_manage_messages', // Required for private replies
];

Umgebungseinrichtung

Erstelle eine .env-Datei mit deinen Anmeldedaten:

INSTAGRAM_CLIENT_ID=your_client_id
INSTAGRAM_CLIENT_SECRET=your_client_secret
INSTAGRAM_ACCESS_TOKEN=your_long_lived_token
INSTAGRAM_USER_ID=your_business_account_id

Token-Austausch-Implementierung

Instagram-Tokens beginnen als kurzlebige Tokens (1 Stunde) und müssen gegen langlebige Tokens (60 Tage) ausgetauscht werden:

interface TokenResponse {
  access_token: string;
  token_type: string;
  expires_in: number;
}

async function exchangeForLongLivedToken(
  shortLivedToken: string,
  clientSecret: string
): Promise<TokenResponse> {
  const baseUrl = 'https://graph.instagram.com';
  
  const response = await fetch(
    `${baseUrl}/access_token?` +
    `grant_type=ig_exchange_token&` +
    `client_secret=${clientSecret}&` +
    `access_token=${shortLivedToken}`,
    { method: 'GET' }
  );

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Token exchange failed: ${response.status} - ${errorText}`);
  }

  return response.json();
}

async function refreshLongLivedToken(
  currentToken: string
): Promise<TokenResponse> {
  const baseUrl = 'https://graph.instagram.com';
  
  const response = await fetch(
    `${baseUrl}/refresh_access_token?` +
    `grant_type=ig_refresh_token&` +
    `access_token=${currentToken}`,
    { method: 'GET' }
  );

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Token refresh failed: ${response.status} - ${errorText}`);
  }

  return response.json();
}

Hinweis: Langlebige Tokens müssen vor ihrem Ablauf aktualisiert werden. Richte einen Cron-Job ein, um Tokens mindestens 7 Tage vor Ablauf zu aktualisieren.

Kommentare von Posts abrufen

Die Grundlage jedes Instagram-Kommentarmoderation-Systems ist das effiziente Abrufen von Kommentaren. Die API unterstützt Paginierung für die Verarbeitung von Posts mit Tausenden von Kommentaren.

Grundlegendes Abrufen von Kommentaren

interface InstagramUser {
  id: string;
  username: string;
}

interface InstagramComment {
  commentId: string;
  comment: string;
  created: string;
  from: InstagramUser;
  likeCount: number;
  replyCount: number;
  hidden: boolean;
  platform: 'instagram';
  replies: InstagramComment[];
}

interface CommentResponse {
  comments: InstagramComment[];
  pagination: {
    hasMore: boolean;
    cursor?: string;
  };
}

async function getMediaComments(
  accessToken: string,
  mediaId: string,
  options?: { limit?: number; cursor?: string }
): Promise<CommentResponse> {
  const baseUrl = 'https://graph.instagram.com';
  const limit = Math.min(options?.limit || 25, 50);
  
  let url = `${baseUrl}/${mediaId}/comments?` +
    `fields=id,text,timestamp,username,hidden,` +
    `from{id,username},like_count,` +
    `replies{id,text,timestamp,username,hidden,from{id,username},like_count}&` +
    `limit=${limit}&access_token=${accessToken}`;

  if (options?.cursor) {
    url += `&after=${options.cursor}`;
  }

  const response = await fetch(url);
  
  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Failed to fetch comments: ${response.status} - ${errorText}`);
  }

  const data = await response.json();

  // Build lookup map for complete comment data
  const commentDataById = new Map<string, any>();
  (data.data || []).forEach((comment: any) => {
    commentDataById.set(comment.id, comment);
  });

  // Identify reply IDs to filter from top-level
  const allReplyIds = new Set<string>();
  (data.data || []).forEach((comment: any) => {
    (comment.replies?.data || []).forEach((reply: any) => {
      allReplyIds.add(reply.id);
    });
  });

  // Filter to only top-level comments
  const topLevelComments = (data.data || [])
    .filter((comment: any) => !allReplyIds.has(comment.id));

  const comments: InstagramComment[] = topLevelComments.map((comment: any) => ({
    commentId: comment.id,
    comment: comment.text,
    created: comment.timestamp,
    from: {
      id: comment.from?.id,
      username: comment.from?.username || comment.username,
    },
    likeCount: comment.like_count || 0,
    replyCount: comment.replies?.data?.length || 0,
    hidden: comment.hidden || false,
    platform: 'instagram',
    replies: (comment.replies?.data || []).map((reply: any) => {
      const fullReplyData = commentDataById.get(reply.id) || reply;
      return {
        commentId: reply.id,
        comment: fullReplyData.text || reply.text,
        created: fullReplyData.timestamp || reply.timestamp,
        from: {
          id: fullReplyData.from?.id || reply.from?.id,
          username: fullReplyData.from?.username || reply.from?.username,
        },
        likeCount: fullReplyData.like_count || reply.like_count || 0,
        hidden: fullReplyData.hidden || false,
        platform: 'instagram',
        replies: [],
        replyCount: 0,
      };
    }),
  }));

  return {
    comments,
    pagination: {
      hasMore: !!data.paging?.next,
      cursor: data.paging?.cursors?.after,
    },
  };
}

Alle Kommentare mit Paginierung abrufen

Für Posts mit vielen Kommentaren implementiere Paginierung, um alles abzurufen:

async function getAllComments(
  accessToken: string,
  mediaId: string,
  maxComments: number = 1000
): Promise<InstagramComment[]> {
  const allComments: InstagramComment[] = [];
  let cursor: string | undefined;
  
  while (allComments.length < maxComments) {
    const response = await getMediaComments(accessToken, mediaId, {
      limit: 50,
      cursor,
    });
    
    allComments.push(...response.comments);
    
    if (!response.pagination.hasMore || !response.pagination.cursor) {
      break;
    }
    
    cursor = response.pagination.cursor;
    
    // Rate limiting: wait between requests
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return allComments.slice(0, maxComments);
}

Build faster with Late

One API call to post everywhere. No OAuth headaches. No platform-specific code.

Free tier • No credit card • 99.97% uptime

Programmatisch auf Kommentare antworten

Die Möglichkeit, programmatisch über die Instagram Comments API zu antworten, ermöglicht automatisiertes Engagement, Kundensupport-Bots und skaliertes Community-Management.

Implementierung öffentlicher Antworten

interface ReplyResult {
  replyId: string;
  success: boolean;
  error?: string;
}

async function replyToComment(
  accessToken: string,
  commentId: string,
  message: string
): Promise<ReplyResult> {
  const baseUrl = 'https://graph.instagram.com';
  
  try {
    const response = await fetch(
      `${baseUrl}/${commentId}/replies`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message,
          access_token: accessToken,
        }),
      }
    );

    if (!response.ok) {
      const errorText = await response.text();
      return {
        replyId: '',
        success: false,
        error: `Reply failed: ${response.status} - ${errorText}`,
      };
    }

    const data = await response.json();
    return {
      replyId: data.id,
      success: true,
    };
  } catch (error) {
    return {
      replyId: '',
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    };
  }
}

Private Antwort (Direktnachricht)

Instagram ermöglicht das Senden einer privaten DM an Kommentarautoren. Dies ist nützlich für Kundensupport-Szenarien:

interface PrivateReplyResult {
  messageId: string;
  success: boolean;
  error?: string;
}

async function sendPrivateReply(
  accessToken: string,
  igUserId: string,
  commentId: string,
  message: string
): Promise<PrivateReplyResult> {
  const baseUrl = 'https://graph.instagram.com';
  
  try {
    const response = await fetch(
      `${baseUrl}/${igUserId}/messages`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${accessToken}`,
        },
        body: JSON.stringify({
          recipient: {
            comment_id: commentId,
          },
          message: {
            text: message,
          },
        }),
      }
    );

    if (!response.ok) {
      const errorText = await response.text();
      
      // Handle specific error cases
      if (errorText.includes('551') || errorText.toLowerCase().includes('already')) {
        return {
          messageId: '',
          success: false,
          error: 'A private reply has already been sent to this comment. Instagram only allows one private reply per comment.',
        };
      }
      
      if (errorText.includes('10903')) {
        return {
          messageId: '',
          success: false,
          error: 'Comment is older than 7 days. Private replies must be sent within 7 days.',
        };
      }
      
      return {
        messageId: '',
        success: false,
        error: `Private reply failed: ${response.status} - ${errorText}`,
      };
    }

    const data = await response.json();
    return {
      messageId: data.message_id || data.id,
      success: true,
    };
  } catch (error) {
    return {
      messageId: '',
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    };
  }
}

Hinweis: Instagram erlaubt nur EINE private Antwort pro Kommentar, und sie muss innerhalb von 7 Tagen nach dem Posten des Kommentars gesendet werden. Plane deine Automatisierung entsprechend.

Kommentare ausblenden und löschen

Effektive Instagram-Kommentarmoderation erfordert die Möglichkeit, unangemessene Kommentare auszublenden oder eigene Antworten zu löschen.

Kommentare ein- und ausblenden

async function hideComment(
  accessToken: string,
  commentId: string
): Promise<{ success: boolean; error?: string }> {
  const baseUrl = 'https://graph.instagram.com';
  
  try {
    const response = await fetch(
      `${baseUrl}/${commentId}?hide=true&access_token=${accessToken}`,
      { method: 'POST' }
    );

    if (!response.ok) {
      const errorText = await response.text();
      return {
        success: false,
        error: `Hide failed: ${response.status} - ${errorText}`,
      };
    }

    return { success: true };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    };
  }
}

async function unhideComment(
  accessToken: string,
  commentId: string
): Promise<{ success: boolean; error?: string }> {
  const baseUrl = 'https://graph.instagram.com';
  
  try {
    const response = await fetch(
      `${baseUrl}/${commentId}?hide=false&access_token=${accessToken}`,
      { method: 'POST' }
    );

    if (!response.ok) {
      const errorText = await response.text();
      return {
        success: false,
        error: `Unhide failed: ${response.status} - ${errorText}`,
      };
    }

    return { success: true };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    };
  }
}

Kommentare löschen

Du kannst nur Kommentare löschen, die du selbst verfasst hast (deine eigenen Antworten):

async function deleteComment(
  accessToken: string,
  commentId: string
): Promise<{ success: boolean; error?: string }> {
  const baseUrl = 'https://graph.instagram.com';
  
  try {
    const response = await fetch(
      `${baseUrl}/${commentId}?access_token=${accessToken}`,
      { method: 'DELETE' }
    );

    if (!response.ok) {
      const errorText = await response.text();
      return {
        success: false,
        error: `Delete failed: ${response.status} - ${errorText}`,
      };
    }

    return { success: true };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error',
    };
  }
}

Kommentarfilterung und Moderationsregeln

Der Aufbau eines automatisierten Moderationssystems erfordert die Definition von Regeln dafür, welche Inhalte markiert, ausgeblendet oder beantwortet werden sollen.

Moderationsregel-Engine

interface ModerationRule {
  id: string;
  name: string;
  type: 'keyword' | 'regex' | 'sentiment' | 'spam';
  pattern?: string;
  keywords?: string[];
  action: 'hide' | 'flag' | 'delete' | 'reply';
  replyTemplate?: string;
  enabled: boolean;
}

interface ModerationResult {
  commentId: string;
  triggered: boolean;
  matchedRules: string[];
  action: 'hide' | 'flag' | 'delete' | 'reply' | 'none';
  replyMessage?: string;
}

class CommentModerator {
  private rules: ModerationRule[];

  constructor(rules: ModerationRule[]) {
    this.rules = rules.filter(r => r.enabled);
  }

  evaluate(comment: InstagramComment): ModerationResult {
    const matchedRules: string[]

Eine API. 13+ Plattformen.

Social Media Features in Minuten integrieren, nicht Wochen.

Für Entwickler gemacht. Von Agenturen geschätzt. Von 6.325 Nutzern vertraut.