Сервису telegra.ph уже много лет, но информации о том как пользоваться его api почему-то не много, тем временем, крупные телеграм-каналы потихоньку приступили к промышленному освоению. Инструмент вполне себе неплохая альтернатива созданию веб-страниц, к тому же появилась удобная библиотека, которая позволяет автоматизировать процесс.

С чего всё началось:

Случайно обратил внимание на кнопку "Посмотреть", которая появилась на некоторых телеграмм-каналах ("Раньше всех, ну почти", и "RT на русском")

Если нажать кнопку, то открывается статья судя-по всему на telegra.ph, что интересно, в самом посте ссылка на сайт, и на компьютере она туда и ведет, а вот в мобильной версии, есть такой вот просмотр. Пока не разбирался с деталями именно такой реализации, но сделать автопостинг в телеграф сразу захотелось, об этом, собственно дальше и будет разговор.

Array of Node или главная загвоздка Telegraph API и её разрешение

В целом, ничего сложного в Telegraph API нет, основная проблема была в том, что передавать содержание страницы нужно в виде Array of Node, up to 64 KB. Т.е. просто написать "Hello world" не получится (нужно писать ["Hello world"]), а передать какую-то разметку, так совсем не просто, например "Hello world":

[
  {
  "tag": "b",
  "children": ["Hello world"]
  }
]

Однако решение есть, это библиотека Telegraph, впрочем, постараюсь рассказать как работать и без неё. Приступаем.

Создание аккаунта и получение токена

Все работает через запросы к https://api.telegra.ph/ после чего указывается метод и, если надо, путь. Делать это можно как угодно: curl из командной строки, или requests.get() в питоне, или где хотите ещё. Я приведу пример работы в python.

Чтобы создать новый аккаунт нужно выполнить просто запрос к https://api.telegra.ph/ с указанием метода createAccount:

import requests
#создаем параметры для создания профиля
data={
    'short_name':'', # ОБЯЗАТЕЛЬНЫЙ ПАРАМЕТР, имя учетной записи, помогает пользователям с несколькими учетными записями запомнить, какая сейчас используются. Отображается пользователю над кнопкой «Изменить / Опубликовать» на Telegra.ph, другие пользователи не видят это имя.
    'author_name':'', # Не обязательно. Указывает автора в заголовке странцы
    'author_url':'' # Не обязательно. Ссылка открывается, когда пользователи нажимают на имя автора под заголовком. Это может быть любая ссылка, не обязательно на профиль или канал Telegram.
}
#отправляем запрос ответ понадобится, запишем в переменную:
result=requests.get("https://api.telegra.ph/createAccount?", params=data)

Из bash будет так:

curl https://api.telegra.ph/createAccount?short_name=Sandbox&author_name=Anonymous

С библиотекой telegraph: нужно её установить (pip install telegraph), а дальше всё просто:

import requests
from telegraph import Telegraph

telegraph = Telegraph()

result=telegraph.create_account(short_name='1337')

В ответ приходит json с токеном и прочим. Токен надо сохранять, я сохраню полученные данные в файл graph_bot.json

with open('graph_bot.json', 'w', encoding='utf-8') as f:
    json.dump(graph_bot, f, ensure_ascii=False, indent=4) # сохраняю в файл graph_bot

Вывод result.json()

{
    "ok":true,
    "result":
    {
        "short_name":"", #тут будет имя
        "author_name":"",
        "author_url":"",
        "access_token":"", #тут токен
        "auth_url":""
    }
}

Что интересно, метода удаления профайла и страниц не обнаружил. Имена аккаунтов не уникальные, можно насоздавать сколько угодно профилей с одинаковым именем, разница будет только в токенах.

Создание страницы (createPage)

Получаем токен из сохраненного json и передаём запрос на создание страницы:

with open('graph_bot.json') as f:
    graph_bot = json.load(f)
#создание страницы
data={
    'access_token':graph_bot["access_token"],
    'title':'article_head', # Заголовок, обязательный параметр
    'author_name':graph_bot["author_name"], # это поле можно не заполнять
    'content': content_json,# Текст (массив Node), обязательный параметр
    'return_content':'false' # если стоит true в ответе придет и то, что размещено, если false, то поле не вернется
}
page=requests.get("https://api.telegra.ph/createPage?", params=data)

