Integration recipe
Get pixPLace comments in Telegram with a bot
A small bot script polls your comment inbox and sends each new comment to a Telegram chat, without duplicates.
Who it is for
Creators who want a message in Telegram when someone comments under their posts.
What it automates
Poll the comment inbox every few minutes and forward each new comment to a Telegram chat.
Steps
- Create a bot with BotFather and keep its token in TELEGRAM_BOT_TOKEN. Send the bot a message and note your chat id in TELEGRAM_CHAT_ID.
- Put the pixPLace API key in PIXPLACE_API_KEY. The script reads GET /api/v1/comments, the inbox of all comments under your posts, newest first.
- Remember the createdAt of the newest comment you sent and pass it as since next time. The comment with exactly that time comes back once more, so the script also remembers its id.
- Run the script from cron every few minutes. If the API answers 429 or 503 it stops, and the next run tries again.
- When you create the key, tick the `read` scope. A key without it gets 403 insufficient_scope on these calls.
Examples
Placeholders: ppk_live_XXXXXXXX is your key. The ids and the image address are samples. The API address is always https://pixplace.space/api/v1.
inbox_to_telegram.py
import json
import os
import requests
PIXPLACE = "https://pixplace.space/api/v1"
HEAD = {"Authorization": "Bearer " + os.environ["PIXPLACE_API_KEY"]}
TG = "https://api.telegram.org/bot" + os.environ["TELEGRAM_BOT_TOKEN"]
STATE = "state.json"
state = json.load(open(STATE)) if os.path.exists(STATE) else {"since": None, "ids": []}
params = {"limit": 50}
if state["since"]:
params["since"] = state["since"]
r = requests.get(PIXPLACE + "/comments", params=params, headers=HEAD, timeout=30)
if r.status_code in (429, 503):
raise SystemExit("pixPLace asks to wait %s s, the next run will retry" % r.headers.get("Retry-After"))
r.raise_for_status()
fresh = [c for c in reversed(r.json()["data"]) if c["id"] not in state["ids"]]
for c in fresh:
who = c["author"]["username"] or c["author"]["name"]
text = "%s on %s:\n%s" % (who, c["post"]["title"], c["content"])
requests.post(TG + "/sendMessage", json={"chat_id": os.environ["TELEGRAM_CHAT_ID"], "text": text}, timeout=30).raise_for_status()
if fresh:
newest = fresh[-1]["createdAt"]
state = {"since": newest, "ids": [c["id"] for c in fresh if c["createdAt"] == newest]}
json.dump(state, open(STATE, "w"))Run it every 5 minutes (crontab -e)
*/5 * * * * cd /home/me/bot && PIXPLACE_API_KEY=ppk_live_XXXXXXXX TELEGRAM_BOT_TOKEN=... TELEGRAM_CHAT_ID=... /usr/bin/python3 inbox_to_telegram.pyCommon errors
| Status | Cause | What to do |
|---|---|---|
| 400 | The since value is older than the inbox allows, or limit or cursor is invalid. The message names the parameter. | Delete state.json to start from the default window, or pass a newer since. Keep limit between 1 and the maximum. |
| 401 | The API key is missing, malformed, revoked or sent in the wrong header. | The script sends the header from PIXPLACE_API_KEY: make sure cron passes that variable, because cron does not read your shell profile. The header must read Authorization: Bearer followed by your ppk_live_ key. Check the key in Settings → Developer. |
| 403 | The key lacks a scope the call needs: the answer is 403 with error.code insufficient_scope and the missing scope in error.required. | Create a new key in Settings → Developer with the `read` scope ticked and use it instead; repeating the call with the same key fails the same way. |
| 503 | The database is momentarily unavailable. The answer carries Retry-After: 5. | Reading is safe to repeat. The script exits and the next cron run asks again. |
The full list of statuses, the retry rules and the limits are in Errors and retries.