BroweSharing URLs with sound
By: Joe Todd
Tags: Webassembly, Sharing, Chrome, Chrome Extension, Chirp

The Chrome extension makes use of the Chirp WebAssembly SDK to send and receive data using sound in the browser. The URL is passed through the link shortening API provided by Akari, and this short code is sent using Chirp.

At the moment, there are bugs with audioCapture permissions in chrome extensions, so we have to use some workarounds to access audio data and also to run WebAssembly code.

To gain access to the microphone, one way around the current limitations are to request permissions inside an options page. Once the permissions have been granted, the decision is cached by the browser so that the popup window also has access.

Secondly to get the extension to load a WebAssembly file, we need to allow the use of the “evil” eval method.

Here is an example of the extension’s manifest.json. We also need to add the Akari API to the permissions list, to enable cross origin requests.



"name": "Chirp URL Share",

"version": "1.1",

"description": "Share links with anyone nearby",

"browser_action": {

"default_icon": "icon-24.png",

"default_title": "Chirp URL Share"

},

"icons": {

"48": "icon-48.png",

"128": "icon-128.png"

},

"permissions": [

"activeTab",

"storage",

"https://api.waa.ai/*"

],

"web_accessible_resources": [

"chirp-connect.wasm",

"images/*",

"fonts/*"

],

"browser_action": {

"default_title": "Chirp URL Share",

"default_popup": "popup.html"

},

"options_page": "options.html",

"minimum_chrome_version": "65.0.3325",

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",

"manifest_version": 2

} "name": "Chirp URL Share","version": "1.1","description": "Share links with anyone nearby","browser_action": {"default_icon": "icon-24.png","default_title": "Chirp URL Share"},"icons": {"48": "icon-48.png","128": "icon-128.png"},"permissions": ["activeTab","storage",],"web_accessible_resources": ["chirp-connect.wasm","images/*","fonts/*"],"browser_action": {"default_title": "Chirp URL Share","default_popup": "popup.html"},"options_page": "options.html","minimum_chrome_version": "65.0.3325","content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'","manifest_version": 2

The options page will just trigger getUserMedia to request microphone permissions, once this has been allowed the extension is free to use the microphone whenever the extension popup is opened.

getUserMedia is called internally inside the Chirp SDK, so we just need to instantiate the SDK to trigger this.

enableButton.onclick = () => {

Chirp({ key: 'CHIRP_APP_KEY' }).then(sdk => {})

}

Inside the popup now we can use the Chirp WebAssembly SDK alongside the Akari URL shortening API to generate a short code for the current tab, and transmit it over the air waves using sound. Here is the example code for popup.js.

const { Chirp, toAscii } = ChirpConnectSDK

const key = 'AKARI_API_KEY'

let sdk const openUrl = url => chrome.tabs.create({ url })

fetch(`

.then(response => response.json())

.then(json => openUrl(json.data.link))

} const lengthen = code => {fetch(` https://api.waa.ai/info/${code}?key=${key}` .then(response => response.json()).then(json => openUrl(json.data.link))

fetch(`

.then(response => response.json())

.then(json => sdk.send(json.data.short_code))

} const shorten = url => {fetch(` https://api.waa.ai/shorten?url=${url}&key=${key}` .then(response => response.json()).then(json => sdk.send(json.data.short_code)) sendButton.onclick = () => {

chrome.tabs.query({ active: true, currentWindow: true }, tab => {

shorten(tab[0].url)

});

} Chirp({

key: 'CHIRP_APP_KEY',

onReceived: data => lengthen(toAscii(data))

})

.then(_sdk => {

sdk = _sdk

})

The WebAssembly SDK is available now from Chirp’s CDN at https://public.chirp.io/wasm/latest/chirp-connect.js.

Further documentation can be found at the Chirp developer hub.

Chirp is free for both development and commercial use up to 10k monthly active users. More information on pricing can be found at chirp.io.

joe@chirp.io