getting a Firefox plugin to detect and mimic attempts to check for Apple Pay support - firefox-addon-webextensions

Now that Apple's credit card offering is out, I can get 2% cash back on purchases on the web made with Apple Pay. Unfortunately, my browser of choice is Firefox, which doesn't yet support Apple Pay.
I'd like to detect attempts to check for Apple Pay support, so I can alert myself in some way and switch over Safari to complete my purchase. Per Apple's docs, this check is performed via window.ApplePaySession.
So, I've attempted the following in an extension:
manifest.json
{
"manifest_version": 2,
"name": "applepay",
"version": "1.0",
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"applepay.js"
]
}
]
}
applepay.js
window.ApplePaySession = {
canMakePayments: function () {
console.log('canMakePayments');
return Promise.resolve(true);
},
canMakePaymentsWithActiveCard: function () {
console.log('canMakePaymentsWithActiveCard');
Promise.resolve(true);
},
};
I'm able to console.log(window) in applepay.js and get the whole object, but my changes to the object don't appear to take effect - it's acting like window is read-only. What am I missing?

In Firefox, content scripts (addon written in WebExtensions) don't share the same context as page scripts (website scripts).
In your content script, do something similar to this:
function notify(message) {
console.log("do something");
}
exportFunction(notify, window, {defineAs:'notify'});
After, the page script will see that window.notify exists.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts

Related

Test CanFullfillmentRequest in alexa mobile app or echo device during development mode

I'm creating a alexa skill, in which i want to trigger all my commands without invocation name, i have implement CanFullfillmentRequest by following (https://developer.amazon.com/en-US/docs/alexa/custom-skills/implement-canfulfillintentrequest-for-name-free-interaction.html#invoke-and-test-the-skill) this url and test it from simulator using json file.
now i want to test this in mobile app environment.
How do i test this?
Is there only way to submit my skill and test this feature on live mode? Or there is any other way to test this.
#name-free-intrection
The only way to test a skill that implements CanFulfillIntentRequest and is not live yet is to simulate the request by crafting one and sending it to your skill.
Create a new .json file containing the input JSON with the request type set to CanFulfillIntentRequest.
The following is a sample .json file for the request. Substitute the appropriate values for your skill. Because you cannot test CanFulfillIntentRequest with an Alexa-enabled device, the purpose of this file is to duplicate the content of an actual CanFulfillIntentRequest from Alexa for testing with ASK CLI, or in the Alexa Simulator.
{
"session":{
"new": true,
"sessionId":"SessionId.[unique-value-here]",
"application":{
"applicationId":"amzn1.ask.skill.[unique-value-here]"
},
"attributes":{
"key": "string value"
},
"user":{
"userId":"amzn1.ask.account.[unique-value-here]"
}
},
"request":{
"type":"CanFulfillIntentRequest",
"requestId":"EdwRequestId.[unique-value-here]",
"intent":{
"name":"MyNameIsIntent",
"slots":{
"name":{
"name":"name",
"value":"Jeff"
}
}
},
"locale":"en-US",
"timestamp":"2017-10-03T22:02:29Z"
},
"context":{
"AudioPlayer":{
"playerActivity":"IDLE"
},
"System":{
"application":{
"applicationId":"amzn1.ask.skill.[unique-value-here]"
},
"user":{
"userId":"amzn1.ask.account.[unique-value-here]"
},
"device":{
"supportedInterfaces":{
}
}
}
},
"version":"1.0"
}
More info: https://developer.amazon.com/en-US/docs/alexa/custom-skills/implement-canfulfillintentrequest-for-name-free-interaction.html#create-the-json-for-testing-your-skill

Mozilla addon loading too late to block a resource

I'm trying to cancel requests from studio.code.org to www.google.com/jsapi to help page loads go faster. In my locale, google is blocked, but the browser waits for 75 seconds before giving up. I'd like to prevent the delay by blocking the request (and the page seems to work fine without jsapi).
I followed the example from https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeRequest, installed the addon. I included a console.log statement to see that my code is called, but it only shows up after the browser waits another 75 seconds trying to load the resource that I hoped to block.
I'm open to other approaches if this isn't going to work.
manifest.json:
{
"manifest_version": 2,
"name": "cancel-google",
"version": "1.0",
"permissions": [
"webRequest",
"webRequestBlocking"
],
"content_scripts": [
{
"matches": ["https://studio.code.org/*"],
"js": ["cancel-google.js"]
}
]
}
cancel-google.js:
// match pattern for the URLs to block
var pattern = "*www.google.com/jsapi";
console.log("cancelator script loaded");
// cancel function returns an object
// which contains a property `cancel` set to `true`
function cancel(requestDetails) {
console.log("Cancelling: " + requestDetails.url);
return {cancel: true};
}
// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
cancel,
{urls: [pattern]},
["blocking"]
);
cancel-google.js should be loaded as a background script, which is true for most of the WebExtension APIs.
{
"name": "Your Addon",
"manifest_version": 2,
"background": {
"scripts": ["cancel-google.js"]
}
}
Then it should work.
Smile4ever's answer is correct but I found some other issues with my original code.
First - the 'timing' issue of my original content-script was a red herring. Although the original content script will write to the log of the page, it has no effect on loading resources. The same script, as a background script, will not write anything (that I have noticed) into the console log, but it will work.
Second - the background script needs more permissions than I had originally (more than are described in the mozilla.org link).
"permissions": [
"http://*/*",
"https://*/*",
"webRequest",
"webRequestBlocking" ]
The above permissions are adequate/excessive; you can also replace "http(s)://*/*" with the actual urls of the pages requesting the resource and the resource to be blocked.

How to call a web-action from watson assistant dialog node?

