Blind Transfer in JSSIP - webrtc

I have been trying to make a blind transfer on a ongoing call.
Below is the code i have implemented:
transfersession(ext) {
this.rtcSession.refer('sip:' + ext + '#' + serveraddress);
}
Can someone tell is there something more I have to write?
The above code disconnects the ongoing call and adds the call to he queue.
What mistake am I doing? Thanks in advance.

This is my code to make a blind transfer
function makeBlindTransfer(numberToTransfer) {
let eventHandlers = {
requestSucceeded: function (e) {
console.log("Transferencia realizada con exito");
},
requestFailed: function (e) {
console.log("Transferencia fallo");
},
trying: function (e) {
console.log("trying", e);
},
progress: function (e) {
console.log("progress", e);
},
accepted: function (e) {
console.log("accepted", e);
},
failed: function (e) {
console.log("failed", e);
},
};
try {
ssession.refer(numberToTransfer, {
eventHandlers,
extraHeaders: [`Contact: <sip:${dest}#yourhost:yourport>`],
});
} catch (err) {
console.log("no pudimos realizar su solicitud");
}
}
you can check in the documentation too:
https://jssip.net/documentation/2.0.x/api/refer_subscriber/
https://jssip.net/documentation/2.0.x/api/session/#method_refer

Other side should support refer. However, that can be insecure, so disabled by most of providers.
Anyway, you should learn how to use tcpdump/wireshark and check sip trace.

Related

position payload in attribute for action?

Where I must type 'payload' in attributes for action?
In {} brackets or outside?
1 option:
async loadData( {state, payload, dispatch}) {
try {
...omitted
}
} catch (e) {
console.error(e)
}
},
2 option:
async loadData( {state,dispatch}, payload) {
try {
...omitted
}
} catch (e) {
console.error(e)
}
},
The first argument can be destructured to access a lot of useful things to access some state, run a quick mutation etc...more details here: https://vuex.vuejs.org/api/#actions
The second argument is the actual payload that you are passing if you want to update something with some data.
Not to confuse with a dispatch where you pass the name + payload directly.
So, option 2.

Loop expo biometric authentication until success

I'm trying to implement a biometric authentication (faceID / fingerprint) on Android using React-native with Expo.
Using the LocalAuthentication.authenticateAsync() function, the user is able to authenticate with his biometry. But if it fail, the user have to press the biometric authentication again.
So i tried a little trick with a recursif or do while loop but the result is strange :
const scanFingerPrint = async () => {
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
} catch (e) {
console.log(e);
}
};
With this code, if the user fail the biometric authentication, it will pass in the "else" infinitly...
So I was wondering how to handle that on android.
You can handle it manually using a variable.
First create variable retryCount inside constructor or as a property of class so that it is accessible in each function.
constructor(props) {
super(props);
this.retryCount = 3;
}
set the value of retryCount before calling scanFingerPrint function.
this.retryCount = 3; //number of attempts you want to provide
Now modify function like below to prevent infinite loop:
const scanFingerPrint = async () => {
try {
if (this.retryCount <= 0){
//exceeded the number of attempts..try again after a minute
} else{
this.retryCount--;
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
}
} catch (e) {
console.log(e);
}
};
You can pass function variable for attempts.
see this,
const scanFingerPrint = async (remainingAttempts = 5) => { // you can change 5 as per your choice
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential().then(credentials =>
onScan(credentials)
);
} else {
ShakeAnimation(animatedValueModal);
if (remainingAttempts) {
remainingAttempts--;
scanFingerPrint(remainingAttempts);
} else {
alert("You have exceeded max scan limit.");
}
}
} catch (e) {
console.log(e);
}
};
and you do not need to change anything else. not event your first time function call.
Expo provide an "error" key on the results of the local authentication. To not handle an hardware error i used this :
if (!results.success) {
switch (results.error) {
case "lockout":
setLocked(true);
break;
case "authentication_failed" || "too_fast":
ShakeAnimation(animatedValueModal);
await scanBiometric();
break;
case "user_cancel" :
break;
default:
ShakeAnimation(animatedValueModal);
break;
}
}

