Files
oh-my-pi-telegram/lib/time-injection.ts
Evandro Fonseca Junior d1d04001d0
Release / release (push) Failing after 5s
Validate / validate (push) Failing after 5m21s
chore: fork @llblab/[email protected] as @evandrodevbr/oh-my-pi-telegram
Fork of upstream llblab/[email protected].0 (SHA afe09c5) repackaged as a
drop-in extension for can1357/oh-my-pi (omp >= 16.5.2).

Changes vs upstream:
- Rename package: @llblab/pi-telegram -> @evandrodevbr/oh-my-pi-telegram
- Bump version: 0.22.0 -> 0.22.0-evandro.1
- Update repository/homepage/bugs URLs to evandrodevbr
- Add omp field in package.json (displayName + compatibleWith)
- README: prepend 'Oh My Pi (omp) Compatibility' section with install
  commands, verified-components table, upstream lineage, and rationale
- CHANGELOG: add '0.22.0-evandro.1' entry under Unreleased
- docs/: rename @llblab/pi-telegram imports to @evandrodevbr/oh-my-pi-telegram
- tests/public-api.test.ts: rename package import paths

Gates re-run on the fork:
- npm run typecheck  -> tsc --noEmit (success)
- npm test           -> 1229 pass / 0 fail / 1 platform-only skip
- npm run audit      -> found 0 vulnerabilities
- npm run pack:check -> evandrodevbr-oh-my-pi-telegram-0.22.0-evandro.1.tgz

Verified:
- omp install --link ./pi-telegram -> Linked OK
- omp plugin list -> @evandrodevbr/[email protected].0-evandro.1

Upstream lineage: badlogic/pi-telegram -> llblab/pi-telegram (0.22.0) -> evandrodevbr/oh-my-pi-telegram (this fork)
2026-07-15 14:18:16 -03:00

79 lines
2.2 KiB
TypeScript

/**
* Telegram per-chat time injection runtime
* Zones: telegram inbound, prompt content
* Owns the formatted `[time]` line and the per-chat interval bookkeeping that decides when to emit it
*/
import type { ResolvedTelegramTimeConfig } from "./config.ts";
export interface TimeInjectionRuntime {
resolveLine: (chatId: number, now?: Date) => string | null;
}
export interface TimeInjectionRuntimeDeps {
getConfig: () => ResolvedTelegramTimeConfig;
recordRuntimeEvent?: (
category: string,
error: unknown,
details?: Record<string, unknown>,
) => void;
}
export function formatTelegramTimeInjectionLine(
now: Date,
timezone: string,
): string {
const parts = new Intl.DateTimeFormat("en-CA", {
timeZone: timezone,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
}).formatToParts(now);
const get = (type: Intl.DateTimeFormatPartTypes): string =>
parts.find((part) => part.type === type)?.value ?? "";
const year = get("year");
const month = get("month");
const day = get("day");
const hourRaw = get("hour");
const hour = hourRaw === "24" ? "00" : hourRaw;
const minute = get("minute");
const second = get("second");
return `${year}-${month}-${day} ${hour}:${minute}:${second} ${timezone}`;
}
export function createTimeInjectionRuntime(
deps: TimeInjectionRuntimeDeps,
): TimeInjectionRuntime {
const lastInjectedAt = new Map<number, number>();
return {
resolveLine: (chatId, now = new Date()) => {
const config = deps.getConfig();
if (config.injectionMode === "hidden") return null;
let line: string;
try {
line = formatTelegramTimeInjectionLine(now, config.timezone);
} catch (error) {
deps.recordRuntimeEvent?.("time-injection", error, {
timezone: config.timezone,
});
return null;
}
if (config.injectionMode === "always") return line;
const previous = lastInjectedAt.get(chatId);
const nowMs = now.getTime();
if (
previous !== undefined &&
nowMs - previous < config.interval
) {
return null;
}
lastInjectedAt.set(chatId, nowMs);
return line;
},
};
}