8000
Skip to content

yerdaulet-damir/teleping

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
 β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•
    β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ–ˆβ•—
    β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘
    β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•
    β•šβ•β•   β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•     β•šβ•β•β•šβ•β•  β•šβ•β•β•β• β•šβ•β•β•β•β•β•

like console.log but it arrives on your phone.
telegram alerts for solo builders β€” 1 import, 5 functions, zero deps.

npm tests license bundle zero deps


teleping


// your stripe webhook just broke at 2am.
// you're asleep. teleping is not.

import { teleping } from 'teleping'

// simple β€” drop anywhere, fire-and-forget
teleping.success('New user', { email: 'alex@startup.com', plan: 'pro' })
teleping.error('Payment failed', { amount: 15, reason: 'card_declined' })

// builder β€” full context, tap [Copy for Claude] from your phone
teleping.error('Stripe webhook failed')
  .data({ userId, amount, event: event.type })
  .code(err.stack, 'typescript')
  .button('claude')    // one tap β†’ error context in clipboard, ready for Claude
  .button('cursor')    // one tap β†’ opens exact file:line in Cursor
  .send()
DIY bot teleping
Setup write it yourself npm install teleping
Format ugly plain text emoji + separators + structured
50 same errors 50 messages, phone dies 1 batched message
3AM non-critical wakes you quiet hours suppress it
Error on phone stare at it [Open in Cursor] [Copy for Claude]
Every project rewrite from scratch 1 import

Why

You'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.

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.

shadcn/ui   β†’ beautiful components in 1 line
prisma      β†’ beautiful database queries in 1 line
teleping    β†’ beautiful production alerts in 1 line

Install

npm install teleping

Setup (2 minutes, one time)

  1. Message @BotFather on Telegram β†’ create a bot β†’ copy the token
  2. Start a chat with your new bot β†’ get your chat ID
  3. Add to .env:
TELEPING_TOKEN=your_bot_token
TELEPING_CHAT=your_chat_id

Or run the CLI β€” it does all of this:

npx teleping init   # creates .env with TELEPING_TOKEN + TELEPING_CHAT
npx teleping test   # sends a test message to verify

npm Package

Usage

import { teleping } from 'teleping'

// five functions. that's the whole API.
teleping.log('Server started', { port: 3000 })
teleping.success('New user', { email, plan })
teleping.warn('Rate limit hit', { ip, endpoint })
teleping.error('Payment failed', { error: err.message, userId })
teleping.metric('Monthly revenue', 4500)

What lands on your phone:

βœ… New user
━━━━━━━━━━━━━━━━━━━━━
email    alex@startup.com
plan     pro
━━━━━━━━━━━━━━━━━━━━━
myapp.com Β· 14:23
sent via teleping

πŸ”΄ Payment failed
━━━━━━━━━━━━━━━━━━━━━
error    Stripe timeout
userId   usr_abc123
━━━━━━━━━━━━━━━━━━━━━
myapp.com Β· 02:14
sent via teleping

[πŸ“‚ Open in Cursor]  [πŸ€– Copy for Claude]

Builder API

Call 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.

teleping.error('Stripe webhook failed')
  .data({ userId, amount, stripeEvent: event.type })   // key-value context
  .code(err.stack, 'typescript')                        // syntax-highlighted stack
  .spoiler('userId')                                    // hide behind tap-to-reveal
  .expand()                                             // collapsible data section
  .button('claude')                                     // Copy for Claude
  .button('cursor')                                     // Open in Cursor
  .button('chatgpt')                                    // Copy for ChatGPT
  .button('copy-stack')                                 // Copy raw stack
  .button('copy-data')                                  // Copy data as JSON
  .button('View in Stripe', 'https://dashboard.stripe.com/...')
  .copyButton('Copy event ID', event.id)
  .send()
Method Description
.data(obj) Key-value context fields
.value(n) Numeric value (metric builders)
.code(content, lang?) Code block with optional syntax class
.spoiler(...keys) Hide data fields behind Telegram spoiler tag
.expand() Wrap data in collapsible blockquote
.button(preset) Add button by preset name
.button(text, url) URL button shorthand
.copyButton(text, content) Copy-to-clipboard button β€” no webhook needed
.send() Fire. Required. Call once at the end.

Button presets:

Preset What it does
'cursor' Opens exact file:line from stack trace in Cursor
'claude' One tap copies full error context β†’ paste into Claude
'chatgpt' Same for ChatGPT
'copy-stack' Copies raw stack trace
'copy-data' Copies context data as formatted JSON

Components

Structured message formats β€” shadcn-style building blocks.

// Card β€” any structured event
teleping.card({
  title: 'Deploy complete',
  subtitle: 'production Β· v2.4.1',
  fields: { duration: '48s', tests: '312 passed', coverage: '94%' },
  level: 'success',
  actions: [{ text: 'View on Vercel', url: 'https://vercel.com/...' }],
})

// Progress bar
teleping.progress('Importing users', { current: 847, total: 1200, unit: 'users' })
// β†’ β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–‘β–‘β–‘β–‘β–‘  847/1200 users (71%)

// Table
teleping.table('Top plans today', [
  { plan: 'pro',     signups: 14, revenue: '$420' },
  { plan: 'starter', signups: 38, revenue: '$190' },
])

// Checklist
teleping.checklist('Deploy checklist', [
  { label: 'Migrations run', done: true },
  { label: 'Cache warmed',   done: true },
  { label: 'Smoke tests',    done: false },
])

Vibe coding workflow

You're building in Cursor, shipping to Vercel, debugging with Claude. teleping is built for that loop.

Add this to your CLAUDE.md once β€” Claude will instrument every new route correctly without you explaining it:

