본문 바로가기
솔로프리너

Telegraph, Telegram이 만든 미니멀 퍼블리싱 플랫폼

by AI동키 2026. 2. 10.
반응형

Telegraph (telegra.ph) - Knowledge Base

Telegram이 만든 미니멀 퍼블리싱 플랫폼. 익명으로 글을 작성하고, Telegram Instant View로 바로 열리는 깔끔한 페이지를 생성할 수 있다.

 


1. 개요

  • URL: https://telegra.ph
  • 운영: Telegram 팀
  • 목적: 빠르고 간단한 웹 글 발행 (블로그/아티클)
  • 계정 불필요: 브라우저에서 바로 글 작성 가능 (익명)
  • Instant View: Telegram 앱 내에서 외부 브라우저 없이 즉시 열림
  • 영구 저장: 한번 게시하면 URL이 영구적으로 유지됨. 공식 삭제 기능 없음
  • 대체 미러: graph.org (동일한 API, 동일한 서비스)

2. 지원 포맷 & 제한사항

2.1 허용되는 HTML 태그 (Allowed Tags)

a, aside, b, blockquote, br, code, em, figcaption, figure,
h3, h4, hr, i, iframe, img, li, ol, p, pre, s, strong, u, ul, video

2.2 지원되는 스타일링

기능 지원 여부

볼드 (<b>, <strong>)
이탤릭 (<i>, <em>)
<u>밑줄</u> (<u>)
~~취소선~~ (<s>)
링크 (<a href>)
헤딩 (<h3>, <h4>) ✅ (h3, h4만)
인용 (<blockquote>)
코드 블록 (<pre>, <code>)
리스트 (<ul>, <ol>, <li>)
수평선 (<hr>)
이미지 (<img>)
비디오/임베드 (<iframe>) ✅ (YouTube, Vimeo, Twitter)

2.3 지원하지 않는 것

  • 테이블 (<table>) - 완전 미지원
  • 커스텀 CSS - 폰트, 색상, 배경 등 변경 불가
  • 커스텀 글꼴 - 기본 serif 폰트 고정
  • 마크다운 - 에디터에서 직접 지원 안 함 (API 라이브러리로 변환은 가능)
  • h1, h2, h5, h6 헤딩
  • 글 삭제 - 공식 API에 삭제 메서드 없음

2.4 테이블 우회 방법

테이블이 필요할 경우:

  1. 이미지로 생성하여 삽입 (가장 현실적)
  2. 텍스트로 정렬하여 흉내 (가독성 떨어짐)
  3. 외부 플랫폼 사용 (Notion, GitHub Pages 등)

3. API 레퍼런스

  • Base URL: https://api.telegra.ph
  • 메서드: POST 요청
  • 인증: access_token 파라미터 (createAccount 제외)
  • 응답 형식: JSON ({ "ok": true, "result": {...} })

3.1 Account 메서드

createAccount

새 Telegraph 계정 생성. access_token 발급.

POST https://api.telegra.ph/createAccount

파라미터 필수 설명

short_name 계정 이름 (1-32자). 에디터 상단에 표시
author_name 기본 작성자 이름 (0-128자)
author_url 작성자 프로필 링크 (0-512자)

응답 예시:

{
  "ok": true,
  "result": {
    "short_name": "Ketday",
    "author_name": "캣데이",
    "author_url": "https://t.me/ketday",
    "access_token": "abc123...",
    "auth_url": "https://edit.telegra.ph/auth/..."
  }
}

editAccountInfo

계정 정보 수정.

POST https://api.telegra.ph/editAccountInfo

파라미터 필수 설명

access_token 액세스 토큰
short_name 새 계정 이름
author_name 새 작성자 이름
author_url 새 작성자 링크

getAccountInfo

계정 정보 조회.

POST https://api.telegra.ph/getAccountInfo

파라미터 필수 설명

access_token 액세스 토큰
fields 반환할 필드 목록. 기본: ["short_name", "author_name", "author_url"]. 추가 가능: auth_url, page_count

revokeAccessToken

access_token을 폐기하고 새로 발급. 세션 초기화 또는 토큰 유출 시 사용.

