diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 11951c8c0..d7218c79f 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -6248,7 +6248,7 @@ void dc_event_unref(dc_event_t* event); /** - * webxdc status update received. + * Webxdc status update received. * To get the received status update, use dc_get_webxdc_status_updates() with * `serial` set to the last known update * (in case of special bots, `status_update_serial` from `data2` @@ -6283,6 +6283,15 @@ void dc_event_unref(dc_event_t* event); #define DC_EVENT_WEBXDC_REALTIME_DATA 2150 +/** + * Advertisement for ephemeral peer channel communication received. + * This can be used by bots to initiate peer-to-peer communication from their side. + * @param data1 (int) msg_id + * @param data2 0 + */ + +#define DC_EVENT_WEBXDC_REALTIME_ADVERTISEMENT 2151 + /** * Tells that the Background fetch was completed (or timed out). * diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 2b3dab637..e34a71982 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -563,6 +563,7 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int EventType::WebxdcStatusUpdate { .. } => 2120, EventType::WebxdcInstanceDeleted { .. } => 2121, EventType::WebxdcRealtimeData { .. } => 2150, + EventType::WebxdcRealtimeAdvertisementReceived { .. } => 2151, EventType::AccountsBackgroundFetchDone => 2200, EventType::ChatlistChanged => 2300, EventType::ChatlistItemChanged { .. } => 2301, @@ -621,6 +622,7 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc: } EventType::WebxdcRealtimeData { msg_id, .. } | EventType::WebxdcStatusUpdate { msg_id, .. } + | EventType::WebxdcRealtimeAdvertisementReceived { msg_id } | EventType::WebxdcInstanceDeleted { msg_id, .. } => msg_id.to_u32() as libc::c_int, EventType::ChatlistItemChanged { chat_id } => { chat_id.unwrap_or_default().to_u32() as libc::c_int @@ -666,6 +668,7 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc: | EventType::ChatlistItemChanged { .. } | EventType::ConfigSynced { .. } | EventType::ChatModified(_) + | EventType::WebxdcRealtimeAdvertisementReceived { .. } | EventType::EventChannelOverflow { .. } => 0, EventType::MsgsChanged { msg_id, .. } | EventType::ReactionsChanged { msg_id, .. } @@ -733,6 +736,7 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut | EventType::IncomingMsgBunch { .. } | EventType::ChatlistItemChanged { .. } | EventType::ChatlistChanged + | EventType::WebxdcRealtimeAdvertisementReceived { .. } | EventType::EventChannelOverflow { .. } => ptr::null_mut(), EventType::ConfigureProgress { comment, .. } => { if let Some(comment) = comment { diff --git a/deltachat-jsonrpc/src/api/types/events.rs b/deltachat-jsonrpc/src/api/types/events.rs index f72a183e0..b282bad89 100644 --- a/deltachat-jsonrpc/src/api/types/events.rs +++ b/deltachat-jsonrpc/src/api/types/events.rs @@ -244,6 +244,11 @@ pub enum EventType { #[serde(rename_all = "camelCase")] WebxdcRealtimeData { msg_id: u32, data: Vec }, + /// Advertisement received over an ephemeral peer channel. + /// This can be used by bots to initiate peer-to-peer communication from their side. + #[serde(rename_all = "camelCase")] + WebxdcRealtimeAdvertisementReceived { msg_id: u32 }, + /// Inform that a message containing a webxdc instance has been deleted #[serde(rename_all = "camelCase")] WebxdcInstanceDeleted { msg_id: u32 }, @@ -373,6 +378,11 @@ impl From for EventType { msg_id: msg_id.to_u32(), data, }, + CoreEventType::WebxdcRealtimeAdvertisementReceived { msg_id } => { + WebxdcRealtimeAdvertisementReceived { + msg_id: msg_id.to_u32(), + } + } CoreEventType::WebxdcInstanceDeleted { msg_id } => WebxdcInstanceDeleted { msg_id: msg_id.to_u32(), }, diff --git a/node/constants.js b/node/constants.js index 1eaed5ccb..36ac5a556 100644 --- a/node/constants.js +++ b/node/constants.js @@ -67,6 +67,7 @@ module.exports = { DC_EVENT_SMTP_MESSAGE_SENT: 103, DC_EVENT_WARNING: 300, DC_EVENT_WEBXDC_INSTANCE_DELETED: 2121, + DC_EVENT_WEBXDC_REALTIME_ADVERTISEMENT: 2151, DC_EVENT_WEBXDC_REALTIME_DATA: 2150, DC_EVENT_WEBXDC_STATUS_UPDATE: 2120, DC_GCL_ADD_ALLDONE_HINT: 4, diff --git a/node/events.js b/node/events.js index 611628b05..de02aa7f5 100644 --- a/node/events.js +++ b/node/events.js @@ -38,6 +38,7 @@ module.exports = { 2120: 'DC_EVENT_WEBXDC_STATUS_UPDATE', 2121: 'DC_EVENT_WEBXDC_INSTANCE_DELETED', 2150: 'DC_EVENT_WEBXDC_REALTIME_DATA', + 2151: 'DC_EVENT_WEBXDC_REALTIME_ADVERTISEMENT', 2200: 'DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE', 2300: 'DC_EVENT_CHATLIST_CHANGED', 2301: 'DC_EVENT_CHATLIST_ITEM_CHANGED', diff --git a/node/lib/constants.ts b/node/lib/constants.ts index c901a0c7b..93cf45814 100644 --- a/node/lib/constants.ts +++ b/node/lib/constants.ts @@ -67,6 +67,7 @@ export enum C { DC_EVENT_SMTP_MESSAGE_SENT = 103, DC_EVENT_WARNING = 300, DC_EVENT_WEBXDC_INSTANCE_DELETED = 2121, + DC_EVENT_WEBXDC_REALTIME_ADVERTISEMENT = 2151, DC_EVENT_WEBXDC_REALTIME_DATA = 2150, DC_EVENT_WEBXDC_STATUS_UPDATE = 2120, DC_GCL_ADD_ALLDONE_HINT = 4, @@ -343,6 +344,7 @@ export const EventId2EventName: { [key: number]: string } = { 2120: 'DC_EVENT_WEBXDC_STATUS_UPDATE', 2121: 'DC_EVENT_WEBXDC_INSTANCE_DELETED', 2150: 'DC_EVENT_WEBXDC_REALTIME_DATA', + 2151: 'DC_EVENT_WEBXDC_REALTIME_ADVERTISEMENT', 2200: 'DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE', 2300: 'DC_EVENT_CHATLIST_CHANGED', 2301: 'DC_EVENT_CHATLIST_ITEM_CHANGED', diff --git a/src/events/payload.rs b/src/events/payload.rs index d8d842edf..69302a9a9 100644 --- a/src/events/payload.rs +++ b/src/events/payload.rs @@ -288,6 +288,13 @@ pub enum EventType { data: Vec, }, + /// Advertisement received over an ephemeral peer channel. + /// This can be used by bots to initiate peer-to-peer communication from their side. + WebxdcRealtimeAdvertisementReceived { + /// Message ID of the webxdc instance. + msg_id: MsgId, + }, + /// Inform that a message containing a webxdc instance has been deleted. WebxdcInstanceDeleted { /// ID of the deleted message. diff --git a/src/peer_channels.rs b/src/peer_channels.rs index 891dd7826..614e1bf46 100644 --- a/src/peer_channels.rs +++ b/src/peer_channels.rs @@ -576,6 +576,13 @@ mod tests { .unwrap(); bob.recv_msg_trash(&alice.pop_sent_msg().await).await; + loop { + let event = bob.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeAdvertisementReceived { msg_id } = event.typ { + assert!(msg_id == alice_webxdc.id); + break; + } + } let bob_iroh = bob.get_or_try_init_peer_channel().await.unwrap(); // Bob adds alice to gossip peers. diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 2849874c0..25afe854a 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1446,6 +1446,9 @@ async fn add_parts( Ok(node_addr) => { info!(context, "Adding iroh peer with address {node_addr:?}."); let instance_id = parent.context("Failed to get parent message")?.id; + context.emit_event(EventType::WebxdcRealtimeAdvertisementReceived { + msg_id: instance_id, + }); if let Some(topic) = get_iroh_topic_for_msg(context, instance_id).await? { let node_id = node_addr.node_id; let relay_server = node_addr.relay_url().map(|relay| relay.as_str());