{"id":50843158,"url":"https://github.com/yerdaulet-damir/teleping","last_synced_at":"2026-07-01T18:01:07.326Z","repository":{"id":349003299,"uuid":"1194565960","full_name":"yerdaulet-damir/teleping","owner":"yerdaulet-damir","description":"like console.log but it arrives on your phone. telegram alerts for vibe coders — 1 import, 5 functions, zero deps.","archived":false,"fork":false,"pushed_at":"2026-04-03T18:00:37.000Z","size":73,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T20:51:24.677Z","etag":null,"topics":["alerts","alerts-bot","developer-tools","error-tracking","nextjs","notifications","solo-developer","stripe-webhook","telegram","vercel","vibe-coding","webhook","zero-dependencies"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yerdaulet-damir.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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},"funding":{"github":"yerdaulet-damir"}},"created_at":"2026-03-28T14:30:28.000Z","updated_at":"2026-04-03T20:49:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yerdaulet-damir/teleping","commit_stats":null,"previous_names":["yerdaulet-damir/teleping"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/yerdaulet-damir/teleping","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yerdaulet-damir%2Fteleping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yerdaulet-damir%2Fteleping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yerdaulet-damir%2Fteleping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yerdaulet-damir%2Fteleping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yerdaulet-damir","download_url":"https://codeload.github.com/yerdaulet-damir/teleping/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yerdaulet-damir%2Fteleping/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35017091,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["alerts","alerts-bot","developer-tools","error-tracking","nextjs","notifications","solo-developer","stripe-webhook","telegram","vercel","vibe-coding","webhook","zero-dependencies"],"created_at":"2026-06-14T08:00:22.752Z","updated_at":"2026-07-01T18:01:07.296Z","avatar_url":"https://github.com/yerdaulet-damir.png","language":"TypeScript","funding_links":["https://github.com/sponsors/yerdaulet-damir"],"categories":["Tools"],"sub_categories":["Bot Libs"],"readme":"\u003cdiv align=\"center\"\u003e\n\n```\n ████████╗███████╗██╗     ███████╗██████╗ ██╗███╗   ██╗ ██████╗\n ╚══██╔══╝██╔════╝██║     ██╔════╝██╔══██╗██║████╗  ██║██╔════╝\n    ██║   █████╗  ██║     █████╗  ██████╔╝██║██╔██╗ ██║██║  ███╗\n    ██║   ██╔══╝  ██║     ██╔══╝  ██╔═══╝ ██║██║╚██╗██║██║   ██║\n    ██║   ███████╗███████╗███████╗██║     ██║██║ ╚████║╚██████╔╝\n    ╚═╝   ╚══════╝╚══════╝╚══════╝╚═╝     ╚═╝╚═╝  ╚═══╝ ╚═════╝\n```\n\n**like `console.log` but it arrives on your phone.**\u003cbr\u003e\ntelegram alerts for solo builders — 1 import, 5 functions, zero deps.\n\n[![npm](https://img.shields.io/npm/v/teleping?color=3ECF8E\u0026style=flat-square)](https://npmjs.com/package/teleping)\n[![tests](https://img.shields.io/github/actions/workflow/status/yerdaulet-damir/teleping/ci.yml?label=tests\u0026style=flat-square)](https://github.com/yerdaulet-damir/teleping/actions)\n[![license](https://img.shields.io/badge/license-MIT-3ECF8E.svg?style=flat-square)](LICENSE)\n[![bundle](https://img.shields.io/bundlephobia/minzip/teleping?color=3ECF8E\u0026style=flat-square)](https://bundlephobia.com/package/teleping)\n[![zero deps](https://img.shields.io/badge/dependencies-0-3ECF8E?style=flat-square)](#)\n\n\u003cbr\u003e\n\n[![teleping](https://coolreadme.xyz/api/docs-card?pkg=teleping\u0026version=0.2.1\u0026desc=Telegram+alerts+for+vibe+coders.+Know+what+broke+and+what+shipped+%E2%80%94+the+moment+it+happens.\u0026install=npm+install+teleping\u0026theme=langchain)](https://npmjs.com/package/teleping)\n\n\n\n\u003c/div\u003e\n\n---\n```typescript\n// your stripe webhook just broke at 2am.\n// you're asleep. teleping is not.\n\nimport { teleping } from 'teleping'\n\n// simple — drop anywhere, fire-and-forget\nteleping.success('New user', { email: 'alex@startup.com', plan: 'pro' })\nteleping.error('Payment failed', { amount: 15, reason: 'card_declined' })\n\n// builder — full context, tap [Copy for Claude] from your phone\nteleping.error('Stripe webhook failed')\n  .data({ userId, amount, event: event.type })\n  .code(err.stack, 'typescript')\n  .button('claude')    // one tap → error context in clipboard, ready for Claude\n  .button('cursor')    // one tap → opens exact file:line in Cursor\n  .send()\n```\n\n\u003cdiv align=\"center\"\u003e\n\n| | DIY bot | teleping |\n|---|---|---|\n| Setup | write it yourself | `npm install teleping` |\n| Format | ugly plain text | emoji + separators + structured |\n| 50 same errors | 50 messages, phone dies | 1 batched message |\n| 3AM non-critical | wakes you | quiet hours suppress it |\n| Error on phone | stare at it | [Open in Cursor] [Copy for Claude] |\n| Every project | rewrite from scratch | 1 import |\n\n\u003c/div\u003e\n\n## Why\n\nYou're vibe coding. Cursor, Claude, Vercel, Supabase — everything ships fast. But the moment code hits production, you're blind. You find out about broken payments from users. You find out about signups by checking your dashboard at noon.\n\n**teleping makes your app talk to you directly on Telegram.** Every signup, payment, error, and metric — on your phone, beautifully formatted, the moment it happens.\n\n```\nshadcn/ui   → beautiful components in 1 line\nprisma      → beautiful database queries in 1 line\nteleping    → beautiful production alerts in 1 line\n```\n\n## Install\n\n```bash\nnpm install teleping\n```\n\n## Setup (2 minutes, one time)\n\n1. Message [@BotFather](https://t.me/BotFather) on Telegram → create a bot → copy the token\n2. Start a chat with your new bot → get your chat ID\n3. Add to `.env`:\n\n```env\nTELEPING_TOKEN=your_bot_token\nTELEPING_CHAT=your_chat_id\n```\n\nOr run the CLI — it does all of this:\n\n```bash\nnpx teleping init   # creates .env with TELEPING_TOKEN + TELEPING_CHAT\nnpx teleping test   # sends a test message to verify\n```\n\n![npm Package](https://coolreadme.xyz/api/npm-card?pkg=teleping)\n## Usage\n\n```typescript\nimport { teleping } from 'teleping'\n\n// five functions. that's the whole API.\nteleping.log('Server started', { port: 3000 })\nteleping.success('New user', { email, plan })\nteleping.warn('Rate limit hit', { ip, endpoint })\nteleping.error('Payment failed', { error: err.message, userId })\nteleping.metric('Monthly revenue', 4500)\n```\n\nWhat lands on your phone:\n\n```\n✅ New user\n━━━━━━━━━━━━━━━━━━━━━\nemail    alex@startup.com\nplan     pro\n━━━━━━━━━━━━━━━━━━━━━\nmyapp.com · 14:23\nsent via teleping\n\n🔴 Payment failed\n━━━━━━━━━━━━━━━━━━━━━\nerror    Stripe timeout\nuserId   usr_abc123\n━━━━━━━━━━━━━━━━━━━━━\nmyapp.com · 02:14\nsent via teleping\n\n[📂 Open in Cursor]  [🤖 Copy for Claude]\n```\n\n## Builder API\n\nCall any method with **only a label** (no data object) to get a `MessageBuilder`. Chain modifiers, call `.send()` once. LLM-friendly — describe what you want in a comment and Claude writes the chain.\n\n```typescript\nteleping.error('Stripe webhook failed')\n  .data({ userId, amount, stripeEvent: event.type })   // key-value context\n  .code(err.stack, 'typescript')                        // syntax-highlighted stack\n  .spoiler('userId')                                    // hide behind tap-to-reveal\n  .expand()                                             // collapsible data section\n  .button('claude')                                     // Copy for Claude\n  .button('cursor')                                     // Open in Cursor\n  .button('chatgpt')                                    // Copy for ChatGPT\n  .button('copy-stack')                                 // Copy raw stack\n  .button('copy-data')                                  // Copy data as JSON\n  .button('View in Stripe', 'https://dashboard.stripe.com/...')\n  .copyButton('Copy event ID', event.id)\n  .send()\n```\n\n| Method | Description |\n|---|---|\n| `.data(obj)` | Key-value context fields |\n| `.value(n)` | Numeric value (metric builders) |\n| `.code(content, lang?)` | Code block with optional syntax class |\n| `.spoiler(...keys)` | Hide data fields behind Telegram spoiler tag |\n| `.expand()` | Wrap data in collapsible blockquote |\n| `.button(preset)` | Add button by preset name |\n| `.button(text, url)` | URL button shorthand |\n| `.copyButton(text, content)` | Copy-to-clipboard button — no webhook needed |\n| `.send()` | Fire. Required. Call once at the end. |\n\n**Button presets:**\n\n| Preset | What it does |\n|---|---|\n| `'cursor'` | Opens exact `file:line` from stack trace in Cursor |\n| `'claude'` | One tap copies full error context → paste into Claude |\n| `'chatgpt'` | Same for ChatGPT |\n| `'copy-stack'` | Copies raw stack trace |\n| `'copy-data'` | Copies context data as formatted JSON |\n\n## Components\n\nStructured message formats — shadcn-style building blocks.\n\n```typescript\n// Card — any structured event\nteleping.card({\n  title: 'Deploy complete',\n  subtitle: 'production · v2.4.1',\n  fields: { duration: '48s', tests: '312 passed', coverage: '94%' },\n  level: 'success',\n  actions: [{ text: 'View on Vercel', url: 'https://vercel.com/...' }],\n})\n\n// Progress bar\nteleping.progress('Importing users', { current: 847, total: 1200, unit: 'users' })\n// → ▓▓▓▓▓▓▓▓▓▓░░░░░  847/1200 users (71%)\n\n// Table\nteleping.table('Top plans today', [\n  { plan: 'pro',     signups: 14, revenue: '$420' },\n  { plan: 'starter', signups: 38, revenue: '$190' },\n])\n\n// Checklist\nteleping.checklist('Deploy checklist', [\n  { label: 'Migrations run', done: true },\n  { label: 'Cache warmed',   done: true },\n  { label: 'Smoke tests',    done: false },\n])\n```\n\n## Vibe coding workflow\n\nYou're building in Cursor, shipping to Vercel, debugging with Claude. teleping is built for that loop.\n\n**Add this to your `CLAUDE.md` once** — Claude will instrument every new route correctly without you explaining it:\n\n```markdown\n## Notifications (teleping)\nAPI: teleping.log / .success / .warn / .error / .metric — fire-and-forget, no await\nBuilder: teleping.error('label').data({}).code(stack).button('claude').send()\nComponents: teleping.card() / .progress() / .table() / .checklist()\nConfig: TELEPING_TOKEN + TELEPING_CHAT in .env\nTest: npx teleping test\n```\n\n**The production debugging loop:**\n\n1. Something breaks at 2AM\n2. Your phone: `🔴 Stripe webhook failed` with full stack\n3. Tap **[Copy for Claude]** — error context is in clipboard\n4. Open Claude, paste, get the fix\n5. Or tap **[Open in Cursor]** — jumps to exact file and line\n\n## Real-world examples\n\n### Next.js + Supabase auth\n\n```typescript\n// app/api/auth/callback/route.ts\nexport async function GET(req: Request) {\n  const { data, error } = await supabase.auth.exchangeCodeForSession(code)\n\n  if (error) {\n    teleping.error('Auth failed', { error: error.message })\n    return redirect('/login?error=auth')\n  }\n\n  teleping.success('New signup', {\n    email: data.user.email,\n    provider: data.user.app_metadata.provider,\n  })\n  return redirect('/dashboard')\n}\n```\n\n### Stripe webhook\n\n```typescript\n// app/api/webhooks/stripe/route.ts\nswitch (event.type) {\n  case 'checkout.session.completed':\n    teleping.success('Payment received', {\n      amount: `$${session.amount_total / 100}`,\n      email: session.customer_email,\n      plan: session.metadata.plan,\n    })\n    break\n\n  case 'charge.failed':\n    teleping.error('Payment failed')\n      .data({ amount: `$${event.data.object.amount / 100}`, reason: event.data.object.failure_message })\n      .button('claude')\n      .send()\n    break\n}\n```\n\n### Global error handler\n\n```typescript\n// middleware.ts or app/api/_error.ts\nexport function onError(error: Error, req: Request) {\n  teleping.error(error.message, {\n    path: new URL(req.url).pathname,\n    stack: error.stack,\n    method: req.method,\n  })\n}\n```\n\n### Daily digest via cron\n\n```typescript\n// app/api/cron/digest/route.ts\nexport async function GET() {\n  await teleping.digest()\n  // → 📋 Digest — 42 events\n  //   ✅ 35 success  🔴 2 errors  ⚠️ 5 warnings\n}\n```\n\n## Features\n\n### Smart batching\n\n50 signups in 5 minutes? One message, not 50:\n\n```\n✅ 50× New signup\n━━━━━━━━━━━━━━━━━━━━━\n50 events batched\n━━━━━━━━━━━━━━━━━━━━━\nmyapp.com · 14:30\nsent via teleping\n```\n\n### Quiet hours\n\n```typescript\nteleping.init({\n  quietStart: 23,  // 11 PM\n  quietEnd: 7,     // 7 AM\n  timezone: 'America/New_York',\n})\n```\n\nNon-critical notifications hold until morning. **Errors always go through.**\n\n### Per-level routing\n\nRoute errors to a dedicated Telegram topic, metrics to a separate chat:\n\n```typescript\nteleping.init({\n  chatId: '-100main_chat',\n  routes: {\n    error:  { threadId: '42' },                        // → #errors topic\n    metric: { chatId: '-100metrics_chat' },             // → separate chat\n  },\n})\n```\n\n### Themes\n\n```typescript\nteleping.init({ theme: 'rich' })     // expandable blockquotes, code highlighting\nteleping.init({ theme: 'minimal' })  // default — identical to v0.1\nteleping.init({ theme: 'compact' })  // short separator, no bold\n```\n\n### Graceful degradation\n\nNo `TELEPING_TOKEN`? One `console.warn`. All calls become silent no-ops. Safe in tests, CI, and dev.\n\n## Config reference\n\n```typescript\nteleping.init({\n  token: 'bot_token',            // default: process.env.TELEPING_TOKEN\n  chatId: 'chat_id',             // default: process.env.TELEPING_CHAT\n  app: 'myapp.com',              // shown in every message footer\n  timezone: 'America/New_York',  // for quiet hours\n  quietStart: 23,                // hour 0–23\n  quietEnd: 7,\n  batchWindowMs: 300_000,        // dedup window, default 5 min\n  theme: 'rich',                 // 'rich' | 'minimal' | 'compact'\n  separator: '─────────────',    // override separator line\n  footer: 'myapp v2.1 · prod',   // extra line above \"sent via teleping\"\n  emoji: { error: '💥', success: '🚀' },  // override any level emoji\n  routes: {\n    error:  { chatId: '-100...', threadId: '42' },\n    metric: { chatId: '-100...' },\n  },\n  buttons: {\n    error:   ['cursor', 'claude'],  // add to every error message\n    default: [],\n  },\n})\n```\n\n## API reference\n\n### Core\n\n| Method | When to use | Emoji |\n|---|---|---|\n| `teleping.log(label, data?)` | Server events, job complete | ℹ️ |\n| `teleping.success(label, data?)` | Signup, payment, milestone | ✅ |\n| `teleping.warn(label, data?)` | Rate limit, retry, degraded | ⚠️ |\n| `teleping.error(label, data?)` | Exception, crash — always sends | 🔴 |\n| `teleping.metric(label, value)` | Revenue, user count, latency | 📊 |\n| `teleping.digest()` | Send stats summary, reset counters | 📋 |\n| `teleping.init(config)` | Explicit config, overrides env | — |\n\n### Components\n\n| Method | Signature |\n|---|---|\n| `teleping.card(opts)` | `{ title, subtitle?, fields?, level?, actions? }` |\n| `teleping.progress(label, opts)` | `label, { current, total, unit? }` |\n| `teleping.table(title, rows)` | `title, { [col]: string \\| number \\| boolean }[]` |\n| `teleping.checklist(title, items)` | `title, { label: string; done: boolean }[]` |\n\n### Power user\n\n```typescript\nimport { editMessage } from 'teleping'\n\n// live-update a message (e.g. deploy progress → deploy complete)\nawait editMessage({ token, chatId, messageId, text: 'Deploy complete ✅' })\n```\n\n## CLI\n\n```bash\nnpx teleping init   # guided setup — creates .env\nnpx teleping test   # sends a test message to verify config\n```\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**built for solo builders who ship fast and want to see what's happening.**\n\n[npm](https://npmjs.com/package/teleping) · [github](https://github.com/yerdaulet-damir/teleping) · [issues](https://github.com/yerdaulet-damir/teleping/issues)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyerdaulet-damir%2Fteleping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyerdaulet-damir%2Fteleping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyerdaulet-damir%2Fteleping/lists"}