I am trying to call a simple web-action from my dialog node. Both service and cloud space is hosted in London, still I am getting error that "Direct CloudFunctions calls are not supported on this platform".
I have created a simple skill and added 3 nodes to it, 1 is welcome node, second is test node in that I have added action of type web-action and created a webaction on cloud that returns a simple message. Below is the details for test node and action.
{
"output": {
"generic": [
{
"values": [
{
"text": "Hi how are you $message"
}
],
"response_type": "text",
"selection_policy": "sequential"
}
]
},
"actions": [
{
"name": "/namespace_dev/default/Call DB",
"type": "web_action",
"parameters": {
"mob_num": "$MNum"
},
"credentials": "my cloud function creds",
"result_variable": "message"
}
]
}
Below is the web-action code.
function main(params) {
return { message: 'Hello World' };
}
Node when test node is invoked the action should get executed but I am getting below error.
Dialog node error
Direct CloudFunctions calls are not supported on this platform
Can someone please suggest what mistake I am doing?
Currently, as stated in the Actions Docs, the actions are accessible only in Germany and US South. However, this document differs based on the language you read in. In the German Version, which is my default, you might read this:
Gegenwärtig können Sie eine Cloud Functions-Aktion über Watson Assistant-Instanzen aufrufen, die in den Regionen 'Vereinigte Staaten (Süden)' oder 'Deutschland' gehostet werden.
which translates (using Google) to this:
Currently, you can invoke a Cloud Functions action through Watson Assistant instances hosted in the United States (South) or Germany regions.
If I switch to the English Version of the Documentation, this information disappears.

How to waive Xrays vision in latest Firefox WebExtension?

I am following the guide here:
I want to waive Xrays vision of an iframe:
var foo = $(Components.utils.waiveXrays($("#foobar").get(0).contentWindow.document));
The above is running in a content script with manifest.json like the following:
"content_scripts": [
{
"matches": /* something */,
"css": ["content.css"],
"js": ["jquery-3.2.1.js","content.js"]
}
]
But I will get an undefined object error:
[firefox/index.js][debug] Firefox stderr: JavaScript error: , line 0: Error: Components.utils is undefined
I think the guide on Mozilla website is outdated. It is not for pure WebExtension implementation.
What should be the correct latest method now?
After a couple of days of research (and asking in mozilla firefox mailing list). I already found out the solution. The correct guide is here (as of 2017 May 14):
In the SDK, content scripts can share objects with page scripts, using
techniques like unsafeWindow and createObjectIn. In WebExtensions, the
unsafeWindow is available via wrappedJSObject instead. All the export
helper functions are available, too.
If I want to access the waived xrays version of window object, I should use:
window.wrappedJSObject
If there is an iframe within the page and I want to access the object inside it. Here is one of the way:
document.getElementById("the_iframe").contentWindow.wrappedJSObject
However, I found that if the iframe is in cross-domain, the wrappedJSObject will be not accessible (as of Firefox version 51.0.1). I need to seek another method as follow:
Provide a content script that inject all child iframe and then implement a background script that provide a messaging bridge between the child iframe and the top page:
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["*://*.something"],
"css": ["content.css"],
"all_frames": true, /* ADD THIS LINE */
"js": ["jquery-3.2.1.js","content.js"]
}
]
In content.js, do something like that:
if(window.top == window.self) { // main
main();
}
else if(window.name == "frameA") { // match frameA
  browser.runtime.onMessage.addListener(function(msg) {
/* Check the message msg and then access the waived X rays vision by window.wrappedJSObject */
if(msg matches something) {
var ret = window.wrappedJSObject.foobar(msg.data);
/* Send back the return value to background.js by browser.runtime.sendMessage */
browser.runtime.sendMessage({"returnVal": ret, "from": "frameA"});
}
}
});
}
In background.js, do some message forwarding:
function forward_to_all(r)
{
var forwardMessage = function(tabs) {
for(let tab of tabs) {
browser.tabs.sendMessage(tab.id,r);
}
}
browser.tabs.query({currentWindow:true, active:true}).then(forwardMessage);
}
browser.runtime.onMessage.addListener(function(msg) {
if(msg matches something) {
forward_to_all(msg);
}
});
You aren't meant to be able to waive xrays in firefox webextensions, if you are able to then it's a bug that would quickly be disabled.
I think the guide on Mozilla website is outdated.
Indeed.
What should be the correct latest method now?
what you want to do (ie waive xray wrappers) is not possible. Probably best to think about a new way to achieve what you want, whatever that is (I can't tell by the description).

Is including additional information in the output object a good idea?

I'm experimenting with a Conversation where I would like to modify the output in a couple of different ways:
different output for speech or text
different output depending on the tone of the conversation
It looks like I can add extra output details which make it through to the client ok. For example, adding speech alongside text...
{
"output": {
"speech": {
"Hi. Please see my website for details."
},
"link": "http://www.example.com",
"text": {
"Hi. Please see http://www.example.com for details."
}
}
}
For the tone, I wondered about making up a custom selection policy, unfortunately it seems to treat it the same as a random selection policy. For example...
{
"output": {
"text": {
"values": [
"Hello. Please see http://www.example.com for more details.",
"Hi. Please see http://www.example.com for details."
]
},
"append": false,
"selection_policy": "tone"
}
}
I could just add a separate tone-sensitive object to output though so that's not a big problem.
Would there be any issues adding things to output in this way?
You can definitely use the output field to specify custom variables you want your client app to see with the benefit that these variables will not persist across multiple dialog rounds (which they would if you would add them to the context field).
Now currently there is no "easy" way how to define your custom selection policy (apart from the random and sequential supported by the runtime right now) - but you could still return an array of possible answers to the client app with some attribute telling the client app which selection policy to use and you would implement this policy in the client app.

Resources