Skip to content

Commit

Permalink
Merge pull request #959 from getlipa/feature/report-analytics-when-ha…
Browse files Browse the repository at this point in the history
…ndling-notification

Report analytics when handling notification
  • Loading branch information
danielgranhao authored Mar 5, 2024
2 parents f648e5d + 5e217a7 commit 9636c06
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 9 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 27 additions & 4 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,23 @@ impl LipaEventListener {

impl EventListener for LipaEventListener {
fn on_event(&self, e: BreezEvent) {
report_event_for_analytics(&e, &self.analytics_interceptor);
match e {
BreezEvent::NewBlock { .. } => {}
BreezEvent::InvoicePaid { details } => {
self.analytics_interceptor
.request_succeeded(details.clone());
self.events_callback.payment_received(details.payment_hash)
}
BreezEvent::Synced => {
self.events_callback.synced();
}
BreezEvent::PaymentSucceed { details } => {
if let PaymentDetails::Ln { data } = details.details.clone() {
self.analytics_interceptor.pay_succeeded(details);
self.events_callback
.payment_sent(data.payment_hash, data.payment_preimage)
}
}
BreezEvent::PaymentFailed { details } => {
if let Some(invoice) = details.invoice.clone() {
self.analytics_interceptor.pay_failed(details);
self.events_callback.payment_failed(invoice.payment_hash)
}
}
Expand All @@ -51,3 +48,29 @@ impl EventListener for LipaEventListener {
}
}
}

pub(crate) fn report_event_for_analytics(
e: &BreezEvent,
analytics_interceptor: &AnalyticsInterceptor,
) {
match e {
BreezEvent::NewBlock { .. } => {}
BreezEvent::InvoicePaid { details } => {
analytics_interceptor.request_succeeded(details.clone());
}
BreezEvent::Synced => {}
BreezEvent::PaymentSucceed { details } => {
if let PaymentDetails::Ln { .. } = details.details.clone() {
analytics_interceptor.pay_succeeded(details.clone());
}
}
BreezEvent::PaymentFailed { details } => {
if details.invoice.is_some() {
analytics_interceptor.pay_failed(details.clone());
}
}
BreezEvent::BackupStarted => {}
BreezEvent::BackupSucceeded => {}
BreezEvent::BackupFailed { .. } => {}
}
}
59 changes: 56 additions & 3 deletions src/notification_handling.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
use crate::analytics::{derive_analytics_keys, AnalyticsInterceptor};
use crate::async_runtime::AsyncRuntime;
use crate::auth::build_async_auth;
use crate::data_store::DataStore;
use crate::environment::Environment;
use crate::errors::Result;
use crate::event::report_event_for_analytics;
use crate::logger::init_logger_once;
use crate::{enable_backtrace, start_sdk, Config, RuntimeErrorCode, LOGS_DIR, LOG_LEVEL};
use crate::{
enable_backtrace, sanitize_input, start_sdk, Config, RuntimeErrorCode, UserPreferences,
DB_FILENAME, LOGS_DIR, LOG_LEVEL,
};
use breez_sdk_core::{BreezEvent, BreezServices, EventListener, PaymentStatus};
use log::{debug, error};
use parrot::AnalyticsClient;
use perro::{permanent_failure, MapToError};
use serde::Deserialize;
use std::path::Path;
use std::sync::mpsc::{Receiver, RecvTimeoutError, Sender};
use std::sync::{mpsc, Arc};
use std::sync::{mpsc, Arc, Mutex};
use std::time::{Duration, Instant};

const TIMEOUT: Duration = Duration::from_secs(60);
Expand Down Expand Up @@ -62,7 +70,11 @@ pub fn handle_notification(
let rt = AsyncRuntime::new()?;

let (tx, rx) = mpsc::channel();
let event_listener = Box::new(NotificationHandlerEventListener { event_sender: tx });
let analytics_interceptor = build_analytics_interceptor(&config, &rt)?;
let event_listener = Box::new(NotificationHandlerEventListener::new(
tx,
analytics_interceptor,
));
let environment = Environment::load(config.environment)?;
let sdk = rt
.handle()
Expand All @@ -75,6 +87,36 @@ pub fn handle_notification(
}
}

fn build_analytics_interceptor(config: &Config, rt: &AsyncRuntime) -> Result<AnalyticsInterceptor> {
let user_preferences = Arc::new(Mutex::new(UserPreferences {
fiat_currency: config.fiat_currency.clone(),
timezone_config: config.timezone_config.clone(),
}));

let environment = Environment::load(config.environment)?;
let strong_typed_seed = sanitize_input::strong_type_seed(&config.seed)?;
let async_auth = Arc::new(build_async_auth(
&strong_typed_seed,
environment.backend_url.clone(),
)?);

let analytics_client = AnalyticsClient::new(
environment.backend_url.clone(),
derive_analytics_keys(&strong_typed_seed)?,
Arc::clone(&async_auth),
);

let db_path = format!("{}/{DB_FILENAME}", config.local_persistence_path);
let data_store = DataStore::new(&db_path)?;
let analytics_config = data_store.retrieve_analytics_config()?;
Ok(AnalyticsInterceptor::new(
analytics_client,
Arc::clone(&user_preferences),
rt.handle(),
analytics_config,
))
}

fn handle_payment_received_notification(
rt: AsyncRuntime,
sdk: Arc<BreezServices>,
Expand Down Expand Up @@ -135,10 +177,21 @@ enum Payload {

struct NotificationHandlerEventListener {
event_sender: Sender<BreezEvent>,
analytics_interceptor: AnalyticsInterceptor,
}

impl NotificationHandlerEventListener {
fn new(event_sender: Sender<BreezEvent>, analytics_interceptor: AnalyticsInterceptor) -> Self {
NotificationHandlerEventListener {
event_sender,
analytics_interceptor,
}
}
}

impl EventListener for NotificationHandlerEventListener {
fn on_event(&self, e: BreezEvent) {
report_event_for_analytics(&e, &self.analytics_interceptor);
let _ = self.event_sender.send(e);
}
}
Expand Down

0 comments on commit 9636c06

Please sign in to comment.