Start
Example bots
Two small apps you can run today. Each one needs only a test or live key with the right permission. Paste your key and tokens into the lines at the top, then run.
Telegram balance bot
Send /balance to your own bot and it answers with your Adolfjon balance. It only answers your own chat, so your balance stays private.
- Permission:
balance:read - Create a bot with @BotFather and copy its token.
- Find your chat id: message @userinfobot.
- Paste the bot token, your chat id and your API key into the first lines, then run it. Node.js: save as
bot.mjs(Node 18+).
import requests
TG_BOT_TOKEN = "123456789:YOUR_BOT_TOKEN"
OWNER_CHAT_ID = 123456789
KEY = "ak_test_YOUR_KEY"
TG = f"https://api.telegram.org/bot{TG_BOT_TOKEN}"
API = "https://dev.adolfjon.uz/v1"
OWNER = OWNER_CHAT_ID
def balance():
r = requests.get(f"{API}/me/balance", headers={"Authorization": f"Bearer {KEY}"}, timeout=10).json()
if not r["ok"]:
return "Error: " + r["error"]["message"]
amount = f"{r['data']['balance']:,}".replace(",", " ")
return f"Balance: {amount} {r['data']['currency']}"
offset = 0
while True:
ups = requests.get(f"{TG}/getUpdates", params={"offset": offset, "timeout": 50}, timeout=60).json()["result"]
for u in ups:
offset = u["update_id"] + 1
msg = u.get("message") or {}
if msg.get("chat", {}).get("id") != OWNER:
continue
if msg.get("text") == "/balance":
requests.post(f"{TG}/sendMessage", json={"chat_id": OWNER, "text": balance()}, timeout=10)const TG_BOT_TOKEN = '123456789:YOUR_BOT_TOKEN';
const OWNER_CHAT_ID = 123456789;
const KEY = 'ak_test_YOUR_KEY';
const TG = `https://api.telegram.org/bot${TG_BOT_TOKEN}`;
const API = 'https://dev.adolfjon.uz/v1';
const OWNER = OWNER_CHAT_ID;
async function balance() {
const r = await (await fetch(`${API}/me/balance`, { headers: { Authorization: `Bearer ${KEY}` } })).json();
if (!r.ok) return 'Error: ' + r.error.message;
return `Balance: ${r.data.balance.toLocaleString('ru-RU')} ${r.data.currency}`;
}
let offset = 0;
for (;;) {
const { result } = await (await fetch(`${TG}/getUpdates?timeout=50&offset=${offset}`)).json();
for (const u of result) {
offset = u.update_id + 1;
const m = u.message;
if (!m || m.chat.id !== OWNER || m.text !== '/balance') continue;
await fetch(`${TG}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chat_id: OWNER, text: await balance() }),
});
}
}<?php
$tgBotToken = '123456789:YOUR_BOT_TOKEN';
$owner = 123456789;
$key = 'ak_test_YOUR_KEY';
$tg = 'https://api.telegram.org/bot' . $tgBotToken;
$api = 'https://dev.adolfjon.uz/v1';
function get_json(string $url, array $headers = []): array {
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, CURLOPT_HTTPHEADER => $headers]);
$r = json_decode((string)curl_exec($ch), true);
return is_array($r) ? $r : [];
}
$offset = 0;
while (true) {
foreach (get_json("$tg/getUpdates?timeout=50&offset=$offset")['result'] ?? [] as $u) {
$offset = $u['update_id'] + 1;
$m = $u['message'] ?? null;
if (!$m || $m['chat']['id'] !== $owner || ($m['text'] ?? '') !== '/balance') continue;
$r = get_json("$api/me/balance", ['Authorization: Bearer ' . $key]);
$text = !empty($r['ok'])
? 'Balance: ' . number_format($r['data']['balance'], 0, '.', ' ') . ' ' . $r['data']['currency']
: 'Error: ' . ($r['error']['message'] ?? 'no response');
get_json("$tg/sendMessage?" . http_build_query(['chat_id' => $owner, 'text' => $text]));
}
}Discord order notifier
Posts every new order on your account to a Discord channel. It checks once a minute, well under the rate limit, and remembers what it already posted in seen_orders.json.
- Permission:
orders:read - In Discord: channel settings → Integrations → Webhooks → New webhook → copy the URL.
- Paste the Discord webhook URL and your API key into the first lines, then run it. Node.js: save as
notify.mjs. - The first run only remembers your existing orders; new ones get posted from then on.
import json, os, time, requests
KEY = "ak_test_YOUR_KEY"
HOOK = "https://discord.com/api/webhooks/YOUR_WEBHOOK"
API = "https://dev.adolfjon.uz/v1"
SEEN_FILE = "seen_orders.json"
seen = set(json.load(open(SEEN_FILE))) if os.path.exists(SEEN_FILE) else None
while True:
r = requests.get(f"{API}/me/orders", params={"limit": 20},
headers={"Authorization": f"Bearer {KEY}"}, timeout=10).json()
if r["ok"]:
if seen is None:
seen = {o["id"] for o in r["data"]}
for o in reversed(r["data"]):
if o["id"] in seen:
continue
seen.add(o["id"])
items = ", ".join(i["title"] for i in o["items"])
total = f"{o['total_uzs']:,}".replace(",", " ")
requests.post(HOOK, json={"content": f"New order {o['id']}: {items} · {total} UZS · {o['status']}"}, timeout=10)
json.dump(sorted(seen), open(SEEN_FILE, "w"))
time.sleep(60)import fs from 'node:fs';
const KEY = 'ak_test_YOUR_KEY';
const HOOK = 'https://discord.com/api/webhooks/YOUR_WEBHOOK';
const API = 'https://dev.adolfjon.uz/v1';
const SEEN_FILE = 'seen_orders.json';
let seen = fs.existsSync(SEEN_FILE) ? new Set(JSON.parse(fs.readFileSync(SEEN_FILE, 'utf8'))) : null;
for (;;) {
const r = await (await fetch(`${API}/me/orders?limit=20`, { headers: { Authorization: `Bearer ${KEY}` } })).json();
if (r.ok) {
if (seen === null) seen = new Set(r.data.map((o) => o.id));
for (const o of [...r.data].reverse()) {
if (seen.has(o.id)) continue;
seen.add(o.id);
const items = o.items.map((i) => i.title).join(', ');
await fetch(HOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: `New order ${o.id}: ${items} · ${o.total_uzs.toLocaleString('ru-RU')} UZS · ${o.status}` }),
});
}
fs.writeFileSync(SEEN_FILE, JSON.stringify([...seen]));
}
await new Promise((ok) => setTimeout(ok, 60000));
}<?php
$key = 'ak_test_YOUR_KEY';
$hook = 'https://discord.com/api/webhooks/YOUR_WEBHOOK';
$api = 'https://dev.adolfjon.uz/v1';
$seenFile = __DIR__ . '/seen_orders.json';
$seen = is_file($seenFile) ? array_flip(json_decode(file_get_contents($seenFile), true)) : null;
while (true) {
$ch = curl_init("$api/me/orders?limit=20");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key]]);
$r = json_decode((string)curl_exec($ch), true);
if (!empty($r['ok'])) {
if ($seen === null) $seen = array_flip(array_column($r['data'], 'id'));
foreach (array_reverse($r['data']) as $o) {
if (isset($seen[$o['id']])) continue;
$seen[$o['id']] = true;
$items = implode(', ', array_column($o['items'], 'title'));
$text = "New order {$o['id']}: $items · " . number_format($o['total_uzs'], 0, '.', ' ') . " UZS · {$o['status']}";
$p = curl_init($hook);
curl_setopt_array($p, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode(['content' => $text])]);
curl_exec($p);
}
file_put_contents($seenFile, json_encode(array_keys($seen)));
}
sleep(60);
}Tips
- Start with an
ak_test_key: account endpoints return realistic fake data, so you can build without touching your real account. - A file with your key inside is like a password: do not send it, upload it to GitHub or show it in a screenshot. See Key safety.
- Running it on a server? Lock the key to that server's IP. See IP allowlist.