addEventListner for received SMS using mozMobileMessage in B2G - angularjs

I have been teaching myself how to write apps in AngularJS for Firefox OS for a university assignment. This is my first attempt at writing an app in JS.
The aim of the app is to run commands based upon 'commands' sent via SMS (aka, 'ring loud', 'lock device', 'turn on wifi', and reply to an SMS command with GPS locations). At the moment, I'm just trying to do a simple $window.alert('Messaged Received'), to display when an SMS has been received.
My problem is, I am trying to create an addEventListener for incoming SMS, and for the moment, display an $window.alert(). Later, I will use a case switch.
I've referred to the MDN API to create the Event Listener.
var mozMM = navigator.mozMobileMessage;
mozMM.addEventListener('received', function addEventListener(evt) {
// Display a alert when a message is received
$window.alert('SMS received');
$window.alert(evt.message.body);
}, false);
My manifest.webapp has been set up to include all the relevant settings:
"type" : "certified",
"permissions": {
"backgroundservice":{},
"sms":{},
...
},
"messages": [
{ "sms-received": "/index.html" },
{ "notification": "/index.html" }
]
I am able to send SMS from my app without any issues. So I assume I have no problems with my permissions. I've also confirmed that I have full access to the mozMobileMessage object.
For testing, I am using a Geekphone, which has been rooted, and can install certified apps.
I have uploaded the source code to github:
https://github.com/s3069246/findmydevice/tree/master/app

Thanks to someone on Google Groups for giving me the correct solution. I thought I would also share it here.
The issue was that I was using the wrong Event Handler. I should have been using a system message handler instead
navigator.mozSetMessageHandler('sms-received', function onSMS(sms) {
/* here your code */
});
Combined with the "message": [] handler in the manifest, the system handler will alert the application that a message has been received, even if the app is running in the background.

Related

Unable to add a .listen() directive at the end of audio playing