## Notifications (teleping)
API: teleping.log / .success / .warn / .error / .metric β€” fire-and-forget, no await
Builder: teleping.error('label').data({}).code(stack).button('claude').send()
Components: teleping.card() / .progress() / .table() / .checklist()
Config: TELEPING_TOKEN + TELEPING_CHAT in .env
Test: npx teleping test

The production debugging loop:

  1. Something breaks at 2AM
  2. Your phone: πŸ”΄ Stripe webhook failed with full stack
  3. Tap [Copy for Claude] β€” error context is in clipboard
  4. Open Claude, paste, get the fix
  5. Or tap [Open in Cursor] β€” jumps to exact file and line

Real-world examples

Next.js + Supabase auth

// app/api/auth/callback/route.ts
export async function GET(req: Request) {
  const { data, error } = await supabase.auth.exchangeCodeForSession(code)

  if (error) {
    teleping.error('Auth failed', { error: error.message })
    return redirect('/login?error=auth')
  }

  teleping.success('New signup', {
    email: data.user.email,
    provider: data.user.app_metadata.provider,
  })
  return redirect('/dashboard')
}

Stripe webhook

// app/api/webhooks/stripe/route.ts
switch (event.type) {
  case 'checkout.session.completed':
    teleping.success('Payment received', {
      amount: `$${session.amount_total / 100}`,
      email: session.customer_email,
      plan: session.metadata.plan,
    })
    break

  case 'charge.failed':
    teleping.error('Payment failed')
      .data({ amount: `$${event.data.object.amount / 100}`, reason: event.data.object.failure_message })
      .button('claude')
      .send()
    break
}

Global error handler

// middleware.ts or app/api/_error.ts
export function onError(error: Error, req: Request) {
  teleping.error(error.message, {
    path: new URL(req.url).pathname,
    stack: error.stack,
    method: req.method,
  })
}

Daily digest via cron

// app/api/cron/digest/route.ts
export async function GET() {
  await teleping.digest()
  // β†’ πŸ“‹ Digest β€” 42 events
  //   βœ… 35 success  πŸ”΄ 2 errors  ⚠️ 5 warnings
}

Features

Smart batching

50 signups in 5 minutes? One message, not 50:

βœ… 50Γ— New signup
━━━━━━━━━━━━━━━━━━━━━
50 events batched
━━━━━━━━━━━━━━━━━━━━━
myapp.com Β· 14:30
sent via teleping

Quiet hours

teleping.init({
  quietStart: 23,  // 11 PM
  quietEnd: 7,     // 7 AM
  timezone: 'America/New_York',
})

Non-critical notifications hold until morning. Errors always go through.

Per-level routing

Route errors to a dedicated Telegram topic, metrics to a separate chat:

teleping.init({
  chatId: '-100main_chat',
  routes: {
    error:  { threadId: '42' },                        // β†’ #errors topic
    metric: { chatId: '-100metrics_chat' },             // β†’ separate chat
  },
})

Themes

teleping.init({ theme: 'rich' })     // expandable blockquotes, code highlighting
teleping.init({ theme: 'minimal' })  // default β€” identical to v0.1
teleping.init({ theme: 'compact' })  // short separator, no bold

Graceful degradation

No TELEPING_TOKEN? One console.warn. All calls become silent no-ops. Safe in tests, CI, and dev.

Config reference

teleping.init({
  token: 'bot_token',            // default: process.env.TELEPING_TOKEN
  chatId: 'chat_id',             // default: process.env.TELEPING_CHAT
  app: 'myapp.com',              // shown in every message footer
  timezone: 'America/New_York',  // for quiet hours
  quietStart: 23,                // hour 0–23
  quietEnd: 7,
  batchWindowMs: 300_000,        // dedup window, default 5 min
  theme: 'rich',                 // 'rich' | 'minimal' | 'compact'
  separator: '─────────────',    // override separator line
  footer: 'myapp v2.1 Β· prod',   // extra line above "sent via teleping"
  emoji: { error: 'πŸ’₯', success: 'πŸš€' },  // override any level emoji
  routes: {
    error:  { chatId: '-100...', threadId: '42' },
    metric: { chatId: '-100...' },
  },
  buttons: {
    error:   ['cursor', 'claude'],  // add to every error message
    default: [],
  },
})

API reference

Core

Method When to use Emoji
teleping.log(label, data?) Server events, job complete ℹ️
teleping.success(label, data?) Signup, payment, milestone βœ…
teleping.warn(label, data?) Rate limit, retry, degraded ⚠️
teleping.error(label, data?) Exception, crash β€” always sends πŸ”΄
teleping.metric(label, value) Revenue, user count, latency πŸ“Š
teleping.digest() Send stats summary, reset counters πŸ“‹
teleping.init(config) Explicit config, overrides env β€”

Components

Method Signature
teleping.card(opts) { title, subtitle?, fields?, level?, actions? }
teleping.progress(label, opts) label, { current, total, unit? }
teleping.table(title, rows) title, { [col]: string | number | boolean }[]
teleping.checklist(title, items) title, { label: string; done: boolean }[]

Power user

import { editMessage } from 'teleping'

// live-update a message (e.g. deploy progress β†’ deploy complete)
await editMessage({ token, chatId, messageId, text: 'Deploy complete βœ…' })

CLI

npx teleping init   # guided setup β€” creates .env
npx teleping test   # sends a test message to verify config

built for solo builders who ship fast and want to see what's happening.

npm Β· github Β· issues

About

like console.log but it arrives on your phone. telegram alerts for vibe coders β€” 1 import, 5 functions, zero deps.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

0