POST https://api.telegra.ph/revokeAccessToken

3.2 Page 메서드

createPage

새 페이지(글) 생성.

POST https://api.telegra.ph/createPage

파라미터 필수 설명

access_token 액세스 토큰
title 페이지 제목 (1-256자)
content Node 배열의 JSON 문자열 (최대 64KB)
author_name 작성자 이름 (0-128자)
author_url 작성자 프로필 링크
return_content true면 응답에 content 포함. 기본: false

응답 예시:

{
  "ok": true,
  "result": {
    "path": "Ketday-250210",
    "url": "https://telegra.ph/Ketday-250210",
    "title": "Ketday 데일리 브리핑",
    "description": "",
    "views": 0,
    "can_edit": true
  }
}

editPage

기존 페이지 수정. access_token이 해당 페이지의 소유자여야 함.

POST https://api.telegra.ph/editPage

파라미터 필수 설명

access_token 액세스 토큰
path 페이지 경로 (예: Ketday-250210)
title 페이지 제목
content 수정된 Node 배열 JSON
author_name 작성자 이름
author_url 작성자 링크
return_content 기본: false

getPage

페이지 정보 조회. access_token 불필요 (공개 정보).

POST https://api.telegra.ph/getPage/{path}

파라미터 필수 설명

path 페이지 경로
return_content true면 content 포함. 기본: false

getPageList

계정의 페이지 목록 조회. 최신순 정렬.

POST https://api.telegra.ph/getPageList

파라미터 필수 설명

access_token 액세스 토큰
offset 시작 위치. 기본: 0
limit 조회 수 (0-200). 기본: 50

getViews

페이지 조회수 확인.

POST https://api.telegra.ph/getViews/{path}

파라미터 필수 설명

path 페이지 경로
year 연도별 조회수 (month 사용 시 필수)
month 월별 조회수 (day 사용 시 필수)
day 일별 조회수 (hour 사용 시 필수)
hour 시간별 조회수 (0-24)

4. Content 포맷 (Node)

Telegraph API의 content는 Node 배열의 JSON 문자열이다. Node는 문자열(텍스트 노드)이거나 NodeElement 객체이다.

4.1 NodeElement 구조

{
  "tag": "태그명",
  "attrs": {
    "href": "URL",
    "src": "이미지/비디오 URL"
  },
  "children": ["텍스트 또는 다른 NodeElement"]
}
  • tag: 허용된 태그만 사용 가능 (섹션 2.1 참조)
  • attrs: href와 src만 지원
  • children: 자식 노드 배열 (문자열 또는 NodeElement)

4.2 Content 예시

[
  {
    "tag": "h3",
    "children": ["🐱 Ketday 데일리 마켓 브리핑"]
  },
  {
    "tag": "p",
    "children": [
      {
        "tag": "strong",
        "children": ["코스피"]
      },
      "는 전일 대비 1.2% 상승한 2,580선에서 마감했다냥."
    ]
  },
  {
    "tag": "blockquote",
    "children": ["핵심 포인트: 반도체 섹터가 강세를 보이며 지수 상승을 이끌었다냥."]
  },
  {
    "tag": "figure",
    "children": [
      {
        "tag": "img",
        "attrs": {
          "src": "https://example.com/chart.png"
        }
      },
      {
        "tag": "figcaption",
        "children": ["오늘의 섹터별 등락률"]
      }
    ]
  }
]

5. 이미지 업로드

5.1 업로드 엔드포인트 (비공식)

POST https://telegra.ph/upload
  • 비공식 API (공식 문서에 없음, USE AT YOUR OWN RISK)
  • 지원 포맷: jpg, jpeg, png, gif, mp4
  • 파일 크기 제한: 약 5-6MB
  • ⚠️ 주의: 2024년경 익명 업로드 악용으로 인해 새 미디어 업로드가 비활성화된 적 있음. 현재 상태 확인 필요

5.2 대안: 외부 이미지 호스팅

Telegraph 자체 업로드가 안 될 경우, 외부 호스팅 이미지 URL을 <img src="..."> 또는 <figure> 태그로 삽입 가능.

