Extension Messaging
When implementing a Webfuse Extension you probably want the different components of your Extensions to be able to communicate with each other. We offer two different ways to enable this:
- In-Extension Messaging – Allows you to send messages between the different components of your Extension on a single participant’s side.
- Webfuse Broadcast Messaging – Allows you to broadcast messages to all participants which can then be received by the different components of your Extension.
Extension Component Communication
Section titled “Extension Component Communication”Extension messages are a way to send messages between the different components of your Extension on a single participant’s side.
Sending Extension Messages
Section titled “Sending Extension Messages”Sending a message from any component to Popup, Background, and Side Panel can be done by using runtime.sendMessage():
browser.runtime.sendMessage(message);Sending a message from Popup, Background, Side Panel, and Newtab to the tab Content script (and Newtab pages) can be done by using tabs.sendMessage().
browser.tabs.sendMessage(tabId, message);Example
Section titled “Example”browser.runtime.onMessage.addListener((message) => { if (message.command === 'sendMessageToTabs') { browser.webfuseSession.getTabs().then((tabs) => { sendMessageToTabs(tabs); }); }});
function sendMessageToTabs(tabs) { tabs.forEach((tab) => { browser.tabs.sendMessage(tab.id, {greeting: 'Hi from background'}).then((response) => { console.log('response from tab', tab.id, response); }); });}Here’s the corresponding content component script:
browser.runtime.onMessage.addListener((message, sender) => { if (message.greeting === 'Hi from background') { return ({ response: 'Hi from content script' }); }});Receiving Extension Messages
Section titled “Receiving Extension Messages”Receiving a message in any component can be done by using runtime.onMessage.addListener():
browser.runtime.onMessage.addListener((message, sender) => {});Async Message Handling
Section titled “Async Message Handling”Both runtime.sendMessage() and tabs.sendMessage() return a Promise that resolves with the first listener’s response. Listeners can respond synchronously by returning a value, or asynchronously by returning a Promise.
// content.js — handling messages from background via tabs.sendMessage()browser.runtime.onMessage.addListener((message, sender) => { // Sync: return a value directly if (message.type === 'GET_PAGE_DATA') { return { title: document.title, url: window.location.href }; }
// Async: return a Promise — the messenger awaits it before responding if (message.type === 'WAIT_FOR_ELEMENT') { return new Promise((resolve) => { const check = () => { const el = document.querySelector(message.selector); if (el) return resolve({ found: true, text: el.textContent }); setTimeout(check, 200); }; check(); }); }});// background.js — calling the content script and awaiting the responseasync function getPageData() { const tabs = await browser.webfuseSession.getTabs(); const activeTab = tabs.find(t => t.active); if (!activeTab) return; const data = await browser.tabs.sendMessage(activeTab.id, { type: 'GET_PAGE_DATA' }); console.log('Page title:', data.title);}The same pattern works with runtime.sendMessage() for communication between content scripts, popups, side panels, and the background:
// background.js — handling messages from content script or popupbrowser.runtime.onMessage.addListener((message, sender) => { if (message.type === 'FETCH_DATA') { return fetch(message.url).then(r => r.json()); }});// content.js or popup.js — sending a message to background and awaiting the responseconst data = await browser.runtime.sendMessage({ type: 'FETCH_DATA', url: '/api/data' });console.log('Received:', data);Broadcast Messages to All Participants
Section titled “Broadcast Messages to All Participants”In addition to messaging between components within an Extension, the Session API also allows you to broadcast a message to all participants within a Session. This is useful if you want to communicate with Extensions loaded on other participants’ side, want to communicate to pages that embed your space, interface with your Extension using the REST API.
Broadcasting from an Extension
Section titled “Broadcasting from an Extension”browser.webfuseSession.broadcastMessage(message);Broadcasting Using the Widget API
Section titled “Broadcasting Using the Widget API”The Widget API also allows you to broadcast a message to all participants within a Session.
// Initialize Webfuse space and create a Session with event listenerswebfuse.initSpace('your_widget_key', 'your_space_id').then(async space => { const session = space.session();
session.on('tab_relocate_start', (session, event) => { session.broadcastMessage(`Navigating to a new page: ${event.url}`); });
// Start the Session await session.start();});Sending a Broadcast Using the REST API
Section titled “Sending a Broadcast Using the REST API”Messages to the broadcast channel can also be sent using the REST API, allowing your backend to send messages to all participants in a Session.
import requests
API_Key = "<API_KEY>"Session_ID = "<SESSION_ID>"
url = f"https://app.webfuse.io/v2/spaces/sessions/{Session_ID}/message/"
headers = { "Authorization": f"Token {API_Key}", "Content-Type": "application/json"}
data = { "message": { "content": "Hello from REST API!" }}
response = requests.post(url, json=data, headers=headers)
print(response.json())Receiving a Broadcast Within an Extension
Section titled “Receiving a Broadcast Within an Extension”You can listen for broadcast messages by using browser.webfuseSession.on.addListener() to listen for broadcasted message and session events.
For example, if you want to listen for messages from the background script, you can do the following:
browser.webfuseSession.on.addListener((payload, sender) => { // Case 1: Handle session events // These objects always have an 'event_type' property (e.g., 'session_ended') if (payload.event_type) { if (payload.event_type === 'session_ended') { console.log('Session ended at:', payload.final_location); } }
// Case 2: Handle broadcast messages // These objects always have a 'message' property if (payload.message) { console.log('Broadcast received:', payload.message); }});Receiving a Broadcast Using the Widget API
Section titled “Receiving a Broadcast Using the Widget API”If you want to listen for messages using the Widget API, you can use session.on('message') to listen for message events.
webfuse.initSpace('your_widget_key', 'your_space_id').then(async space => { const session = space.session();
session.on('message', (session, event) => { console.log("Received message:", event.data.message, "from", event.origin); });
// Start the Session await session.start();});