o2o-castad-backend/poc/instagram1-difi/README.md

5.3 KiB

Instagram Graph API POC

Instagram Graph API를 활용한 비즈니스/크리에이터 계정 관리 POC입니다.

기능

  • 인증: 토큰 검증, 장기 토큰 교환, 토큰 갱신
  • 계정: 프로필 정보 조회
  • 미디어: 목록/상세 조회, 이미지/비디오/캐러셀 게시
  • 인사이트: 계정/미디어 성과 지표 조회
  • 댓글: 댓글 조회, 답글 작성

요구사항

1. Instagram 비즈니스/크리에이터 계정

개인 계정은 지원하지 않습니다. Instagram 앱에서 비즈니스 또는 크리에이터 계정으로 전환해야 합니다.

2. Facebook 앱 설정

  1. Meta for Developers에서 앱 생성
  2. Instagram Graph API 제품 추가
  3. 필요한 권한 설정:
    • instagram_basic - 기본 프로필 정보
    • instagram_content_publish - 콘텐츠 게시
    • instagram_manage_comments - 댓글 관리
    • instagram_manage_insights - 인사이트 조회

3. 액세스 토큰 발급

Graph API Explorer 또는 OAuth 흐름을 통해 액세스 토큰을 발급받습니다.

설치

# 프로젝트 루트에서
uv add httpx pydantic-settings

환경변수 설정

.env 파일 또는 환경변수로 설정:

# 필수
export INSTAGRAM_ACCESS_TOKEN="your_access_token"

# 토큰 검증/교환 시 필요
export INSTAGRAM_APP_ID="your_app_id"
export INSTAGRAM_APP_SECRET="your_app_secret"

사용법

기본 사용

import asyncio
from poc.instagram1 import InstagramGraphClient

async def main():
    async with InstagramGraphClient() as client:
        # 계정 정보 조회
        account = await client.get_account()
        print(f"@{account.username}: {account.followers_count} followers")

        # 미디어 목록 조회
        media_list = await client.get_media_list(limit=10)
        for media in media_list.data:
            print(f"{media.media_type}: {media.like_count} likes")

asyncio.run(main())

토큰 검증

async with InstagramGraphClient() as client:
    token_info = await client.debug_token()
    print(f"Valid: {token_info.data.is_valid}")
    print(f"Expires: {token_info.data.expires_at_datetime}")

이미지 게시

async with InstagramGraphClient() as client:
    media = await client.publish_image(
        image_url="https://example.com/image.jpg",
        caption="My photo! #photography",
    )
    print(f"Posted: {media.permalink}")

인사이트 조회

async with InstagramGraphClient() as client:
    # 계정 인사이트
    insights = await client.get_account_insights(
        metrics=["impressions", "reach"],
        period="day",
    )
    for insight in insights.data:
        print(f"{insight.name}: {insight.latest_value}")

    # 미디어 인사이트
    media_insights = await client.get_media_insights("MEDIA_ID")
    reach = media_insights.get_metric("reach")
    print(f"Reach: {reach.latest_value}")

댓글 관리

async with InstagramGraphClient() as client:
    # 댓글 조회
    comments = await client.get_comments("MEDIA_ID")
    for comment in comments.data:
        print(f"@{comment.username}: {comment.text}")

    # 답글 작성
    reply = await client.reply_comment(
        comment_id="COMMENT_ID",
        message="Thanks!",
    )

예제 실행

# 인증 예제
python -m poc.instagram1.examples.auth_example

# 계정 예제
python -m poc.instagram1.examples.account_example

# 미디어 예제
python -m poc.instagram1.examples.media_example

# 인사이트 예제
python -m poc.instagram1.examples.insights_example

# 댓글 예제
python -m poc.instagram1.examples.comments_example

에러 처리

from poc.instagram1 import (
    InstagramGraphClient,
    AuthenticationError,
    RateLimitError,
    InstagramPermissionError,
    MediaPublishError,
)

async with InstagramGraphClient() as client:
    try:
        account = await client.get_account()
    except AuthenticationError as e:
        print(f"토큰 오류: {e}")
    except RateLimitError as e:
        print(f"Rate limit 초과. {e.retry_after}초 후 재시도")
    except InstagramPermissionError as e:
        print(f"권한 부족: {e}")

Rate Limit

  • 시간당 200회 요청 제한 (사용자 토큰당)
  • 429 응답 시 자동으로 지수 백오프 재시도
  • RateLimitError.retry_after로 대기 시간 확인 가능

파일 구조

poc/instagram1/
├── __init__.py          # 패키지 진입점
├── config.py            # 설정 (환경변수)
├── exceptions.py        # 커스텀 예외
├── models.py            # Pydantic 모델
├── client.py            # API 클라이언트
├── examples/            # 실행 예제
│   ├── auth_example.py
│   ├── account_example.py
│   ├── media_example.py
│   ├── insights_example.py
│   └── comments_example.py
├── DESIGN.md            # 설계 문서
└── README.md            # 사용 가이드 (본 문서)

참고 문서