For context, I am building a skill that involves recorded narrations as audio streams.
For one of the narrations, a question will be posed to the user (recorded as part of the narrations)
The user's intent, captured using this.response.listen(), will determine the next set of narration to play
My issue is the following - as part of the Skill requires audio playback, I am using the AudioPlayerInterfaces. I encounter the error at the following part (see code below with comment):
var audioEventHandlers = {
'PlaybackStarted': function() {
this.emit(':responseReady');
},
'PlaybackFinished': function() {
if (currentStream.keyName === 'intro') {
this.response.listen(); //<-- this line causes the error
}
this.emit(':responseReady');
}, //additional handler code omitted as not relevant
Specifically, the error triggered by this.response.listen() is:
"error": {
"type": "INVALID_RESPONSE",
"message": "The following directives are not supported: Response may not contain an reprompt,Response may not have shouldEndSession set to false"
},
I have seen other Skills utilizes recordings, followed by a .listen() prompt, so I know that this is technically feasible. I was wondering how I should be approaching this?
Thanks!

Request Deferrer with Service Worker in PWA

I am making a PWA where users can answer the forms. I want it to make also offline, so when a user fills out a form and does not have the internet connection, the reply will be uploaded when he is back online. For this, I want to catch the requests and send them when online. I wanted to base it on the following tutorial:
https://serviceworke.rs/request-deferrer_service-worker_doc.html
I have managed to implement the localStorage and ServiceWorker, but it seems the post messages are not caught correctly.
Here is the core function:
function tryOrFallback(fakeResponse) {
// Return a handler that...
return function(req, res) {
// If offline, enqueue and answer with the fake response.
if (!navigator.onLine) {
console.log('No network availability, enqueuing');
return;
// return enqueue(req).then(function() {
// // As the fake response will be reused but Response objects
// // are one use only, we need to clone it each time we use it.
// return fakeResponse.clone();
// });
}
console.log("LET'S FLUSH");
// If online, flush the queue and answer from network.
console.log('Network available! Flushing queue.');
return flushQueue().then(function() {
return fetch(req);
});
};
}
I use it with:
worker.post("mypath/add", tryOrFallback(new Response(null, {
status: 212,
body: JSON.stringify({
message: "HELLO"
}),
})));
The path is correct. It detects when the actual post event happens. However, I can't access the actual request (the one displayed in try or fallback "req" is basically empty) and the response, when displayed, has the custom status, but does not contain the message (the body is empty). So somehow I can detect when the POST is happening, but I can't get the actual message.
How to fix it?
Thank you in advance,
Grzegorz
Regarding your sample code, the way you're constructing your new Response is incorrect; you're supplying null for the response body. If you change it to the following, you're more likely to see what you're expecting:
new Response(JSON.stringify({message: "HELLO"}), {
status: 212,
});
But, for the use case you describe, I think the best solution would be to use the Background Sync API inside of your service worker. It will automatically take care of retrying your failed POST periodically.
Background Sync is currently only available in Chrome, so if you're concerned about that, or if you would prefer not to write all the code for it by hand, you could use the background sync library provided as part of the Workbox project. It will automatically fall back to explicit retries whenever the real Background Sync API isn't available.

Open URL in IBM Watson conversation

I am using a Blumix free account to develop a chat-bot using watson conversation.
How do I add a clickable URL in the response, or automatically call a URL in browser?
I have edited the "advanced response" using the suggestions as described on this page but could not get it work.
How can I achieve that?
I don't know if I understood your question correctly, but.. if you wants add some url inside flows Conversation Service (IBM Watson), try it:
1º: Add the url with tag <a target> and href= your URL inside flows. See the example:
JSON:
"output": {
"text": "This is a link <a target=\"_blank\" href= \"https://www.choosemyplate.gov\">Food and nutrition Guide</a>.\n<br/><br/>Talk to you later, bye for now!"
},
2º See that it did not work inside the Conversation, because it will be your browser that will render the html.
3º If you open with your browser, it works, see:
See that the link is showing up, and this will work for other things in html, like button, for example...
But if you can: based on user input should access a url:
This is done by using two features: Context.request skip_user_input
A request is a special context variable that has args, name and result. It is used to tell the calling app that it should do some action based on this variable.
Setting skip_user_input is optional. In many cases, you might want to execute some business logic in your application and then provide its results via result. Setting skip_user_input to true, will tell Watson Conversation to not wait for input from the user. Thus, your condition on the next node should be based on the content inside result.
{
"output": {},
"context": {
"request": {
"args": {
"url_to_invoke": "your_url"
},
"name": "Call_A_URL",
"result": "context.response"
},
"skip_user_input": true
}
}
Reference: IBM Professional #Dudi: here.

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.

SignalR server doesn't consistently call methods on client

I have an AngularJS application that I intend to have receive communications via SignalR from the server, most notably when data changes and I want the client to refresh itself.
The following is my hub logic:
[HubName("update")]
public class SignalRHub : Hub
{
public static void SendDataChangedMessage(string changeType)
{
var context = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>();
context.Clients.All.ReceiveDataChangedMessage(changeType);
}
}
I use the following within my API after the data operation has successfully occurred to send the message to the clients:
SignalRHub.SendDataChangedMessage("newdata");
Within my AngularJS application, I create a service for SignalR with the following javascript that's referenced in the HTML page:
angular.module('MyApp').value('signalr', $.connection.update);
Within the root for the AngularJS module, I set this up with the following so that it starts and I can see the debug output:
$(function () {
$.connection.hub.logging = true;
$.connection.hub.start();
});
$.connection.hub.error(function(err) {
console.log('An error occurred: ' + err);
});
Then I've got my controller. It's got all sorts of wonderful things in it, but I'll show the basics as relate to this issue:
angular.module('MyApp').controller('MyController', function($scope, signalr) {
signalr.client.ReceiveDataChangedMessage = function dataReceived(changeType) {
console.log('DataChangedUpdate: ' + changeType);
};
});
Unfortunately, when I set a breakpoint in the javascript, this never executes though the rest of the program works fine (including performing the operation in the API).
Some additional (hopefully) helpful information:
If I set a breakpoint in the SignalRHub class, the method is successfully called as expected and throws no exceptions.
If I look at Fiddler, I can see the polling operations but never see any sign of the call being sent to the client.
The Chrome console shows that the AngularJS client negotiates the websocket endpoint, it opens it, initiates the start request, transitions to the connected state, and monitors the keep alive with a warning and connection lost timeout. There's no indication that the client ever disconnects from the server.
I reference the proxy script available at http://localhost:port/signalr/hubs in my HTML file so I disregard the first error I receive stating that no hubs have been subscribed to. Partly because the very next message in the console is the negotiation with the server and if I later use '$.connection.hub' in the console, I'll see the populated object.
I appreciate any help you can provide. Thanks!
It's not easy to reproduce it here, but it's likely that the controller function is invoked after the start of the connection. You can verify with a couple of breakpoints on the first line of the controller and on the start call. If I'm right, that's why you are not called back, because the callback on the client member must be defined before starting the connection. Try restructuring your code a bit in order to ensure the right order.

Resources