telegram-writer 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +131 -2
- package/build/index.cjs +1132 -0
- package/build/index.mjs +1125 -0
- package/example/index.mjs +40 -0
- package/package.json +65 -4
- package/rollup.config.mjs +37 -0
- package/scripts/fix.ts +45 -0
- package/src/config/logger.ts +35 -0
- package/src/config/params.ts +40 -0
- package/src/config/telegram.ts +33 -0
- package/src/functions/send_message.ts +48 -0
- package/src/functions/sign_in.ts +18 -0
- package/src/index.ts +11 -0
- package/src/lib/core/di.ts +3 -0
- package/src/lib/core/provide.ts +20 -0
- package/src/lib/core/types.ts +17 -0
- package/src/lib/index.ts +30 -0
- package/src/lib/services/base/AuthService.ts +74 -0
- package/src/lib/services/base/LoggerService.ts +63 -0
- package/src/lib/services/base/MarkdownService.ts +786 -0
- package/src/lib/services/base/WriterService.ts +178 -0
- package/src/lib/services/global/TelegramGlobalService.ts +35 -0
- package/src/model/TextBlock.model.ts +43 -0
- package/src/model/WriterMessage.model.ts +8 -0
- package/tsconfig.json +30 -0
- package/types.d.ts +206 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Petr Tripolsky
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,132 @@
|
|
|
1
|
-
#
|
|
1
|
+
# telegram-writer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A library for publishing posts to Telegram chats and channels via MTProto (a userbot built on [gramjs](https://gram.js.org/)). It takes **Markdown and photos** and sends them as a post: the Markdown is converted to HTML and then reduced to the tags Telegram supports, long texts are split into several messages, photos go as albums. A companion to [telegram-reader](https://www.npmjs.com/package/telegram-reader) — the photos it returns can be passed straight back in.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **QR-code authorization** — one interactive session, after which the client reuses the saved `session.txt`.
|
|
8
|
+
- **`sendMessage`** — Markdown + photos → chat. Photos are sent as albums (up to 10 per album); the text becomes the caption when it fits into the caption limit, otherwise it follows as separate messages.
|
|
9
|
+
- **Markdown → Telegram HTML**: `marked` renders the Markdown, `htmlparser2` parses the result, and everything Telegram cannot display is flattened to text. Only `b`, `i`, `u`, `s`, `spoiler`, `code`, `pre`, `blockquote` and `a` survive, so Telegram never sees a tag it would reject (tables, headings, lists, images).
|
|
10
|
+
- **Long posts are split** at the message limit (4096 chars) and at the caption limit (1024 chars) between paragraphs or at a line/word boundary — formatting never breaks across messages.
|
|
11
|
+
- **Photos** are accepted as base64 (the `telegram-reader` format), data-URLs or `Buffer`s; each is rotated by EXIF, downsized to at most 2560px on the long side and re-encoded as JPEG via `sharp`, so Telegram always treats it as a photo. Processing goes through a pool (`maxExec: 5`) to avoid OOM on weak hardware.
|
|
12
|
+
|
|
13
|
+
## Installation and build
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
npm run build # rollup → build/index.cjs, build/index.mjs + types.d.ts
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Requires Node.js 20+ (`sharp`, `marked` and `htmlparser2` are used).
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
1. Get an `api_id` and `api_hash` at [my.telegram.org](https://my.telegram.org) and pass them via `setConfig` **before** the first call to any other function (recommended way):
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { setConfig } from "telegram-writer";
|
|
28
|
+
|
|
29
|
+
setConfig({
|
|
30
|
+
CC_TELEGRAM_API_ID: 1234567,
|
|
31
|
+
CC_TELEGRAM_API_HASH: "0123456789abcdef0123456789abcdef",
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Values set through `setConfig` take priority over everything else. Alternatively, use environment variables (a `.env` file works too):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
CC_TELEGRAM_API_ID=1234567
|
|
39
|
+
CC_TELEGRAM_API_HASH=0123456789abcdef0123456789abcdef
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Resolution order: `setConfig` → environment variables → built-in defaults. The current effective values can be inspected with `getConfig()`.
|
|
43
|
+
|
|
44
|
+
Two more keys control splitting: `CC_TELEGRAM_MESSAGE_LIMIT` (default `4096`) and `CC_TELEGRAM_CAPTION_LIMIT` (default `1024`; Telegram Premium accounts may raise it to `4096`).
|
|
45
|
+
|
|
46
|
+
2. Create `session.txt` by signing in once. The recommended way is a one-liner:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
node -e 'require("telegram-writer").signIn()'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or call it from your own code:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { signIn } from "telegram-writer";
|
|
56
|
+
|
|
57
|
+
await signIn();
|
|
58
|
+
// Session saved to ./session.txt
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A QR code appears in the console — scan it in Telegram (*Settings → Devices → Link Desktop Device*); if 2FA is enabled, you will be prompted for the password. The session is saved to `./session.txt` and reused by all subsequent calls.
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
### Send a post
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { sendMessage } from "telegram-writer";
|
|
69
|
+
|
|
70
|
+
const sent = await sendMessage({
|
|
71
|
+
chat: "some_channel", // username, "@username", numeric id as a string, or "me"
|
|
72
|
+
content: "# Report\n\n**BTCUSDT** closed at `68 400`\n\n- long\n- stop `67 900`",
|
|
73
|
+
photos: [chartPngBuffer, base64FromTelegramReader], // optional
|
|
74
|
+
silent: false, // optional, do not notify members
|
|
75
|
+
replyTo: 123, // optional, message id to reply to
|
|
76
|
+
linkPreview: false, // optional, defaults to false
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Each returned row describes one sent message, in send order:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
interface WriterMessage {
|
|
84
|
+
id: number; // message id within the chat
|
|
85
|
+
chat: string; // chat exactly as passed in the request
|
|
86
|
+
date: Date; // server-side send time
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Delivery rules:
|
|
91
|
+
|
|
92
|
+
- **No photos** — the text goes as one message, or several when it exceeds `CC_TELEGRAM_MESSAGE_LIMIT`.
|
|
93
|
+
- **With photos** — albums of up to 10 photos are sent first. When the text fits `CC_TELEGRAM_CAPTION_LIMIT` it becomes the caption of the first album; otherwise the albums go without a caption and the text follows as separate messages.
|
|
94
|
+
- Empty text with no photos sends nothing and returns `[]`.
|
|
95
|
+
|
|
96
|
+
### How Markdown is converted
|
|
97
|
+
|
|
98
|
+
Inside `sendMessage` the Markdown is rendered to HTML by `marked`, parsed by `htmlparser2`, and rebuilt so that only Telegram entities remain. Nothing else is ever sent with `parseMode: "html"`.
|
|
99
|
+
|
|
100
|
+
| Markdown | Telegram |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `**bold**`, `*italic*`, `~~strike~~`, raw `<u>`/`<ins>` | `<b>`, `<i>`, `<s>`, `<u>` |
|
|
103
|
+
| `<tg-spoiler>`, `<spoiler>`, `<span class="tg-spoiler">` | `<spoiler>` |
|
|
104
|
+
| `` `code` `` | `<code>` (other styles inside are dropped — Telegram forbids them) |
|
|
105
|
+
| ```` ```lang ```` fenced block | `<pre><code class="language-lang">` (or plain `<pre>`) |
|
|
106
|
+
| `[text](url)`, `<https://url>` | `<a href="url">` — only `http(s)://`, `tg://`, `mailto:`; other links become plain text |
|
|
107
|
+
| `` | `<a href="url">alt</a>` — Telegram cannot embed images in text |
|
|
108
|
+
| `# Heading` … `###### Heading` | bold line |
|
|
109
|
+
| `- item`, `1. item`, `- [x] task` | `• item`, `1. item`, `☑ task` lines; nested lists indented by 4 spaces |
|
|
110
|
+
| `> quote` | `<blockquote>` (nested quotes are flattened; raw `<blockquote expandable>` is kept) |
|
|
111
|
+
| GFM table | aligned monospace `<pre>` block |
|
|
112
|
+
| `---` | paragraph break |
|
|
113
|
+
| single newline | line break (`breaks: true`) |
|
|
114
|
+
| `<div>`, `<span>`, any other tag | removed, text kept; `<script>`/`<style>` removed with content |
|
|
115
|
+
|
|
116
|
+
Blocks are separated by a blank line. Identical tags are never nested and `code` never carries other styles, matching Telegram's entity rules.
|
|
117
|
+
|
|
118
|
+
### Direct client access
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { getTelegram } from "telegram-writer";
|
|
122
|
+
|
|
123
|
+
const client = await getTelegram(); // authorized TelegramClient (singleton)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## REPL
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npm run repl
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Builds the project and starts Node with `.env` loaded — handy for testing the functions by hand.
|