추천 이미지 호스팅:

  • GitHub raw (private repo for control)
  • Cloudflare R2 / AWS S3
  • ImgBB, Imgur 등 무료 호스팅

6. 라이브러리 & SDK

6.1 Python

pip install telegraph
from telegraph import Telegraph

# 계정 생성
telegraph = Telegraph()
telegraph.create_account(
    short_name='Ketday',
    author_name='캣데이',
    author_url='https://t.me/ketday'
)

# 페이지 생성 (Node 리스트)
response = telegraph.create_page(
    title='Ketday 데일리 마켓 브리핑',
    content=[
        {'tag': 'h3', 'children': ['📊 오늘의 시장 요약']},
        {'tag': 'p', 'children': ['코스피는 전일 대비 상승했다냥.']},
    ],
    author_name='캣데이',
    author_url='https://t.me/ketday'
)
print(response['url'])  # https://telegra.ph/Ketday-...

# 페이지 생성 (HTML 문자열) - python-telegraph v2.x
response = telegraph.create_page(
    title='Ketday 브리핑',
    html_content='

시장 요약

코스피 상승!

'
)

# 페이지 수정
telegraph.edit_page(
    path='Ketday-250210',
    title='수정된 제목',
    content=[{'tag': 'p', 'children': ['수정된 내용']}]
)

# 조회수 확인
views = telegraph.get_views('Ketday-250210', year=2025, month=2, day=10)

# 페이지 목록
pages = telegraph.get_page_list(offset=0, limit=50)

# 이미지 업로드 (비공식)
from telegraph.utils import FilesOpener
with FilesOpener(['chart.png']) as f:
    uploaded = telegraph.upload_file(f)
    # [{'src': '/file/abc123.jpg'}]
    image_url = f'https://telegra.ph{uploaded[0]["src"]}'

Python 라이브러리 비교:

패키지 버전 특징

telegraph (python273) 0.1.x 기본적, 심플
python-telegraph 2.2.x html_content 지원, graph.org 미러 지원, upload_file 포함
html-telegraph-poster 0.5.x HTML 직접 포스팅 특화, lxml 기반

6.2 Node.js

npm i telegra.ph
const Telegraph = require('telegra.ph')

// 기존 토큰으로 초기화
const client = new Telegraph(process.env.TELEGRAPH_TOKEN)

// 또는 새 계정 생성
const client = new Telegraph()
const account = await client.createAccount('Ketday', '캣데이', 'https://t.me/ketday')
client.token = account.access_token

// 페이지 생성
const page = await client.createPage('Ketday 브리핑', [
  { tag: 'h3', children: ['📊 시장 요약'] },
  { tag: 'p', children: ['코스피 상승!'] }
], '캣데이', 'https://t.me/ketday')
console.log(page.url)

// 페이지 목록
const pages = await client.getPageList(0, 50)

// 조회수
const views = await client.getViews('Ketday-250210', 2025, 2, 10)

Node.js 대안 라이브러리:

  • @dcdunkan/telegraph (Deno/JSR) - Markdown/HTML 파싱 내장, 최신 유지보수

7. GitHub Actions 자동화

7.1 워크플로우 구조

[Cron 스케줄] → [데이터 수집] → [AI 브리핑 생성] → [차트 이미지 생성]
                                                          ↓
                                              [Telegraph 페이지 발행]
                                                          ↓
                                              [Telegram 채널에 링크 전송]

7.2 GitHub Actions 예시

name: Ketday Daily Briefing
on:
  schedule:
    - cron: '0 23 * * 0-4'  # UTC 23:00 = KST 08:00 (월~금)
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: pip install telegraph requests matplotlib

      - name: Generate and publish briefing
        env:
          TELEGRAPH_TOKEN: ${{ secrets.TELEGRAPH_TOKEN }}
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHANNEL_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
        run: python scripts/daily_briefing.py

7.3 Python 스크립트 핵심 로직

import os
import json
import requests
from telegraph import Telegraph
from datetime import datetime

# 1. Telegraph 초기화
telegraph = Telegraph(access_token=os.environ['TELEGRAPH_TOKEN'])

