fix: coalesce BlueBubbles link previews (#1981) (thanks @tyler6204)
This commit is contained in:
@@ -50,6 +50,7 @@ Status: unreleased.
|
|||||||
- **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed).
|
- **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed).
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
- BlueBubbles: coalesce inbound URL link preview messages. (#1981) Thanks @tyler6204.
|
||||||
- Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj.
|
- Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj.
|
||||||
- Telegram: wrap reasoning italics per line to avoid raw underscores. (#2181) Thanks @YuriNachos.
|
- Telegram: wrap reasoning italics per line to avoid raw underscores. (#2181) Thanks @YuriNachos.
|
||||||
- Voice Call: enforce Twilio webhook signature verification for ngrok URLs; disable ngrok free tier bypass by default.
|
- Voice Call: enforce Twilio webhook signature verification for ngrok URLs; disable ngrok free tier bypass by default.
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ type BlueBubblesDebounceEntry = {
|
|||||||
/**
|
/**
|
||||||
* Default debounce window for inbound message coalescing (ms).
|
* Default debounce window for inbound message coalescing (ms).
|
||||||
* This helps combine URL text + link preview balloon messages that BlueBubbles
|
* This helps combine URL text + link preview balloon messages that BlueBubbles
|
||||||
* sends as separate webhook events.
|
* sends as separate webhook events when no explicit inbound debounce config exists.
|
||||||
*/
|
*/
|
||||||
const DEFAULT_INBOUND_DEBOUNCE_MS = 350;
|
const DEFAULT_INBOUND_DEBOUNCE_MS = 350;
|
||||||
|
|
||||||
@@ -339,6 +339,17 @@ const targetDebouncers = new Map<
|
|||||||
ReturnType<BlueBubblesCoreRuntime["channel"]["debounce"]["createInboundDebouncer"]>
|
ReturnType<BlueBubblesCoreRuntime["channel"]["debounce"]["createInboundDebouncer"]>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
function resolveBlueBubblesDebounceMs(
|
||||||
|
config: ClawdbotConfig,
|
||||||
|
core: BlueBubblesCoreRuntime,
|
||||||
|
): number {
|
||||||
|
const inbound = config.messages?.inbound;
|
||||||
|
const hasExplicitDebounce =
|
||||||
|
typeof inbound?.debounceMs === "number" || typeof inbound?.byChannel?.bluebubbles === "number";
|
||||||
|
if (!hasExplicitDebounce) return DEFAULT_INBOUND_DEBOUNCE_MS;
|
||||||
|
return core.channel.debounce.resolveInboundDebounceMs({ cfg: config, channel: "bluebubbles" });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates or retrieves a debouncer for a webhook target.
|
* Creates or retrieves a debouncer for a webhook target.
|
||||||
*/
|
*/
|
||||||
@@ -349,7 +360,7 @@ function getOrCreateDebouncer(target: WebhookTarget) {
|
|||||||
const { account, config, runtime, core } = target;
|
const { account, config, runtime, core } = target;
|
||||||
|
|
||||||
const debouncer = core.channel.debounce.createInboundDebouncer<BlueBubblesDebounceEntry>({
|
const debouncer = core.channel.debounce.createInboundDebouncer<BlueBubblesDebounceEntry>({
|
||||||
debounceMs: DEFAULT_INBOUND_DEBOUNCE_MS,
|
debounceMs: resolveBlueBubblesDebounceMs(config, core),
|
||||||
buildKey: (entry) => {
|
buildKey: (entry) => {
|
||||||
const msg = entry.message;
|
const msg = entry.message;
|
||||||
// Build key from account + chat + sender to coalesce messages from same source
|
// Build key from account + chat + sender to coalesce messages from same source
|
||||||
|
|||||||
Reference in New Issue
Block a user