Media

SocFlow 미디어 서버를 통해 이미지, 비디오 등의 파일을 업로드하고 관리할 수 있습니다. 업로드된 미디어는 고유한 ID와 URL을 받으며, 게시물 작성 시 사용할 수 있습니다.

미디어는 안전한 클라우드 스토리지에 저장되며, CDN을 통해 빠르게 전송됩니다. 이미지는 자동으로 최적화되고 리사이징됩니다.


POST/v1/media

미디어 업로드

파일을 SocFlow 미디어 서버에 업로드합니다. multipart/form-data 형식으로 파일을 전송해야 합니다.

요청 필드

  • Name
    file
    Type
    File
    Description

    필수. 업로드할 파일. 이미지, 비디오, 오디오 등 다양한 형식 지원.

  • Name
    title
    Type
    string
    Description

    (선택) 파일 제목. 제공하지 않으면 파일명이 사용됩니다.

  • Name
    description
    Type
    string
    Description

    (선택) 파일 설명. 제공하지 않으면 제목과 동일하게 설정됩니다.

지원 파일 형식

  • 이미지: JPG, PNG, GIF, WebP
  • 비디오: MP4, MOV, WebM
  • 기타: PDF, ZIP 등

요청

POST
/v1/media
curl --location 'https://api.socflow.app/api/v1/media' \
--header 'X-Secret-Token: {YOUR_API_KEY}' \
--form 'file=@"/path/to/image.jpg"' \
--form 'title="My Image"' \
--form 'description="Sample image description"'

응답

201
Created
{
  "success": true,
  "message": "Media asset created successfully",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "object_key": "550e8400-e29b-41d4-a716-446655440000.jpg",
    "content_type": "image/jpeg",
    "size_bytes": 245678,
    "title": "My Image",
    "alt_text": "Sample image description",
    "version": 1,
    "created_at": 1704067200000,
    "code": 200
  }
}

GET/v1/media/:id

미디어 다운로드

업로드된 미디어 파일을 다운로드합니다. 파일의 고유 ID를 사용하여 접근할 수 있습니다.

URL 파라미터

  • Name
    id
    Type
    string
    Description

    필수. 미디어 파일의 고유 ID (UUID 형식)

조건부 요청 지원

이 엔드포인트는 HTTP 조건부 요청을 지원합니다:

  • If-None-Match: ETag 기반 캐시 검증 (304 Not Modified)
  • If-Modified-Since: 수정 시간 기반 캐시 검증
  • Range: 부분 다운로드 지원 (206 Partial Content)

요청

GET
/v1/media/:id
curl --location 'https://api.socflow.app/api/v1/media/550e8400-e29b-41d4-a716-446655440000' \
--output downloaded-file.jpg

응답 헤더

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 245678
ETag: "abc123def456"
Last-Modified: Mon, 01 Jan 2024 00:00:00 GMT
Content-Disposition: attachment; filename="550e8400-e29b-41d4-a716-446655440000"
Accept-Ranges: bytes

GET/v1/media/users/:id

미디어 목록 조회

특정 사용자가 업로드한 미디어 목록을 조회합니다. 페이지네이션과 필터링을 지원합니다.

URL 파라미터

  • Name
    user_id
    Type
    string
    Description

    필수. 조회할 사용자의 ID. 인증된 사용자 본인의 ID만 조회 가능합니다.

쿼리 파라미터

  • Name
    page
    Type
    number
    Description

    (선택) 페이지 번호. 기본값: 1

  • Name
    limit
    Type
    number
    Description

    (선택) 페이지당 항목 수. 기본값: 20, 최대값: 100

  • Name
    type
    Type
    string
    Description

    (선택) 미디어 타입 필터. 가능한 값: image, video, audio

  • Name
    search
    Type
    string
    Description

    (선택) 제목 검색어

요청

GET
/v1/media/users/:id
curl --location 'https://api.socflow.app/api/v1/media/users/user_123?page=1&limit=20' \
--header 'X-Secret-Token: {YOUR_API_KEY}'

응답

200
OK
{
  "success": true,
  "data": {
    "result": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "object_key": "550e8400-e29b-41d4-a716-446655440000.jpg",
        "content_type": "image/jpeg",
        "size_bytes": 245678,
        "width": 1920,
        "height": 1080,
        "duration_ms": null,
        "title": "My Image",
        "alt_text": "Sample image",
        "tags_json": null,
        "metadata_json": null,
        "version": 1,
        "created_at": 1704067200000,
        "updated_at": 1704067200000,
        "download_url": "https://media.socflow.app/550e8400-e29b-41d4-a716-446655440000.jpg"
      }
    ],
    "usage": {
      "usage_size": 5234567890
    },
    "result_info": {
      "count": 20,
      "page": 1,
      "limit": 20,
      "total_count": 150,
      "total_pages": 8
    },
    "filters": {
      "type": "image"
    }
  }
}

DELETE/v1/media/:id

미디어 삭제

업로드한 미디어 파일을 삭제합니다. 본인이 업로드한 파일만 삭제할 수 있습니다.

URL 파라미터

  • Name
    id
    Type
    string
    Description

    필수. 삭제할 미디어 파일의 고유 ID (UUID 형식)

요청

DELETE
/v1/media/:id
curl --location --request DELETE 'https://api.socflow.app/api/v1/media/550e8400-e29b-41d4-a716-446655440000' \
--header 'X-Secret-Token: {YOUR_API_KEY}'