# 2. 브리핑 콘텐츠 생성 (AI 또는 데이터 기반)
today = datetime.now().strftime('%Y년 %m월 %d일')
content = [
    {'tag': 'h3', 'children': [f'📊 {today} 시장 요약']},
    {'tag': 'p', 'children': ['...브리핑 내용...']},
    # 차트 이미지 삽입
    {'tag': 'figure', 'children': [
        {'tag': 'img', 'attrs': {'src': chart_url}},
        {'tag': 'figcaption', 'children': ['섹터별 등락률']}
    ]},
]

# 3. Telegraph 발행
page = telegraph.create_page(
    title=f'🐱 Ketday 마켓 브리핑 - {today}',
    content=content,
    author_name='캣데이',
    author_url='https://t.me/ketday'
)

# 4. Telegram 채널에 전송
bot_token = os.environ['TELEGRAM_BOT_TOKEN']
channel_id = os.environ['TELEGRAM_CHANNEL_ID']
message = f"🐱 오늘의 마켓 브리핑이다냥!\n\n{page['url']}"

requests.post(
    f'https://api.telegram.org/bot{bot_token}/sendMessage',
    json={
        'chat_id': channel_id,
        'text': message,
        'parse_mode': 'HTML'
    }
)

8. 주의사항 & 팁

8.1 access_token 관리

  • 절대 코드에 하드코딩하지 말 것 → GitHub Secrets 또는 환경변수 사용
  • access_token이 있으면 해당 계정의 모든 글 수정 가능
  • 토큰 유출 시 revokeAccessToken으로 즉시 갱신

8.2 Rate Limiting

  • FLOOD_WAIT_ 에러 발생 시 지정된 초만큼 대기 필요
  • 에러 형식: FLOOD_WAIT_60 (60초 대기)

8.3 URL 패턴

  • 형식: https://telegra.ph/{Title}-{MM}-{DD}
  • 같은 날 같은 제목이면 뒤에 숫자 추가: Title-02-10-2
  • path는 페이지 생성 시 자동 생성됨 (제어 불가)

8.4 콘텐츠 제한

  • content 최대 크기: 64KB
  • 제목: 1-256자
  • 작성자 이름: 0-128자
  • 작성자 URL: 0-512자

8.5 삭제 불가

  • 공식 삭제 API 없음
  • 우회: 내용을 빈 내용으로 editPage하여 사실상 비움 처리 가능
  • Telegram 측에서 부적절한 콘텐츠는 제거할 수 있음

8.6 SEO

  • Telegraph 페이지는 Google에 인덱싱됨
  • description 필드는 자동 생성 (첫 번째 텍스트 노드 기반)
  • Open Graph 메타 태그 자동 생성

9. 유용한 패턴

9.1 아카이브 인덱스 페이지 만들기

모든 브리핑 링크를 모아놓은 인덱스 페이지를 하나 만들고, 새 브리핑이 발행될 때마다 editPage로 업데이트:

# 인덱스 페이지 업데이트
index_content = [{'tag': 'h3', 'children': ['📚 Ketday 브리핑 아카이브']}]
for page in all_pages:
    index_content.append({
        'tag': 'p',
        'children': [{
            'tag': 'a',
            'attrs': {'href': page['url']},
            'children': [page['title']]
        }]
    })

telegraph.edit_page(
    path='Ketday-Archive',
    title='Ketday 브리핑 아카이브',
    content=index_content
)

9.2 Telegram 채널 고정 메시지로 인덱스 링크 고정

# 인덱스 페이지 링크를 채널에 고정
requests.post(
    f'https://api.telegram.org/bot{bot_token}/pinChatMessage',
    json={
        'chat_id': channel_id,
        'message_id': index_message_id
    }
)

10. 참고 링크

리소스 URL

Telegraph 에디터 https://telegra.ph
공식 API 문서 https://telegra.ph/api
Python SDK (python273) https://github.com/python273/telegraph
Python SDK (python-telegraph) https://python-telegraph.readthedocs.io
Node.js SDK (telegraf) https://github.com/telegraf/telegra.ph
Deno/JSR SDK https://jsr.io/@dcdunkan/telegraph
html-telegraph-poster https://github.com/mercuree/html-telegraph-poster
대체 미러 https://graph.org
반응형

댓글