Twilio voice call answering and talking - android

I have implemented android twilio call with this tutorial,
https://github.com/twilio/voice-quickstart-android
Everything works perfectly as they have mentioned. The call rings I can attend the call and listen to the VoiceResponse message I saved in server. My requirement is I need to talk to the one android twilio application to other android with same twilio application instead of receiving VoiceResponse message. If I make phone calls to actual phone numbers then I can talk and listen without any problem, but from application to application speaking does not work.
I am using node js as server code, the first calling person code is given below.
client.api.calls.create({
url: url,
to: phoneNumber,
from: callerId,
}, function(err, call) {
if (err) { console.error('There was a problem starting the call: ', err); }
console.log('Call with sid: ${call.sid} was started');
});
xml response for url is
router.post('/callSecond', function(request, response) {
const voiceResponse = new VoiceResponse();
const dial = voiceResponse.dial({ callerId: 'client:al' });
voiceResponse.say("Congratulations! You have received your first inbound call! Good bye. Welcome to Twilio! Welcome to Twilio!!!! Welcome to Twilio");
dial.client("leo");
console.log('Response :' + voiceResponse.toString());
response.send(voiceResponse.toString());
});
Can anyone please help me to find a solution for this, speaking to each other using twilio mobile application.
Thank you in advance

Related

Not getting the "MESSAGE_DELIVERED" Firebase event

I am trying to measure the latency between having a message exit Firebase Servers and being received on an Android app via the Firebase SDK. I have BigQuery integrated with my Firebase project, and have tried adding the following code:
// In the manifest:
<meta-data android:name= "delivery_metrics_exported_to_big_query_enabled"
android:value="true"/>
// In my Application object:
FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(true);
The code seems to be exporting data to BigQuery. However, to calculate what I want I need timestamps for two different types of events associated to the same message id, "MESSAGE_ACCEPTED" and "MESSAGE_DELIVERED". Then, all I have to do is run a simple query that calculates the timestamp difference between those two.
My problem is: I can never seem to get the "MESSAGE_DELIVERED" variant for a given message id. I only ever get the "MESSAGE_ACCEPTED" side of the equation.
I am sending messages to the Android device via my own JavaScript app, and the request I make is like so:
app.get('/triggerAnt', function(req, res){
axios.post('https://fcm.googleapis.com/fcm/send', {
to:<TOKEN_FOR_DEVICE_GOES_HERE>,
notification:{
"title":"TESTNOTIFICATIONLATENCY",
"body":"TESTINGLATENCY"
},
fcm_options: {
analytics_label:<LABEL_HERE>
}
}, {headers: headers})
.then((response) => {
console.log(response.status);
}, (error) => {
console.log(error);
});
})
I would like to point out that the notification does effectively reach the device and I can open it too.
Is this delay on BigQuery's side or am I doing something wrong?
Thank you.

how to send SMS or make a phone call from a samsung gear s app

i am trying to find a way to send SMS and make a phone call from a samsung gear s app.
the documentation is mostly missing and searching for this did not lead to much findings.
has anybody worked with that? is it at all possible?
as an alternative, if the app cannot send SMS or make the call, is it possible to start the default apps (similar to Android intent for SMS/Phone app or iOS openURL).
thanks.
#memical - I have found a workaround to launch message/sms app using the app id.
<p onclick="hackSMS();">Send SMS</p>
<script>
function hackSMS() {
tizen.application.launch("com.samsung.message", function(){console.log ("Launched")});
}
</script>
Remember to add this http://tizen.org/privilege/application.launch priviege in your apps config.xml
Note: I tried other methods also like using exposed tizen platform api's for web apps to launch some predefined app control. But it is working for Call and not for sms.
here is what i find so far:
to make a call from a Gear S app use the following code:
var appControl = new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/call", "tel:001....");
tizen.application.launchAppControl(appControl, null,
function() {
console.log("ok");
},
function(e)
{
console.log("error: " + e.message);
},
{
onsuccess : function()
{
console.log("ok 2");
},
onfailure : function(er)
{
console.log("error 2: " + er.message);
}
});
sending SMS is not possible at this time.
There is no messaging API implemented on Tizen for wearable devices. You can check it yourself by calling:
console.log(tizen.messaging);
It will return 'undefined'
It means that you can't programmatically send or read an SMS or an email from your wearable device using Tizen messaging API.
To open the app for make a call try this code:
Uri number = Uri.parse("tel:"+telNumber);
Intent openCallIntent = new Intent(Intent.ACTION_DIAL, number);
startActivity(openCallIntent);
To make a call:
Uri number = Uri.parse("tel:"+telNumber);
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(number);
startActivity(callIntent);
To send an sms:
Intent sendSmsIntent = new Intent(Intent.ACTION_VIEW);
sendSmsIntent.setType("vnd.android-dir/mms-sms");
sendSmsIntent.putExtra("address", telNumber);
sendSmsIntent.putExtra("sms_body","Whatever you want");
startActivity(sendSmsIntent);
Similar questions to this one are already answered in stackoverflow
Try this which is very simple as compare to using the platform APIs.
http://www.w3.org/TR/mwabp/#bp-interaction-uri-schemes
The most broadly supported scheme is tel: as described in RFC3966
[RFC3966]. Code such as the following can be used to enable
"Click-to-Call":
[PHONE-NUMBER]
Note that [PHONE-NUMBER] should always be entered using the full
international prefix (e.g. +1-201-555-0111) to ensure that it works
outside of its home country.
Similarly RFC5724 [RFC5724] can be used to send a GSM SMS (text
message) as follows:
[PHONE-NUMBER]
Note that at the time of writing support for this RFC is limited and
device compatibility should be verified before deployment.

