I am trying to use Facebook Messenger Extensions on my bot
but after I've added attached html & javascript code, I receive error 2071011 (I tried this on Android phone).
<!DOCTYPE HTML>
<head>
</head>
<body>
<script>
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.com/en_US/messenger.Extensions.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'Messenger'));
window.extAsyncInit = function () {
// the Messenger Extensions JS SDK is done loading
MessengerExtensions.getUserID(function success(uids) {
var psid = uids.psid;
alert(psid);
}, function error(err) {
alert("Messenger Extension Error: " + err);
});
};
</script>
<h2>Test</h2>
</body>
In "messenger.Extensions.js" SDK file I found the following explanation for the error:
"JavaScript bridge does not exist - Please make sure you are in latest
version of Facebook or Messenger App."
What does that mean someone can explain what is the problem?
I had the same problem. I fixed it by:
Make sure you have the latest version of messenger
Make sure your webview is opened with messenger_extensions: true
Make sure you whitelist your domains :https://developers.facebook.com/docs/messenger-platform/thread-settings/domain-whitelisting
Related
I have developped an extension to scrape some content from web page and up to now it was working fine but since I switched to manifest v3, the parsing doesn't work anymore.
I use the following script to read the source code:
chrome.scripting.executeScript(
{
target: {tabId: tab.id, allFrames: true},
files: ['GetSource.js'],
}, async function(results)
{
// GETTING HTML
parser = new DOMParser();
content = parser.parseFromString(results, "text/html");
... ETC ...
This code used to work fine but now I get the following message in my console:
Uncaught (in promise) ReferenceError: DOMParser is not defined
The code is part of a promise but I don't think the promise is the problem here. I basically need to load the source code into a variable so that I can parse it afterwards.
I've checked the documentation but I haven't found something mentionned that DOMParser was not going to work with v3.
Any idea?
Thanks
Since service workers don't have access to DOM, it's not possible for
an extension's service worker to access the DOMParser API or create an
to parse and traverse documents.
More detail
And I solve the problem by using library dom-parser.The code could be like this
import DomParser from "dom-parser";
const parser = new DomParser();
const dom = parser.parseFromString('you html string');
From the docs:
Since service workers don't have access to DOM, it's not possible for an extension's service worker to access the DOMParser API or create an to parse and traverse documents.
Using an external library just for doing what DomParser already does?? It is too heavy.
To work-around with it, we can use an offscreen document. It's just invisible webpage where you can run fetch, audio, DomParser, ... and communicate with background (service_worker) via chrome.runtime.
See an example below:
background.js
chrome.offscreen.createDocument({
url: chrome.runtime.getURL('xam.html'),
reasons: [chrome.offscreen.Reason.DOM_PARSER],
justification: 'reason for needing the document',
});
// Just a test
setTimeout(() => {
const onDone = (msg) => {
console.log(msg);
chrome.runtime.onMessage.removeListener(onDone);
};
chrome.runtime.onMessage.addListener(onDone);
chrome.runtime.sendMessage('from-background-page');
}, 3000);
xam.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="xam.js">
</script>
</body>
</html>
xam.js
async function main() {
const v = await fetch('https://......dev/').then((t) => t.text());
const d = new DOMParser().parseFromString(v, 'text/html');
const options = Array.from(d.querySelector('select').options)
.map((v) => `${v.value}|${v.text}`)
.join('\n');
chrome.runtime.sendMessage(options);
}
chrome.runtime.onMessage.addListener(async (msg) => {
console.log(msg);
main();
});
manifest.json
"permissions": [
// ...
"offscreen"
]
https://developer.chrome.com/docs/extensions/reference/offscreen/
The extension's permissions carry over to offscreen documents, but extension API access is heavily limited. Currently, an offscreen document can only use the chrome.runtime APIs to send and receive messages; all other extension APIs are not exposed.
Notes:
I haven't tested how long this offscreen document alive.
Just sample codes, it should work. Customzie as your own cases.
I am working on a Chrome Web App. It interacts with Google Cloud Messaging. My question is can the Chrome Web App html5 pages call a RESTful WebAPI service? I am not finding any examples on how to do this inside the app pages? The WebAPI will return JSON. Any tips - very much appreciated.
Edit:
This is in the html page:
<body>
<select id="ParametersDropDownList"></select>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="test.js"></script>
</body>
And this is in my test.js file:
var uri = 'http://localhost/custom.webapi/api/parameter?emailaddress=john#foo.bar';
var msg;
$.getJSON(uri)
.done(function(data) {
var appenddata;
$.each(data, function(key, item) {
appenddata += "<option value = '" + item.ParameterName + " '>" + item.ParameterName + " </option>";
});
$('#ParametersDropDownList').html(appenddata);
})
.fail(function(jqXHR, textStatus, err) {
var error = $.parseJSON(jqXHR.responseText);
msg = "Failed to get action data Error message is " + error.message;
});
This code works in a regular html5 page. Meaning, the webapi returns json and the dropdown list is populated with the expected values.
Turned out it was CSP related. Specifically accessing jquery from googleapis.com. I instead downloaded the minified version and added it to the project.
I was wondering what kind of technologies are behind Web Push, for example https://goroost.com
How is that working? How to configure my server for Web Push? What should I look at?
The underlying technology is the Push API, combined with the Notifications API
You can read more about how to implement this yourself in Google's developer docs. Note that currently push notifications are only supported in Google Chrome, but Microsoft and Mozilla have said they will be implementing it soon.
I can answer for WonderPush.com
First, you need to sign up on WonderPush and declare your website.
Then, Copy/paste the following snippet before the closing <body> tag:
<script>
(function(w, d, s, id, n){
w[n] = w[n] || {q: [],
init: function(o) {w[n].initOpts = o;},
ready: function(c) {w[n].q.push(c);}};
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://cdn.by.wonderpush.com/sdk/1.1/wonderpush-loader.min.js";
fjs.parentNode.insertBefore(js, fjs);
}(window, document, 'script', 'wonderpush-jssdk-loader','WonderPush'));
WonderPush.init({
webKey: "[YOUR_WEBKEY]" // sign up for FREE to retrieve your web key
});
</script>
I'm currently trying to make Opus packets work with Web Audio API. The problem is however, while it should be natively supported by FireFox and Chrome, only FireFox can decode a stream of OPUS samples using decodeAudioData from the Web Audio API. Chrome does recognize the file when I drag the opus file into the browser and it also does play it! So I'm wondering that I may be doing something wrong here causing failure in Chrome.
Then I used some sample code from http://awm.jp/~yoya/js/audio/meow.html just load an opus file and try to decode it. Again Firefox does, and Chrome doesn't. So I'm wondering if someone can confirm my finding or tell me what I'm doing wrong here. Below is the modified version from the earlier link. Thanks!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
<title> decodeAudioData sample </title>
</head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
//$(document).ready(function() {
var catMeowingBuffer = null;
window.AudioContext = window.AudioContext||window.webkitAudioContext;
var context = new AudioContext();
function onError(err) {
console.log("unable to decode");
}
function loadCatSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
catMeowingBuffer = buffer;
var src = context.createBufferSource();
src.buffer = catMeowingBuffer
src.connect(context.destination);
src.start(0);
}, onError);
}
request.send();
}
loadCatSound("opus.opus");
function playCatSound() {
if (catMeowingBuffer !== null) {
var src = context.createBufferSource();
src.buffer = catMeowingBuffer
src.connect(context.destination);
src.start(0);
}
}
//});
</script>
<body>
<h1> decodeAudioData sample </h1>
<button onclick="playCatSound();"> playCatSound </button>
<hr>
<address></address>
</body> </html>
This is a bug in Chrome. See https://code.google.com/p/chromium/issues/detail?id=409402.
I have an application, which streams an MP3 using Node.JS. Currently this is done through the following post route...
app.post('/item/listen',routes.streamFile)
...
exports.streamFile = function(req, res){
console.log("The name is "+ req.param('name'))
playlistProvider.streamFile(res, req.param('name'))
}
...
PlaylistProvider.prototype.streamFile = function(res, filename){
res.contentType("audio/mpeg3");
var readstream = gfs.createReadStream(filename, {
"content_type": "audio/mpeg3",
"metadata":{
"author": "Jackie"
},
"chunk_size": 1024*4 });
console.log("!")
readstream.pipe(res);
}
Is there anyone that can help me read this on the client side? I would like to use either JPlayer or HTML5, but am open to other options.
So the real problem here was, we are "requesting a file" so this would be better as a GET request. In order to accomplish this, I used the express "RESTful" syntax '/item/listen/:name'. This then allows you to use the JPlayer the way specified in the links provided by the previous poster.
I'm assuming you didn't bother visiting their site because had you done so, you would have seen several examples of how to achieve this using HTML5/JPlayer. The following is a bare-bones example provided by their online developer's documentation:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery.jplayer.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#jquery_jplayer_1").jPlayer({
ready: function() {
$(this).jPlayer("setMedia", {
mp3: "http://www.jplayer.org/audio/mp3/Miaow-snip-Stirring-of-a-fool.mp3"
}).jPlayer("play");
var click = document.ontouchstart === undefined ? 'click' : 'touchstart';
var kickoff = function () {
$("#jquery_jplayer_1").jPlayer("play");
document.documentElement.removeEventListener(click, kickoff, true);
};
document.documentElement.addEventListener(click, kickoff, true);
},
loop: true,
swfPath: "/js"
});
});
</script>
</head>
<body>
<div id="jquery_jplayer_1"></div>
</body>
</html>