pub struct WhatsAppBridge {
outbound_tx: UnboundedSender<OutboundMsg>,
health: Arc<Mutex<BridgeHealth>>,
app_secret: String,
webhook_verify_token: String,
target_agent: Option<String>,
window_state: Arc<Mutex<HashMap<String, u64>>>,
}Fields§
§outbound_tx: UnboundedSender<OutboundMsg>§health: Arc<Mutex<BridgeHealth>>§app_secret: String§webhook_verify_token: String§target_agent: Option<String>§window_state: Arc<Mutex<HashMap<String, u64>>>Per-sender (WhatsApp phone number) last-inbound timestamp (unix ms), for 24h customer service window tracking (spec §3.3). Not persisted to disk in v1 — a restart means the bridge falls back to templates until the next inbound message re-opens the window, an accepted degradation per the spec.
Implementations§
Source§impl WhatsAppBridge
impl WhatsAppBridge
Sourcepub fn init_global(config: WhatsAppConfig, http: Client)
pub fn init_global(config: WhatsAppConfig, http: Client)
Initialize the global WhatsApp bridge and start the outbound send background task. No-op if already initialized.
Unlike Discord/Telegram/Slack, there is no inbound connection loop to
spawn here — inbound delivery is passive HTTP handled by
webhook::handle_verify/handle_inbound, already registered
unconditionally on the main axum router (see server/mod.rs)
regardless of whether init_global has run. Those handlers return
503 via WhatsAppBridge::get() returning None until this runs.
pub fn get() -> Option<&'static WhatsAppBridge>
Sourcepub fn send(&self, msg: OutboundMsg) -> Result<(), String>
pub fn send(&self, msg: OutboundMsg) -> Result<(), String>
Enqueue a message for delivery via the Graph API. Returns error if the bridge task has exited (should not happen in normal operation).
pub fn health(&self) -> BridgeHealth
pub(crate) fn app_secret(&self) -> &str
pub(crate) fn verify_token(&self) -> &str
pub(crate) fn target_agent(&self) -> Option<&String>
Sourcepub(crate) fn record_inbound(&self, from_id: &str)
pub(crate) fn record_inbound(&self, from_id: &str)
Called by webhook::handle_inbound on each valid inbound message, to
update the 24h window state (spec §3.3) and the health snapshot’s
last_event_at.
Keys on rest::normalize_phone(from_id), not the raw id, so this
matches whatever normalized form rest::send_message looks the
number up under — Meta’s inbound from has no + prefix, but a
caller sending via handle_whatsapp_send may supply one (E.164);
without a shared normalization the window lookup always missed
(found via review).
Trait Implementations§
Source§impl MessagingBridge for WhatsAppBridge
impl MessagingBridge for WhatsAppBridge
Source§fn health(&self) -> BridgeHealth
fn health(&self) -> BridgeHealth
Arc<Mutex<BridgeHealth>> guarded by a short-lived lock).Auto Trait Implementations§
impl Freeze for WhatsAppBridge
impl RefUnwindSafe for WhatsAppBridge
impl Send for WhatsAppBridge
impl Sync for WhatsAppBridge
impl Unpin for WhatsAppBridge
impl UnsafeUnpin for WhatsAppBridge
impl UnwindSafe for WhatsAppBridge
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more