Access component's this inside firebase promise reposonse

I've tried to bind it like it doesn't seem to make the trick :)
firebaseInstance.auth().fetchSignInMethodsForEmail(this.signUpData.email)
.then((response) => {
... all logic
}).bind(this)
...since it outputs the following error:
firebaseInstance.auth(...).fetchSignInMethodsForEmail(...).bind is not a function
Here is the component's logic, can someone please suggest a proper way to access this after firebase response resolves? :bowing:
import { VALIDATION_MESSAGES, VALUES } from './signup.module.config'
import GLOBAL_EVENTS from 'values/events'
import { firebaseInstance } from 'database'
export default {
name: `SignUpForm`,
data() {
return {
signUpData: {
email: ``,
password: ``,
confirmPassword: ``
}
}
},
methods: {
onEmailSignUp() {
// Here this is component
console.log(this.$refs)
firebaseInstance.auth().fetchSignInMethodsForEmail(this.signUpData.email)
.then((response) => {
// other logic
} else {
// Here this is lost and equals undefined
this.$refs.email.setCustomValidity(`error`)
}
})
}
}
}
The bind instruction should be used on a function object, not on a function return value.
By doing
firebaseInstance.auth().fetchSignInMethodsForEmail(this.signUpData.email)
.then((response) => {
... all logic
}).bind(this)
You try to use bind on the return of the then method of you promise, which is a promise object and can't use bind.
You can try firebaseInstance.auth().fetchSignInMethodsForEmail(this.signUpData.email)
.then(function(response){
... all logic
}.bind(this))
instead. Here the bind is put on the function send in the promise so it should work correctly. I also transformed the function from arrow function to normal, because I think there is no need for arrow function with bind.
Using ES8 async/await sugar syntax you can do it like this :
async onEmailSignUp () {
try {
const response = await firebaseInstance.auth().fetchSignInMethodsForEmail(this.signUpData.email)
// other logic
} catch (error) {
console.log(error)
this.$refs.email.setCustomValidity(`error`)
}
}

Laravel echo listen for whisper function not working

