UNPKG

@gguf/claw

Version:

WhatsApp gateway CLI (Baileys web) with Pi RPC agent

132 lines (117 loc) 2.94 kB
import { scot, da } from "@urbit/aura"; export type TlonPokeApi = { poke: (params: { app: string; mark: string; json: unknown }) => Promise<unknown>; }; type SendTextParams = { api: TlonPokeApi; fromShip: string; toShip: string; text: string; }; export async function sendDm({ api, fromShip, toShip, text }: SendTextParams) { const story = [{ inline: [text] }]; const sentAt = Date.now(); const idUd = scot("ud", da.fromUnix(sentAt)); const id = `${fromShip}/${idUd}`; const delta = { add: { memo: { content: story, author: fromShip, sent: sentAt, }, kind: null, time: null, }, }; const action = { ship: toShip, diff: { id, delta }, }; await api.poke({ app: "chat", mark: "chat-dm-action", json: action, }); return { channel: "tlon", messageId: id }; } type SendGroupParams = { api: TlonPokeApi; fromShip: string; hostShip: string; channelName: string; text: string; replyToId?: string | null; }; export async function sendGroupMessage({ api, fromShip, hostShip, channelName, text, replyToId, }: SendGroupParams) { const story = [{ inline: [text] }]; const sentAt = Date.now(); // Format reply ID as @ud (with dots) - required for Tlon to recognize thread replies let formattedReplyId = replyToId; if (replyToId && /^\d+$/.test(replyToId)) { try { formattedReplyId = formatUd(BigInt(replyToId)); } catch { // Fall back to raw ID if formatting fails } } const action = { channel: { nest: `chat/${hostShip}/${channelName}`, action: formattedReplyId ? { // Thread reply - needs post wrapper around reply action // ReplyActionAdd takes Memo: {content, author, sent} - no kind/blob/meta post: { reply: { id: formattedReplyId, action: { add: { content: story, author: fromShip, sent: sentAt, }, }, }, }, } : { // Regular post post: { add: { content: story, author: fromShip, sent: sentAt, kind: "/chat", blob: null, meta: null, }, }, }, }, }; await api.poke({ app: "channels", mark: "channel-action-1", json: action, }); return { channel: "tlon", messageId: `${fromShip}/${sentAt}` }; } export function buildMediaText(text: string | undefined, mediaUrl: string | undefined): string { const cleanText = text?.trim() ?? ""; const cleanUrl = mediaUrl?.trim() ?? ""; if (cleanText && cleanUrl) { return `${cleanText}\n${cleanUrl}`; } if (cleanUrl) { return cleanUrl; } return cleanText; }