npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lo-ink/bot-http-lo

v0.6.3

Published

Compatibility exports for native HTTP transport in LO Bot SDK

Readme

@lo-ink/bot-http-lo

Version 0.6 re-exports the native HTTP implementation from @lo-ink/bot-sdk 0.5. New LO applications install only the SDK and use createLoBotClient(options). Existing transport, webhook decoder and error imports remain aliases of the SDK.

Server-side HTTP transport for @lo-ink/bot-sdk and the LO Bot API.

import { createBotClient } from "@lo-ink/bot-sdk";
import { createLoHttpBotTransport } from "@lo-ink/bot-http-lo";

const transport = createLoHttpBotTransport({
  token: process.env.LO_BOT_TOKEN!,
});
const bot = createBotClient(transport);

const identity = await bot.getIdentity();
await bot.sendMessage({
  conversationId: "9007199254740993",
  text: `Hello from ${identity.name}`,
});

The default endpoint is https://api.lo.ink. A custom endpoint must use HTTPS. Tests may explicitly enable plain HTTP for an exact loopback host:

createLoHttpBotTransport({
  token: "1:test-token",
  baseUrl: "http://127.0.0.1:8080",
  allowInsecureLoopback: true,
});

Every request is a single POST to /bot<TOKEN>/<method>. Redirects are refused because the credential is in the path. The transport never retries, never includes credential URLs in errors, preserves decimal identifiers as strings, and forwards cancellation to fetch.

HttpBotError exposes the canonical SDK error code, HTTP status, upstream platformCode, and optional retryAfterSeconds. Messages are intentionally generic. Version 0.3 adds a bounded, sanitized BadRequest.description for decisions such as invalidating a cached file ID.

Secretary extension (0.2)

The transport also implements SecretaryTransport for createSecretaryClient(transport). Business events returned by getUpdates are normalized to the SDK's secretary union; ordinary bot calls keep their existing wire behavior. parseLoBotWebhookUpdate(rawBody) uses the same decoder and preserves 64-bit IDs. Authenticate the webhook secret before calling it; parsing alone never authenticates a request. decodeLoBotUpdate accepts an already parsed object, whose unsafe numeric IDs are rejected rather than rounded.

Connection IDs, source context and stable request keys scope every delegated write. Context identifiers and bulk message IDs are serialized as decimal strings; credential generation and owner identity are derived by the server, never from caller-provided grant fields. Receiving, reading, sending and deleting remain independent. deleteAll is explicit and requires its separate owner permission.

See the reference bot for durable polling, authenticated webhooks, owner/chat isolation, replay, revoke and opt-in. These are LO-native secretary operations.

Media, keyboards and errors

Use the current supported @lo-ink/bot-sdk peer version. The transport builds exact Bot API JSON for replyMarkup and setChatMenuButton, and multipart for uploaded photo/document/voice inputs. It lets fetch set the multipart boundary; reply_markup is a JSON string. Streams are bounded before any network request and cancelled with the request signal. File IDs are reused as JSON; photo results select the final largest size.

API failures are SDK RateLimited, NotAllowed, BadRequest or Unavailable instances, also instances of the existing HttpBotError export. Existing codes and retryAfterSeconds remain compatible; RateLimited adds retryAfterSec. BadRequest.description is bounded and redacts credentials and URLs. No implicit retry exists. Voice upload uses AAC/M4A/MP4; voice captions and media URLs fail before fetch. See bot-sdk's README for limits and cache invalidation.

Files and video (0.4.0)

The transport supports native video uploads with upload-only metadata and thumbnail, cached audio, homogeneous photo/document albums, getFile, and bounded streaming downloads. Media sends use inline keyboards. Albums carry one LO message ID shared by all returned items; deleting that ID deletes the album.

Video calls allow a 90-second preparation deadline by default. Explicit client or per-call deadlines take precedence. File downloads use authenticated paths, reject redirects and traversal, and accept a persistent signal; consume or cancel the returned stream. Missing file paths remain absent.

A genuine API 429 refusal sets details.safeToRetry; unknown HTTP failures do not. Use the native SDK's explicit retryRejected only with replayable input. Network failures and 5xx sends are never repeated automatically.

Native keyboard values in bot-sdk 0.4 use camelCase. The transport converts them to the server contract and checks the serialized keyboard size before fetch. See bot-sdk’s upgrade note before updating 0.3 applications.

LO app-data service updates may use a zero stored-message sentinel. The adapter omits appData.messageId in that case and preserves the real update cursor and sender; it does not invent a message identifier. Signed LO paths from getFile are encoded as one file-route component.

@lo-ink/bot-http-lo/contract exports the server-generated JSON manifest. Its source digests are checked against the declared Git revision. A local working-tree fixture has source.commit: null, explicit base commit and fingerprint; it is unreleased and does not identify a deployed server. Regenerate against a committed server revision before release.