I'm building a live chat app, but I found that listenforwhisper function is not working, but .whisper() function works fine, pusher also received client typing event.
Here is my code:
For listen whisper:
Echo.private(`messages.${this.user.id}`)
.listen("NewMessage", (e) => {
this.handleIncoming(e.message);
})
.listenForWhisper("typing", (e) => {
if(e.name !='') {
this.typeStatus = 'typing .........'
}
else {
this.typeStatus = ''
}
console.log(this.typeStatus);
});
For whisper:
watch: {
message() {
Echo.private(`messages.${this.user.id}`)
.whisper("typing", {
name: this.message
});
}
}
For channel:
Broadcast::channel('messages.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Theoretically, my console will return the typeStatus, but I got nothing in my console.
Whisper works like broadcastToOthers. You're now trying to listen for the current users whispers. You should have a room where the whisper goes to and there should be multiple clients there to recieve. Now your channel is tied to the user and no-one else can see the messages that go through that channel.
Ok, I step in same issue. I got 2 channels and 2 users. I set a interval with wisper
setInterval(() => {
channel.whisper('typing', {
message: 'hola!'
});
}, 3000);
channel.listenForWhisper('typing', (e) => {
console.log('Typing');
console.log(e);
})
The thing was that I was receving events but won't be able to see the output from listenForWhisper until I connect the second user to the channel.
Once the second user is connected, it's works just fine. So I leaved her if you got same issue.

How do I take a screenshot when a test in internjs fails?

I am having issues figuring out how to take a screenshot ONLY when a test fails in InternJs. I have this simple test in my registerSuite;
'verify google homepage': function () {
var url = 'https://www.google.com/';
return this.remote
.get(url)
.getCurrentUrl()
.then(function (data) {
assert.strictEqual(data, url, 'Incorrect URL');
})
.findByName('q')
.click()
}
I can simply create a screenshot using the following code;
.takeScreenshot
.then(function (data) {
fs.writeFileSync('/path/to/some/file', data, 'base64');
)}
I want to only take a screenshot, if the above test fails the assertion or is unable to find the locator.
I looked into the afterEach method, but I can't figure out how to get the status of the last test to apply a conditional.
So my question is, has anyone setup their internjs test to only take screenshots on failures and how was it accomplished?
It is not currently possible to interact with the currently executing test from beforeEach or afterEach methods; this capability is coming in the next version of Intern.
Selenium server, by default, provides a screenshot on every Selenium command failure, which is a Buffer object on the error.detail.screen property. If a Selenium command fails, just use this property which already has the screenshot waiting for you.
For assertion failures, you can create a simple promise helper to take a screenshot for you:
function screenshotOnError(callback) {
return function () {
try {
return callback.apply(this, arguments);
}
catch (error) {
return this.remote.takeScreenshot().then(function (buffer) {
fs.writeFileSync('/path/to/some/file', buffer);
throw error;
});
}
};
}
// ...
'verify google homepage': function () {
return this.remote.get(url).getCurrentUrl().then(screenshotOnError(function (actualUrl) {
assert.strictEqual(actualUrl, url);
}));
}
If it’s too inconvenient to wrap all your callbacks manually like this, you can also create and use a custom interface for registering your tests that wraps the test functions automatically for you in a similar manner. I’ll leave that as an exercise for the reader.
You can use catch method at the end of your chain and use error.detail.screen as suggested by C Snover.
'verify google homepage': function () {
return this.remote
.get(require.toUrl('./fixture.html'))
.findById('operation')
.click()
.type('hello, world')
.end()
.findById('submit')
.click()
.end()
.catch(function(error){
fs.writeFileSync('/tmp/screenshot.png', error.detail.screen);
})
}
I've been playing with this today and have managed to get it for an entire suite rather than needing to add the code to every single test which seems quite needless.
var counter = -1,
suite = {
beforeEach: function () {
counter++;
},
afterEach: function () {
var currentTest = this.tests[counter];
if (!currentTest.error) {
return;
}
this.remote
.takeScreenshot().then(function (buffer) {
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
fs.writeFileSync('/tmp/' + currentTest.name + '.png', buffer);
});
}
};
The annoying thing you will need to do is do this for every test suite rather than "globally" but is much better than doing it for every test.
Building on the answer by Hugo Oshiro,
// tests/support/CleanScreenshots.js
define([
'intern/dojo/node!path',
'intern/dojo/node!del',
], function(path, del) {
return new Promise((resolve, reject) => {
let directory = 'tests/screenshots';
del(path.join(directory, '**/*'))
.then(resolve)
.catch(reject);
});
});
Then in your intern config:
/* global define */
define([
'tests/support/CleanScreenshots'
], function (CleanScreenshots) {
return {
...
setup: function () {
return CleanScreenshots();
},
...
};
});
According to this issue, starting with the Intern 3.0 you can do a custom reporter that take an Screenshots when test fail. So you can centralize it in a simple way, just referencing the custom reporter in your config.js. In my case, what can I just add a reporter array in the config.js with the path to my custom array:
reporters: [
{ id: 'tests/support/ScreenShot' }
],
than I made an custom reporter overriding testFail:
'use strict';
define([
'intern/dojo/node!fs',
], function(fs) {
function ScreenShot(config) {
config = config || {};
}
ScreenShot.prototype.testFail = function(test) {
test.remote.takeScreenshot().then(function(buffer) {
try {
fs.writeFileSync('./screenshots/' + test.parent.name.replace(/ /g, '') + '-' +
test.name.replace(/ /g, '') + '.png', buffer);
} catch (err) {
console.log('Failed to take a screenshot: ' + err);
}
});
};
return ScreenShot;
});
Pay attention to the relative paths both to reference the custom reporter and the place for screenshots. They all seems to be taken considering where you run intern-runner, not the place the source files are located.
For more info about custom reporters go to this page.