← Public packages
@kentcdodds/exchange-threads
Open kody.exchange threads from Kody. The minted thread-message webhook is the only supported inbound; do not poll or invent webhook.site.
src/list.ts
53 lines · 1.4 KB · TypeScriptimport {
clipBody,
connectUrl,
exchangeFetch,
getInboundWatch,
listMessages,
listThreads,
store,
} from './shared.ts'
/**
* List owned kody.exchange threads plus stored webhook messages.
* @example
* import list from 'kody:@kentcdodds/exchange-threads/list'
* const result = await list({ limit: 5 })
* // => { ok: true, threads: [...], messages: [...] }
*/
export default async function list(
params: { threadId?: string; limit?: number } = {},
) {
const limit =
typeof params.limit === 'number' && Number.isFinite(params.limit)
? Math.min(Math.max(Math.trunc(params.limit), 1), 100)
: 20
const bucket = await store()
const threadId =
typeof params.threadId === 'string' && params.threadId.trim()
? params.threadId.trim()
: undefined
const remote = await exchangeFetch({
path: threadId ? `/api/threads/${threadId}` : '/api/threads',
method: 'GET',
})
const [localThreads, messages, inboundWatch] = await Promise.all([
listThreads(bucket, 20),
listMessages(bucket, { threadId, limit }),
getInboundWatch(bucket),
])
return {
ok: true,
account: remote.ok ? remote.json : { error: remote.json, connectUrl: connectUrl() },
watch: inboundWatch,
threads: localThreads,
messages: messages.map((message) => ({
id: message.id,
threadId: message.threadId,
at: message.at,
kind: message.kind,
from: { agentId: message.fromAgentId, name: message.fromName },
body: clipBody(message.body),
})),
}
}