how to make a chat between two people with android socketio module on nodejs server?

I work to develop a chat app with android on node.js server.I made a simple chat app.But everyone gets involved in the same room.I want to make a chat between only two people.How can I do that? What information should I send to the server?such as sender_name,receiver_name,message as a json format.
-How can I to do list online-users?
-And How can I start a chat between only two people?
What are the requirements for it?
This might help:
I'd recommend setting up namespaces for each room you have your chat in. I did something similar in my own code. Note: Rooms and namespaces are a little different from each other in socket.io itself (socket.io has both: http://socket.io/docs/rooms-and-namespaces/).
In the Server code:
I have a method under socket.on('connection') that is similar to
socket.on('groupConnect', function(group){
var groupNsp = io.of('/' + group);
}
This essentially makes sure that a namespace is exists under the name of the desired one. It doesn't mess it up or reset the namespace when it is called again.
Then for receiving the messages:
socket.on('message', function(data){
var msg = data.msg;
var nsp = data.nsp;
io.of(nsp).emit('message', msg);
}
You could also add the nsp to the data you have already and then just send the data again to the clients.
Then, in the client code:
var socketOut = io.connect('http://yourdomain:1337/');
var someGroupOrMethodToGetGroup;
socketOut.emit('groupConnect', someGroupOrMethodToGetGroup);
var nsp;
setTimeout(function(){
socket = io.connect('http://yourdomain:1377/' + someGroupOrMethodToGetGroup);
socket.on('message', function(msg){
displayMessage(msg);
}
nsp = '/' + someGroupOrMethodToGetGroup;
}, 1500);
Then in my displayMessage code I have:
socketOut.emit('message', { msg: desiredMessage, nsp: nsp });
From another answer of mine (https://stackoverflow.com/a/24805494/3842050).

WebRTC flow of function calls for making calls [Android]

I am referring and also going through source code of AppRTCDemo which is a demo application for WebRTC.
What i am trying is:
Build my own WebRTC application which will do AV calls on a Android Device.
Replace existing https://apprtc.appspot.com/ server and related functionality.
For archiving above points, I want to understand basic flow of WebRTC function calls and steps to make/receive calls (functions that i need to calls and there flow).
I have gone through the source code and understood few things,
but as code is pretty complicated to understand, and without any documentation.
It will be great help if some one provides any examples or documents explaining the steps for making/receiving AV calls (how we get/set SDP, how to render local/remote video etc.).
I have seen these posts and are very helpful:
WebRTC java server trouble
https://www.webrtc-experiment.com/docs/WebRTC-PeerConnection.html
I am able to build and run AppRTCDemo App.
Any help on this will be great help!
There is no timeline, it's asynchronous but i will try to explain but there is two main flow, the flow of offer and answer with SDP and the flow of icecandidate.
Flow 1 : SDP
Step 1 - Offer peer :
On the offer side, create a RTCPeerconnection (with stun, trun servers as parameters).
var STUN = {
url:'stun:stun.l.google.com:19302'
};
var TURN = {
url: 'turn:homeo#turn.bistri.com:80',
credential: 'homeo'
};
var iceServers = {
iceServers: [STUN, TURN]
};
var peer = new RTCPeerConnection(iceServers);
Step 2 - Offer peer :
Call getUserMedia with your constraints. In the success callback, add the stream to the RTCPeerconnection using the addStream method. Then you can create the offer with calling createOffer on the Peerconnection Object.
navigator.webkitGetUserMedia(
{
audio: false,
video: {
mandatory: {
maxWidth: screen.width,
maxHeight: screen.height,
minFrameRate: 1,
maxFrameRate: 25
}
}
},
gotStream, function(e){console.log("getUserMedia error: ", e);});
function gotStream(stream){
//If you want too see your own camera
vid.src = webkitURL.createObjectURL(stream);
peer.addStream(stream);
peer.createOffer(onSdpSuccess, onSdpError);
}
Step 3 - Offer peer :
In the callback method of the createOffer, set the parameter (the sdp offer) as the localDescription of the RTCPeerConnection (who will start gathering the ICE candidate). Then send the offer to the other peer using the signaling server. (I will not describe signaling server, it's just passing data to one from another).
function onSdpSuccess(sdp) {
console.log(sdp);
peer.setLocalDescription(sdp);
//I use socket.io for my signaling server
socket.emit('offer',sdp);
}
Step 5 - Answer peer :
The answer peer, each time it receives an offer, create a RTCPeerconnection with TURN, STUN server, then getUserMedia, then in the callback, add the stream to the RTCPeerConnection. With the SDP offer use setRemoteDescription with the sdpOffer. Then Trigger the createAnswer.
In the success callback of the createAnswer, use setLocalDescription with the parameter and then send the answer sdp to the offer peer using signaling server.
//Receive by a socket.io socket
//The callbacks are useless unless for tracking
socket.on('offer', function (sdp) {
peer.setRemoteDescription(new RTCSessionDescription(sdp), onSdpSuccess, onSdpError);
peer.createAnswer(function (sdp) {
peer.setLocalDescription(sdp);
socket.emit('answer',sdp);
}, onSdpError);
});
Step 7 : Offer peer
Receive the sdp answer, setRemoteDescription on the RTCPeerConnection.
socket.on('answer', function (sdp) {
peer.setRemoteDescription(new RTCSessionDescription(sdp), function(){console.log("Remote Description Success")}, function(){console.log("Remote Description Error")});
});
Flow 2 : ICECandidate
Both side :
Each time the RTCPeerConnection fire onicecandidate, send the candidate to the other peer through signalingserver.
When a icecandidate is received, coming from signaling server, just add it to the RTCPeerConnection using the addIceCandidate(New RTCIceCandidate(obj))
peer.onicecandidate = function (event) {
console.log("New Candidate");
console.log(event.candidate);
socket.emit('candidate',event.candidate);
};
socket.on('candidate', function (candidate) {
console.log("New Remote Candidate");
console.log(candidate);
peer.addIceCandidate(new RTCIceCandidate({
sdpMLineIndex: candidate.sdpMLineIndex,
candidate: candidate.candidate
}));
});
Finally :
If two flow above works well use the onaddstream event on each RTCPeerConnection. When ICE Candidates will pair each other and find the best way for peer-to-peer, they will add the stream negociated with the SDP and that is going through the peer to peer connection. So in this event, you juste need to add your stream then to a video tag for example and it's good.
peer.onaddstream = function (event) {
vid.src = webkitURL.createObjectURL(event.stream);
console.log("New Stream");
console.log(event.stream);
};
I will edit tommorow with some code i think to help understand what i'm saying. If have question go for it.
Here is my signaling server :
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3000);
app.get('/', function (req, res) {
res.send('The cake is a lie');
});
io.on('connection', function (socket) {
console.log('NEW CONNECTION');
socket.on('offer', function (data) {
console.log(data);
socket.broadcast.emit("offer",data);
});
socket.on('answer', function (data) {
console.log(data);
socket.broadcast.emit("answer",data);
});
socket.on('candidate', function (data) {
console.log(data);
socket.broadcast.emit("candidate",data);
});
});

Android: Using server-side when working with Parse

Me and my friend are working on an app., and we wish to use Parse.com as our data base from which we can retrieve info.
We can't decide what is the best way to access the data on Parse. For the sake of the example, our app. (i.e. client side) needs something stored on the Parse data base (say some number) - should it directly run the query using the Parse API, or should it make a request to a server side, let it retrieve that number from Parse, and send it back to the client?
We know there's no definite answer, but we couldn't find answer regarding this specific situation. We read this post: When to use client-side or server-side?,
but this not exactly the same case.
I claim that we should try to seperate as much as possible from client side and data bases, and leave these queries run by someone who's in charge (server), where my friend claims this adds unnecessary complication, since it's very natural to use the tools supplied by Parse to access the data base from the client side, without the need for a protocol etc.
We'd appriciate any advice,
Thank you.
In general, go right ahead and make a normal call.
I'd encourage you to do that first in any case, to get everything working on both ends.
Then if necessary go to Cloud Code.
If you are going to do more than one platform (ie iOS and Android), cloud code can be a huge timesaver.
BUT don't forget that for simple calls, cloud code is a waste of time. "Normal" Parse calls are amazingly, incredibly, amazingly, fast and quick to work with.
There is absolutely nothing "wrong" with using normal Parse calls - so do that.
Regarding the question, when do you literally have to use a cloud code call -- you'll know, because you won't be able to do it with a normal call :)
Don't forget very often you can simply use "afterSave" or "beforeSave" in cloud code, to do a huge amount of work. You often don't literally need to go to a "custom call" in cloud code.
Here's a fantastic
Rule of thumb for Parse cloud code --------->
If you have to do "more than one thing" ... in that case you will likely have to make it a cloud code function. If you have to do "three or more things" then DEFINITELY make it a cloud code function.
That's a good rule of thumb.
(Again, as I say, often just an "afterSave" or similar works brilliantly...rather than literally writing a full custom call.)
Here's a typical example of a cloud call that saves 18 billion lines of code in all the platforms covered by the dotcom. First the cloud code...
Parse.Cloud.define("clientRequestHandleInvite", function(request, response)
{
// called from the client, to accept an invite from invitorPerson
var thisUserObj = request.user;
var invitorPersonId = request.params.invitorPersonId;
var theMode = request.params.theMode;
// theMode is likely "accept" or "ignore"
console.log( "clientRequestAcceptInvite called.... invitorPersonId " + invitorPersonId + " By user: " + thisUserObj.id );
console.log( "clientRequestAcceptInvite called.... theMode is " + theMode );
if ( invitorPersonId == undefined || invitorPersonId == "" )
{
response.error("Problem in clientRequestAcceptInvite, 'invitorPersonId' missing or blank?");
return;
}
var query = new Parse.Query(Parse.User);
query.get(
invitorPersonId,
{
success: function(theInvitorPersonObject)
{
console.log("clientRequestFriendRemove ... internal I got the userObj ...('no response' mode)");
if ( theMode == "accept" )
{
createOneNewHaf( thisUserObj, theInvitorPersonObject );
createOneNewHaf( theInvitorPersonObject, thisUserObj );
}
// in both cases "accept" or "ignore", delete the invite in question:
// and on top of that you have to do it both ways
deleteFromInvites( theInvitorPersonObject, thisUserObj );
deleteFromInvites( thisUserObj, theInvitorPersonObject );
// (those further functions exist in the cloud code)
// for now we'll just go with the trick of LETTING THOSE RUN
// so DO NOT this ........... response.success( "removal attempt underway" );
// it's a huge problem with Parse that (so far, 2014) is poorly handled:
// READ THIS:
// parse.com/questions/can-i-use-a-cloud-code-function-within-another-cloud-code-function
},
error: function(object,error)
{
console.log("clientRequestAcceptInvite ... internal unusual failure: " + error.code + " " + error.message);
response.error("Problem, internal problem?");
return;
}
}
);
}
);
If you are new to Parse it's incredibly hard to figure out how to call these from Android or iOS! Here's that one being called from Android ...
this will save you a day of messing about with HashMaps :)
private static void handleInvite( ParseUser invitor, final boolean accepted )
{
String invitorId = invitor.getObjectId();
// you must SEND IDs, NOT PARSEUSER OBJECTS to cloud code. Sucks!
String cloudKode;
cloudKode = (accepted? "accept" : "ignore");
HashMap<String, Object> dict = new HashMap<String, Object>();
dict.put( "invitorPersonId", invitorId );
dict.put( "theMode", cloudKode );
Toast.makeText(State.mainContext, "contacting...", Toast.LENGTH_SHORT).show();
ParseCloud.callFunctionInBackground(
"clientRequestHandleInvite",
dict,
new FunctionCallback<Object>()
{
#Override
public void done(Object s, ParseException e)
{
Toast.makeText(State.mainContext, "blah", Toast.LENGTH_SHORT).show();
// be careful with handling the exception on return...
}
});
}
And here's the same cloud call from iOS ... well for now, until you have to do it in SWIFT
-(void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
int thisRow = indexPath.row;
PFUser *delFriend = [self.theFriends objectAtIndex:thisRow];
NSLog(#"you wish to delete .. %#", [delFriend fullName] );
// note, this cloud call is happily is set and forget
// there's no return either way. life's like that sometimes
[PFCloud callFunctionInBackground:#"clientRequestFriendRemove"
withParameters:#{
#"removeThisFriendId":delFriend.objectId
}
block:^(NSString *serverResult, NSError *error)
{
if (!error)
{
NSLog(#"ok, Return (string) %#", serverResult);
}
}];
[self back]; // that simple
}
Note For the iOS/Swift experience, click to: How to make this Parse.com cloud code call? which includes comments from the Parse.com team. Hope it saves someone some typing, cheers

Categories

Resources