응답

200
OK
{
  "success": true,
  "message": "Media asset deleted successfully"
}

응답 필드

Media Asset 객체

  • Name
    id
    Type
    string
    Description

    미디어 파일의 고유 ID (UUID 형식)

  • Name
    object_key
    Type
    string
    Description

    스토리지에 저장된 파일의 키 (예: 550e8400-e29b-41d4-a716-446655440000.jpg)

  • Name
    content_type
    Type
    string
    Description

    파일의 MIME 타입 (예: image/jpeg, video/mp4)

  • Name
    size_bytes
    Type
    number
    Description

    파일 크기 (바이트)

  • Name
    width
    Type
    number | null
    Description

    (이미지/비디오) 가로 픽셀 수

  • Name
    height
    Type
    number | null
    Description

    (이미지/비디오) 세로 픽셀 수

  • Name
    duration_ms
    Type
    number | null
    Description

    (비디오/오디오) 재생 시간 (밀리초)

  • Name
    title
    Type
    string
    Description

    파일 제목

  • Name
    alt_text
    Type
    string
    Description

    파일 설명 (대체 텍스트)

  • Name
    tags_json
    Type
    string | null
    Description

    태그 정보 (JSON 문자열)

  • Name
    metadata_json
    Type
    string | null
    Description

    추가 메타데이터 (JSON 문자열)

  • Name
    version
    Type
    number
    Description

    파일 버전

  • Name
    created_at
    Type
    number
    Description

    생성 시각 (Unix timestamp, milliseconds)

  • Name
    updated_at
    Type
    number
    Description

    수정 시각 (Unix timestamp, milliseconds)

  • Name
    download_url
    Type
    string
    Description

    파일 다운로드 URL (목록 조회 시에만 포함)

Usage 객체

  • Name
    usage_size
    Type
    number
    Description

    사용자가 사용 중인 총 스토리지 용량 (바이트)

Result Info 객체

  • Name
    count
    Type
    number
    Description

    현재 페이지의 항목 수

  • Name
    page
    Type
    number
    Description

    현재 페이지 번호

  • Name
    limit
    Type
    number
    Description

    페이지당 최대 항목 수

  • Name
    total_count
    Type
    number
    Description

    전체 항목 수

  • Name
    total_pages
    Type
    number
    Description

    전체 페이지 수


사용 예시

이미지 갤러리 구현

async function createImageGallery() {
  const userId = 'user_123'

  // 이미지만 가져오기
  const response = await fetch(
    `https://api.socflow.app/api/v1/media/users/${userId}?type=image&page=1&limit=50`,
    {
      headers: {
        'X-Secret-Token': process.env.SOCFLOW_API_KEY,
      },
    },
  )

  const result = await response.json()
  const images = result.data.result

  console.log(`총 ${result.data.result_info.total_count}개의 이미지`)

  images.forEach((image) => {
    console.log(`
      제목: ${image.title}
      크기: ${(image.size_bytes / 1024).toFixed(2)}KB
      해상도: ${image.width}x${image.height}
      URL: ${image.download_url}
    `)
  })
}

await createImageGallery()

파일 업로드 및 게시물 작성

async function uploadAndPost(file) {
  // 1. 파일 업로드
  const formData = new FormData()
  formData.append('file', file)
  formData.append('title', '내 게시물 이미지')

  const uploadResponse = await fetch('https://api.socflow.app/api/v1/media', {
    method: 'POST',
    headers: {
      'X-Secret-Token': process.env.SOCFLOW_API_KEY,
    },
    body: formData,
  })

  const uploadResult = await uploadResponse.json()
  const mediaId = uploadResult.data.id

  console.log(`업로드 완료: ${mediaId}`)

  // 2. 게시물 작성 (미디어 ID 사용)
  const postResponse = await fetch('https://api.socflow.app/api/v1/posts', {
    method: 'POST',
    headers: {
      'X-Secret-Token': process.env.SOCFLOW_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      account_id: 'acc_instagram_12345',
      content: '새로운 게시물입니다!',
      media_ids: [mediaId],
    }),
  })

  const postResult = await postResponse.json()
  console.log(`게시물 작성 완료: ${postResult.data.id}`)
}

스토리지 용량 모니터링

async function monitorStorage(userId) {
  const response = await fetch(
    `https://api.socflow.app/api/v1/media/users/${userId}?page=1&limit=1`,
    {
      headers: {
        'X-Secret-Token': process.env.SOCFLOW_API_KEY,
      },
    },
  )

  const result = await response.json()
  const usageBytes = result.data.usage.usage_size
  const usageMB = (usageBytes / 1024 / 1024).toFixed(2)
  const usageGB = (usageBytes / 1024 / 1024 / 1024).toFixed(2)

  console.log(`현재 사용량: ${usageMB}MB (${usageGB}GB)`)

  const limit = 10 * 1024 * 1024 * 1024 // 10GB
  const usagePercent = ((usageBytes / limit) * 100).toFixed(1)

  console.log(`사용률: ${usagePercent}%`)

  if (usageBytes > limit * 0.9) {
    console.warn('⚠️ 경고: 스토리지 용량이 90% 이상 사용되었습니다!')
  }
}

await monitorStorage('user_123')

Was this page helpful?