Если всё пройдет хорошо, в ответ придет примерно такой результат:

{
    'ok': True, 
    'result': 
    {
        'path': 'article-head-11-04-2', 
        'url': 'https://telegra.ph/article-head-11-04-2', 
        'title': 'article_head', 
        'description': '', 
        'author_name': 'Bot', 
        'views': 0, 
        'can_edit': True
    }
}

Если в отправляемых данных есть ошибка, возвращается сообщение о ней:

{
    'ok': False, 
    'error': 'CONTENT_FORMAT_INVALID' # передан не array of node
}

Как уже сказал выше, главная проблема тут, это правильный формат передаваемого текста, рабочий парсер html to node реализован в библиотеке telegraph. Тут всё просто, можно сохранить весь HTML в строковую переменную и спокойно её передать в виде соответствующего поля:

from telegraph import Telegraph

telegraph = Telegraph("access_token") # передаём токен доступ к страницам аккаунта
response = telegraph.create_page(
    'Hey', # заголовок страницы
    html_content='<p>Hello, world!</p>' # ставим параметр html_content, добавляем текст страницы
)

print('https://telegra.ph/{}'.format(response['path'])) # распечатываем адрес страницы

Получаем страницу: https://telegra.ph/Hey-11-04-22

В библиотеке довольно внушительный список запрещенных тэгов, но для минимальной верстки telegra.ph хватает

Изменение страницы (editPage)

Чтобы изменить страницу надо знать её адрес, он идет после ph/ для страницы https://telegra.ph/Hey-11-04-22 параметр path будет "Hey-11-04-22". И конечно, токен доступа. Отправляем запрос с указанием метода и параметрами к https://api.telegra.ph/editPage

data={
    'path':'Hey-11-04-22', #путь к странице он содержится в url после https://telegra.ph/
    'access_token':'your_token',  # токен
    'title':'article_head', #заголовок, обязательный параметр, если не меняется, всё равно надо прописывать
    'author_name':None,  
    'content': content_json,  #содержание страницы должен быть  Array of Node
    'return_content':'false' 
}
#редактирование страницы
requests.get("https://api.telegra.ph/editPage?", params=data)

Опять же тут проблема в формате данных, которые должны быть Array of Node. Воспользуемся готовым решением:

from telegraph import Telegraph

telegraph = Telegraph('access_token') # чтобы получить доступ к вашим страницам

telegraph.edit_page(
    path="", # обязательный параметр
    title="", # обязательный параметр
    html_content="",  #измененное содержание страницы, тут можно передать хоть строку с тегами, хоть руками написать что надо
    author_name="", # можно пропустить
    author_url="", # можно пропустить
    return_content=False    
)

В случае ошибки приходит сообщение {'ok': False, 'error': 'описание ошибки'}. Если всё хорошо, статус 'ok' будет True.

Что ещё можно:

В целом, для создания и редактирования страниц достаточно, думаю принцип работы понятен. Также можно:

  • посмотреть и изменить информацию об аккаунте,

  • отозвать токен,

  • посмотреть свои страницы и

  • количество просмотров на них (делаем аналитику).

Например информация о профиле:

data={
    'access_token': "access_token",
    'fields':'["short_name","page_count"]'    
}
account_info=requests.get("https://api.telegra.ph/getAccountInfo?", params=data)
print(account_info.json())

Все можно почитать в документации:

Комментарии (3)


  1. Ryav
    06.11.2021 05:06

    Это всё здорово, конечно, но практического применения не вижу.


    1. Story-teller Автор
      06.11.2021 09:19

      Можно создавать копии страниц сайтов, чтобы пользователи с мобильных не уходили с канала/чата, например, интегрировать в админку, когда одновременно создаётся материал в двух местах. Видел пока на паре каналов.

      Да и в целом, вопросы по этому апи есть, а простого объяснения не нашел.


  1. SanekK
    06.11.2021 08:50
    +1

    Внешние сайты в телеграме парсятся по специальным шаблонам, которые пишут люди (несколько лет назад был конкурс на написание нескольких сотен самых крупных сайтов для корректного отображения в режиме статьи)