{"id":28930824,"url":"https://github.com/tishka17/sulguk","last_synced_at":"2026-04-10T10:02:23.832Z","repository":{"id":183206208,"uuid":"669602371","full_name":"Tishka17/sulguk","owner":"Tishka17","description":"HTML to telegram entities converter","archived":false,"fork":false,"pushed_at":"2025-12-29T16:53:17.000Z","size":164,"stargazers_count":113,"open_issues_count":8,"forks_count":14,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2026-01-01T21:41:15.240Z","etag":null,"topics":["html","sulguk","telegram"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tishka17.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-22T20:17:11.000Z","updated_at":"2025-12-31T21:38:33.000Z","dependencies_parsed_at":"2024-01-15T00:41:38.219Z","dependency_job_id":"952aac19-0ce5-486d-9760-5923721de6b5","html_url":"https://github.com/Tishka17/sulguk","commit_stats":null,"previous_names":["tishka17/html2tg","tishka17/sulguk"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/Tishka17/sulguk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tishka17%2Fsulguk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tishka17%2Fsulguk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tishka17%2Fsulguk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tishka17%2Fsulguk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tishka17","download_url":"https://codeload.github.com/Tishka17/sulguk/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tishka17%2Fsulguk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31637748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","sulguk","telegram"],"created_at":"2025-06-22T15:38:21.612Z","updated_at":"2026-04-10T10:02:23.820Z","avatar_url":"https://github.com/Tishka17.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Sulguk - HTML to telegram entities converter\n================================================\n\n\n[![PyPI version](https://badge.fury.io/py/sulguk.svg)](https://badge.fury.io/py/sulguk)\n[![downloads](https://img.shields.io/pypi/dm/sulguk.svg)](https://pypistats.org/packages/sulguk)\n[![license](https://img.shields.io/github/license/Tishka17/sulguk.svg)](https://github.com/Tishka17/sulguk/blob/master/LICENSE)\n\n\nNeed to deliver formatted content to your bot clients?\nHaving a hangover after trying to fit HTML into telegram?\nBeautifulsoup is too complicated and not helping with messages?\n\nTry `sulguk` (술국, a hangover\nsoup) - [delivered since 1800s](https://en.wikipedia.org/wiki/Food_delivery).\n\n## Problem\n\nTelegram supports `parse_mode=\"html\"`, but:\n\n* Telegram processes spaces and new lines incorrectly. So we cannot format HTML source for more readability.\n* Amount of supported tags is very low \n* It does not ignore additional attributes in supported tags.\n\nLet's imagine we have HTML like this:\n\n```html\n\u003cb\u003eThis is a demo of \u003ca href=\"https://github.com/tishka17/sulguk\"\u003eSulguk\u003c/a\u003e\u003c/b\u003e\n\n  \u003cu\u003eUnderlined\u003c/u\u003e\n  \u003ci\u003eItalic\u003c/i\u003e\n  \u003cb\u003eBold\u003c/b\u003e\n```\n\nThis is how it is rendered in browser (expected behavior):\n\n![](https://github.com/tishka17/sulguk/blob/master/images/problem_browser.png?raw=True)\n\nBut this is how it is rendered in Telegram with `parse_mode=\"html\"`:\n\n![](https://github.com/tishka17/sulguk/blob/master/images/problem_telegram.png?raw=True)\n\nTo solve this we can convert HTML to telegram entities with `sulguk`. So that's how it looks now:\n\n![](https://github.com/tishka17/sulguk/blob/master/images/problem_sulguk.png?raw=True)\n\n## Example\n\n1. Create your nice HTML:\n\n```html\n\n\u003col start=\"10\"\u003e\n    \u003cli\u003esome item\u003c/li\u003e\n    \u003cli\u003eother item\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eSome \u003cb\u003etext\u003c/b\u003e in a paragraph\u003c/p\u003e\n```\n\n2. Convert it into text and entities\n\n```python\nresult = transform_html(raw_html)\n```\n\n3. Send it to telegram.\n\nDepending on your library you may need to convert entities from dict into\nproper type\n\n```python\nawait bot.send_message(\n    chat_id=CHAT_ID,\n    text=result.text,\n    entities=result.entities,\n)\n```\n\n## Example for aiogram users\n\n1. Add `SulgukMiddleware` to your bot\n\n```python\nfrom sulguk import AiogramSulgukMiddleware\n\nbot.session.middleware(AiogramSulgukMiddleware())\n```\n\n2. Create your nice HTML:\n\n```html\n\n\u003col start=\"10\"\u003e\n    \u003cli\u003esome item\u003c/li\u003e\n    \u003cli\u003eother item\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eSome \u003cb\u003etext\u003c/b\u003e in a paragraph\u003c/p\u003e\n```\n\n3. Send it using `sulguk` as a `parse_mode`:\n\n```python\nfrom sulguk import SULGUK_PARSE_MODE\n\nawait bot.send_message(\n    chat_id=CHAT_ID,\n    text=raw_html,\n    parse_mode=SULGUK_PARSE_MODE,\n)\n```\n\n## Supported tags:\n\nFor all supported tags unknown attributes are ignored as well as unknown classes.\nUnsupported tags are raising an error. \n\n#### Standard telegram tags (with some changes):\n* `\u003ca\u003e` - a hyperlink with `href` attribute \n* `\u003cb\u003e`, `\u003cstrong\u003e` - a bold text\n* `\u003ci\u003e`, `\u003cem\u003e` - an italic text\n* `\u003cs\u003e`, `\u003cstrike\u003e`, `\u003cdel\u003e` - a strikethrough text\n* `\u003cu\u003e`, `\u003cins\u003e` - an underlined text\n* `\u003cspan\u003e` - an inline element with optional attribute `class=\"tg-spoiler\"` to make a spoiler\n* `\u003ctg-spoiler\u003e` - a telegram spoiler\n* `\u003cpre\u003e` with optional `class=\"language-\u003cname\u003e\"` - a preformatted block with code. `\u003cname\u003e` will be sent as a language attribute in telegram.\n* `\u003ccode\u003e` - an inline preformatted element. \n* `\u003cdetails\u003e` - rendered as an expandable blockquote\n* `\u003csummary\u003e` - treated as a paragraph, typically used as first child of `\u003cdetails\u003e` for the heading\n\n**Note:** In standard Telegram HTML you can set a preformatted text language nesting `\u003ccode class=\"language-\u003cname\u003e\"\u003e` in `\u003cpre\u003e` tag. This works when it is an only child. But any additional symbol outside of `\u003ccode\u003e` breaks it.\nThe same behavior is supported in sulguk. Otherwise, you can set the language on `\u003cpre\u003e` tag itself.\n\n#### Additional tags:\n* `\u003cbr/\u003e` - new line\n* `\u003chr/\u003e` - horizontal line\n* `\u003cwbr/\u003e` - word break opportunity\n* `\u003cul\u003e` - unordered list\n* `\u003col\u003e` - ordered list with optional attributes\n    * `reversed` - to reverse numbers order\n    * `type` (`1`/`a`/`A`/`i`/`I`) - to set numbering style\n    * `start` - to set starting number\n* `\u003cli\u003e` - list item, with optional  `value` attribute to change number. Nested lists have\n  indentation\n* `\u003cdiv\u003e` - a block (not inline) element\n* `\u003cp\u003e` - a paragraph, emphasized with empty lines\n* `\u003cq\u003e` - a quoted text\n* `\u003cblockquote\u003e` - a block quote. Like a paragraph with indentation\n* `\u003cblockquote expandable\u003e` - a block quote with expandable\n* `\u003ch1\u003e`-`\u003ch6\u003e` - text headers, styled using available telegram options\n* `\u003cnoscirpt\u003e` - contents is shown as not scripting is supported\n* `\u003ccite\u003e`, `\u003cvar\u003e` - italic\n* `\u003cprogress\u003e`, `\u003cmeter\u003e` are rendered using emoji (🟩🟩🟩🟨⬜️⬜️)\n* `\u003ckbd\u003e`, `\u003csamp\u003e` - preformatted text\n* `\u003cimg\u003e` - as a link with picture emoji before. `alt` text is used if provided.\n* `\u003ctt\u003e` - as italic text\n* `\u003cinput\u003e` - as symbols ✅⬜️(checkbox), 🔘⚪️(radio) or `_______`/value in other cases\n\n#### Tags which are treated as block elements (like `\u003cdiv\u003e`):\n`\u003cfooter\u003e`, `\u003cheader\u003e`, `\u003cmain\u003e`, `\u003cnav\u003e`, `\u003csection\u003e`\n\n#### Tags which are treated as inline elements (like `\u003cspan\u003e`):\n`\u003chtml\u003e`, `\u003cbody\u003e`, `\u003coutput\u003e`, `\u003cdata\u003e`, `\u003ctime\u003e`\n\n#### Tags which contents is ignored:\n\n`\u003chead\u003e`, `\u003clink\u003e`, `\u003cmeta\u003e`, `\u003cscript\u003e`, `\u003cstyle\u003e`, `\u003ctemplate\u003e`, `\u003ctitle\u003e`\n\n\n## Command line utility for channel management\n\n1. Install with addons\n```shell\npip install 'sulguk[cli]'\n```\n\n2. Set environment variable `BOT_TOKEN`\n\n```shell\nexport BOT_TOKEN=\"your telegram token\"\n```\n\n3. Send HTML file as a message to your channel. Additional files will be sent as comments to the first one. You can provide a channel name or a public link\n\n```shell\nsulguk send @chat_id file.html\n```\n\n4. If you want to, edit using the link from shell or from your tg client. Edition of comments is supported as well.\n\n```shell\nsulguk edit 'https://t.me/channel/1?comment=42' file.html\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftishka17%2Fsulguk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftishka17%2Fsulguk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftishka17%2Fsulguk/lists"}