# Telegram Markdown to JSON — Split Long Messages (`creatieve_naald/telegram-message-preparer`) Actor

Prepare long AI responses for Telegram: split Markdown into ordered text/entities payloads with supported formatting. No bot token needed; sending stays in your workflow. $0.01 per text bundle. API and Python examples included.

- **URL**: https://apify.com/creatieve_naald/telegram-message-preparer.md
- **Developed by:** [Stefan Schellen](https://apify.com/creatieve_naald) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 prepared texts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Telegram Markdown to JSON — Split Long Messages

Prepare long AI responses and Markdown reports for Telegram. Get **ordered `text` + `entities` payloads** that preserve supported formatting across message boundaries, without manually escaping MarkdownV2 in your sending step.

**$0.01 per successfully prepared text bundle**, up to 64 KiB UTF-8 input and 20 messages. The price is per input bundle, not per Telegram message. No additional platform-usage charge.

### Try it in one minute

1. Click **Try for free** and run the example using available Apify credit; otherwise the displayed price applies.
2. Open the dataset and expand `messages`.
3. Your workflow sends those messages sequentially with its own bot. This Actor never sends messages or requests a bot token.

### Input and exact output example

Input:

```json
{"markdown":"😀 **HTTP example** and `x_y`"}
```

The synchronous API returns an array containing this envelope:

```json
[
  {
    "schema_version": "1.0",
    "message_count": 1,
    "messages": [
      {
        "index": 1,
        "text": "😀 HTTP example and x_y",
        "entities": [
          {
            "type": "bold",
            "offset": 3,
            "length": 12
          },
          {
            "type": "code",
            "offset": 20,
            "length": 3
          }
        ]
      }
    ],
    "warnings": [
      "MARKDOWN_RENDERED_NOT_LOSSLESS_SOURCE",
      "SEND_SEQUENTIALLY_WITHOUT_PARSE_MODE"
    ]
  }
]
```

`index` is for ordering. Give Telegram only `text`, `entities` and your own `chat_id`; do not include `index` or `parse_mode`.

### Why use this instead of a free splitter?

A character-only splitter can cut formatting spans or mishandle emoji offsets. This service converts Markdown and splits the resulting text/entities together, with bounded input and explicit rejection of unsupported cases. It uses the free telegramify-markdown and pyromark libraries; self-hosting those is a valid alternative. The paid convenience is a hosted API for workflows that do not want to manage Python dependencies.

### Workflow: AI response to Telegram-ready payloads

HTTP POST:

`https://api.apify.com/v2/acts/creatieve_naald~telegram-message-preparer/run-sync-get-dataset-items?memory=256&timeout=20&maxTotalChargeUsd=0.01`

Store `Authorization: Bearer <APIFY_TOKEN>` in workflow credentials. Body: `{"markdown":"your response text"}`. Read the first response envelope's `messages` array.

- **n8n recipe:** HTTP Request (POST, Header Auth, JSON body, timeout 35 seconds, retries off) → Split Out `messages` → your sequential Telegram sender using `text` and `entities`, without `parse_mode`.
- **Make recipe:** JSON/Create JSON → HTTP request → parse first response envelope → Iterator `messages` → your Telegram HTTP sender. Keep entity objects as JSON arrays, not quoted JSON strings.
- These are configuration recipes. The importable n8n example below was tested locally with fixtures; a live Apify-to-n8n run and Make import are not verified. Saved cloud HTTP output and eight real synthetic Telegram messages were accepted with exact text and expected entities.

#### Copyable Python preparation workflow

Python 3 standard library only. Set `APIFY_TOKEN` through a secret manager. This example prepares payloads and does not send them. Request construction and result mapping were tested offline against saved acceptance output.

```python
"""Two copyable workflow adapters. No network calls on import."""
import json, os, urllib.request
from pathlib import Path

def call_actor(slug, field, text, price):
    url = f'https://api.apify.com/v2/acts/creatieve_naald~{slug}/run-sync-get-dataset-items?memory=256&timeout=20&maxTotalChargeUsd={price}'
    request = urllib.request.Request(url, data=json.dumps({field: text}).encode(), headers={'Authorization': 'Bearer '+os.environ['APIFY_TOKEN'], 'Content-Type': 'application/json'}, method='POST')
    # A timeout can mean the job ran. Never automatically start a replacement job.
    with urllib.request.urlopen(request, timeout=35) as response:
        rows = json.load(response)
    if not isinstance(rows,list) or len(rows)!=1 or rows[0].get('schema_version')!='1.0':
        raise ValueError('Unexpected response; inspect existing run before retrying')
    return rows[0]

def telegram_payloads(envelope):
    """Ordered sendMessage body fragments; no bot token/chat ID or sending."""
    messages=envelope['messages']
    if [m['index'] for m in messages]!=list(range(1,len(messages)+1)):
        raise ValueError('Unexpected message order')
    return [{'text': m['text'], 'entities': m['entities']} for m in messages]


result = call_actor('telegram-message-preparer', 'markdown',
                    Path('answer.md').read_text(encoding='utf-8'), '0.01')
payloads = telegram_payloads(result)
## Your sender adds chat_id and submits one payload at a time.
```

### Importable n8n workflow: Markdown to ordered Telegram payloads

Copy the JSON below to `n8n-telegram.json`, then import that file into n8n. This is a standalone example from Agent Tools, not an approved n8n template-directory listing.

1. Select an **HTTP Header Auth** credential on **Prepare using Apify**. Set header name `Authorization` and value `Bearer ` followed by your own Apify token. Never put the token in the shared JSON.
2. Replace the deliberately long synthetic text in **Synthetic Markdown** with your report. The long sample exercises message splitting.
3. Run manually. The workflow calls this paid Actor once, with a $0.01 Actor charge cap and automatic retries disabled, and validates the response before exposing ordered items.
4. Connect your own sender only after reviewing the output. Preserve `sequence`, `text` and `entities`, add your `chat_id`, and do not set `parse_mode`. Keep your bot token in the sender's credentials.

Your sender must handle rate limits and partial delivery. A timeout is ambiguous: inspect the existing run before starting another. The workflow has no Telegram sending node.

**Test scope:** imported and executed locally with n8n 2.43.8 using HTTP fixtures, including invalid output and HTTP failure. No live Apify-to-n8n roundtrip or end-to-end Telegram delivery was performed for this workflow. Separate Actor acceptance tests do not prove this entire integration.

#### Copy the complete importable workflow JSON

```json
{"name":"Prepare Markdown as ordered Telegram payloads with Apify","nodes":[{"id":"start","name":"Run manually","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[0,0],"parameters":{}},{"id":"input","name":"Synthetic Markdown","type":"n8n-nodes-base.set","typeVersion":3.4,"position":[240,0],"parameters":{"mode":"raw","jsonOutput":"{\"markdown\": \"**AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA**\"}","options":{}}},{"id":"prepare","name":"Prepare using Apify","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[480,0],"parameters":{"method":"POST","url":"https://api.apify.com/v2/acts/creatieve_naald~telegram-message-preparer/run-sync-get-dataset-items?memory=256&timeout=20&maxTotalChargeUsd=0.01","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","sendBody":true,"specifyBody":"json","jsonBody":"={{ {markdown: $json.markdown} }}","options":{"timeout":35000,"response":{"response":{"responseFormat":"json"}}}},"retryOnFail":false},{"id":"validate","name":"Validate and expose ordered payloads","type":"n8n-nodes-base.code","typeVersion":2,"position":[720,0],"parameters":{"jsCode":"const rows = $input.all().map(item => item.json);\nif (rows.length !== 1) throw new Error('Expected one result; inspect the existing Apify run before retrying.');\nconst result = rows[0];\nif (result.schema_version !== '1.0' || !Array.isArray(result.messages) || result.messages.length < 1 || result.messages.length > 20 || result.message_count !== result.messages.length) throw new Error('Unexpected result schema.');\nreturn result.messages.map((m, i) => {\n  if (m.index !== i + 1 || typeof m.text !== 'string' || !m.text.trim() || m.text.length > 4096 || !Array.isArray(m.entities)) throw new Error('Invalid message or sequence.');\n  for (const e of m.entities) {\n    if (!Number.isInteger(e.offset) || !Number.isInteger(e.length) || e.offset < 0 || e.length < 1 || e.offset + e.length > m.text.length) throw new Error('Invalid UTF-16 entity bounds.');\n  }\n  return {json: {sequence: m.index, text: m.text, entities: m.entities, warnings: result.warnings || []}};\n});"}},{"id":"guide","name":"Read before running","type":"n8n-nodes-base.stickyNote","typeVersion":1,"position":[-20,-700],"parameters":{"content":"## Prepare Telegram payloads with Apify\nFor workflow builders who want hosted Markdown conversion without installing a parser. This is our paid Apify Actor; free local parsers and community nodes are alternatives.\n\n1. Import this workflow and configure Header Auth: header name Authorization, value Bearer followed by your Apify token. Store it in credentials, never in this export.\n2. Replace the synthetic Markdown in the input node.\n3. A manual run calls Apify once and validates the result. Each output item contains a sequence number, text and explicit entities. It does not send messages.\n4. Your sender must preserve sequence and use entities without parse_mode. Handle partial delivery and Telegram rate limits in that sender.\n\nApify account required. Current Actor price: $0.01 per successful input bundle; maximum 64 KiB and 20 messages. Check the live pricing before running. The request caps Actor charges at $0.01 and has no automatic retries. A timeout may still leave a completed run: inspect that run before trying again.\n\nOnly supported Markdown is accepted; HTML and images are rejected. No custom nodes or LLM calls are required.\n\nValidated with n8n 2.43.8 CLI import and local HTTP fixtures, including invalid output and HTTP failure. A live Apify-to-n8n run has not been performed. No Telegram delivery is included.","height":660,"width":1020,"color":1}}],"connections":{"Run manually":{"main":[[{"node":"Synthetic Markdown","type":"main","index":0}]]},"Synthetic Markdown":{"main":[[{"node":"Prepare using Apify","type":"main","index":0}]]},"Prepare using Apify":{"main":[[{"node":"Validate and expose ordered payloads","type":"main","index":0}]]}},"active":false,"settings":{"executionOrder":"v1"}}
```

The JSON contains only synthetic input and standard n8n nodes, with no saved credentials. A manual execution uses your Apify account and the Actor's current price. Free local parsers are alternatives if you prefer to maintain them.

More bounded workflow tools: [Agent Tools portfolio](https://apify.com/creatieve_naald).

### Limits and delivery responsibility

Maximum 64 KiB UTF-8 input, 20 messages, 4096 UTF-16 units and 100 entities per message. Images and raw HTML are rejected. Only HTTP(S) text links without embedded credentials are supported. Markdown rendering may change whitespace and source notation; not a lossless archive or full grapheme-preservation guarantee. Detected unsafe Unicode boundaries are rejected.

No AI calls, external link fetching, diagram rendering, streaming or delivery. Your sender handles Telegram rate limits, retries and partial delivery. Do not blindly resend a whole bundle after a network timeout; a fresh Apify request is a new potentially billable job. Inspect the existing run first.

### Frequently asked questions

**Will this fix every Telegram formatting error?** No. It avoids a separate parse_mode parsing step by returning entities. You must pass those entities correctly and obey Telegram's delivery rules.

**What do ten output messages cost?** $0.01 when they come from one successful input bundle within the limits. 100 successful input bundles cost $1, before any applicable taxes or account-specific discounts.

**Does it send to my chat?** No. Your own bot and workflow handle delivery. Never submit a bot token or chat ID to this Actor.

### Privacy and support

Apify stores input/output according to account/platform retention settings; no zero-retention promise. Submit only the `markdown` field and avoid sensitive content. No input is sent to an AI provider. Library license notices are included.

Report reproducible problems through the Apify Issues tab using synthetic text, with tokens and personal information removed. Custom bot hosting and bespoke workflow integrations are outside scope.

# Actor input Schema

## `markdown` (type: `string`):

At most 64 KiB UTF-8. No HTML or images. Returns payloads; sends nothing.

## Actor input object example

```json
{
  "markdown": "😀 **Example** and `x_y`"
}
```

# Actor output Schema

## `messages` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "markdown": "😀 **Example** and `x_y`"
};

// Run the Actor and wait for it to finish
const run = await client.actor("creatieve_naald/telegram-message-preparer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "markdown": "😀 **Example** and `x_y`" }

# Run the Actor and wait for it to finish
run = client.actor("creatieve_naald/telegram-message-preparer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "markdown": "😀 **Example** and `x_y`"
}' |
apify call creatieve_naald/telegram-message-preparer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,creatieve_naald/telegram-message-preparer"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bFe9gpubDSaWhyOPC/builds/Tx3W1ebdSg9LBLk6r/openapi.json
