Twilio callback status of an outbound call is always 'completed' - callback

I'm trying to create an IVR Phone tree through REST API in Salesforce (Twilio API). The problem is that I can't catch any other callback status except 'completed'.
If the call was cancelled or there was no response on this call, Twilio sends a call response with 'completed' status anyway.
Moreover, a customer gets a voicemail with a recorded 'welcome' message and first phone tree question after an unsuccessful call attempt.
There is a code sample of how calls are created :
TwilioRestClient client = new TwilioRestClient(TwilioSID, TwilioToken);
Map<String,String> params = new Map<String, String>();
String webURL = webServerURL;
params.put('To', phone);
params.put('From', phoneFrom);
params.put('Url', webURL);
params.put('Method', 'GET');
params.put('FallbackUrl', webURL);
params.put('FallbackMethod', 'GET');
params.put('StatusCallback', webURL);
if (!System.Test.isRunningTest()) {
try {
TwilioCall call = client.getAccount().getCalls().create(params);
} catch(Exception ex) {
}
}
In addition, I was trying to add 'StatusCallbackEvent' parameter (link to Twilio documentation - https://www.twilio.com/docs/voice/twiml#callstatus-values) :
params.put('StatusCallbackEvent', 'busy canceled completed failed no-answer');
// and other optiions like :
// params.put('StatusCallbackEvent', 'busy');
// params.put('StatusCallbackEvent', 'canceled');
// params.put('StatusCallbackEvent', 'completed');
// params.put('StatusCallbackEvent', 'failed');
// params.put('StatusCallbackEvent', 'no-answer');
But there was no any difference in a callback status after failed calls.
How should I make calls to get Twilio call responses with all finalized statuses ('busy', 'failed', 'no-answer', etc ...) ?

Twilio developer evangelist here.
When you set a URL for the StatusCallback then by default you will only receive callbacks when the call is "completed". A completed call may have different reasons for being completed though, such as "busy", "failed", "no-answer" or plain "completed" and you can read that value from the CallStatus parameter that is sent to the URL.
You can subscribe to other events though, as you tried. The only thing is you were trying to subscribe to the potential statuses and not the events themselves.
For a call you can subscribe to "initiated", "ringing", "answered" and "completed". So try:
params.put('StatusCallbackEvent', 'initiated ringing answered completed');

Related

How to return a result to ui from multiple Rest API calls in flutter?

I have 4 API request for money transfer
Authorize
GetBeneficiary
AddBenificiary
RequestTransfer
Now I need to get the result of request transfer and return to the UI and say 'Transfer is successful', and also if any of those API fail in between I need to send to the UI.
I have return something like this:
authorize(){
getBeificiary();
}
getBeificiary(){
if(no benificiary){
addBeificiary();
}else{
requestTransfer();
}
addBenificiary(){
requestTransfer();
}
requestTransfer(){
return 'message';
}
use like this:
var response=Future.wait([<list of apis>]);
// use response as response[0], response[1] as respective to the apis given in the line.

Tell wether or not a mint call to a contract succeeded

I'm working on an NFT site in NextJS and trying to implement a redirect for the user after they successfully mint a token. Here's my mint code:
const mintToken = () => {
safeMint?.();
router.push('/success');
};
As you can see, after safeMint is called, I try to redirect to /success which is what happens. However, it redirects regardless of a successful mint, I want it to only redirect after the call to the smart contract succeeds. I've tried using callbacks and timeouts but nothing seems to work the way I've laid out above. Is there some way of getting or waiting for a success response before redirecting that I'm missing? Thanks!
Function return value is not available outside of EVM if you execute the function with a transaction.
You can wait for the transaction receipt. It contains the transaction status (success / revert), as well as event logs. Tx receipt is available only after the tx is included in a block.
Depending on your safeMint() implementation, it might mint tokens each time the transaction succeeds. But if your implementation allows for the function to succeed even without minting tokens, you might need to check the event logs to make sure that the NFT was really minted.
// transaction reverted
function safeMint() external {
require(failedCondition);
_mint(msg.sender, tokenId);
}
// transaction succeeded but no token was minted
function safeMint() external {
if (failedCondition) {
_mint(msg.sender, tokenId);
}
}
How to wait for the receipt with ethers:
const tx = await myContract.safeMint();
const txReceipt = await transaction.wait();
if (txReceipt.status) {
// not reverted
}
Docs:
https://docs.ethers.io/v5/api/providers/types/#providers-TransactionResponse
https://docs.ethers.io/v5/api/providers/types/#providers-TransactionReceipt
in safeMint function inside contract, you can return the tokenId (or you could return true)
const mintToken =async () => {
const result=await safeMint?();
if(result){
router.push('/success');
}
};

what are the differences beetween notifyUrl response and completePurchase response?

i'm try to use omnipay/paypal, i use this code for returnUrl page:
public function completePayment(Request $request)
{
//return 'pagina dopo acquisto';
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername('blastor_89-facilitator_api1.msn.com');
$gateway->setPassword('BEWB2BEW9CHCV3EQ');
$gateway->setSignature('AFcWxV21C7fd0v3bYYYRCpSSRl31AC5Dp4AnVYBnMIkNFxSQTj8h.lqD');
$gateway->setTestMode(true);
$params = session()->get('params');
$response = $gateway->completePurchase($params)->send();
$paypalResponse = $response->getData();
//$this->store($paypalResponse);
if(isset($paypalResponse['PAYMENTINFO_0_ACK']) && $paypalResponse['PAYMENTINFO_0_ACK'] === 'Success') {
// here you process the response. Save to database ...
}
else {
// Failed transaction ...
}
}
it response with $paypalResponse, while if i use notifyUrl page what do notifyUrl response? what are the differences?
These two responses are completely different although they contain the same basic idea.
The complete purchase response has the data from your call to completePurchase(). The notify response has data that is fed into your application from a notify (PayPal IPN) call. I suggest that you dump the data from each one to take a look.

Parse.com resend verification email

I am using the email verification feature that Parse offers and would like my users to be able to resend the email verification if it fails to send or they cannot see it. Last I saw, Parse does not offer an intrinsic way to do this (stupid) and people have been half-hazzerdly writing code to change the email and then change it back to trigger a re-send. Has there been any updates to this or is changing the email from the original and back still the only way? Thanks
You should only need to update the email to its existing value. This should trigger another email verification to be sent. I haven't been able to test the code, but this should be how you do it for the various platforms.
// Swift
PFUser.currentUser().email = PFUser.currentUser().email
PFUser.currentUser().saveInBackground()
// Java
ParseUser.getCurrentUser().setEmail(ParseUser.getCurrentUser().getEmail());
ParseUser.getCurrentUser().saveInBackground();
// JavaScript
Parse.User.current().set("email", Parse.User.current().get("email"));
Parse.User.current().save();
You have to set the email address to a fake one save and then set it back to the original and then parse will trigger the verification process. Just setting it to what it was will not trigger the process.
iOS
if let email = PFUser.currentUser()?.email {
PFUser.currentUser()?.email = email+".verify"
PFUser.currentUser()?.saveInBackgroundWithBlock({ (success, error) -> Void in
if success {
PFUser.currentUser()?.email = email
PFUser.currentUser()?.saveEventually()
}
})
}
Poking around the source code for Parse server, there doesn't seem to be any public api to manually resend verification emails. However I was able to find 2 undocumented ways to access the functionality.
The first would be to use the internal UserController on the server (for instance from a Cloud function) like this:
import { AppCache } from 'parse-server/lib/cache'
Cloud.define('resendVerificationEmail', async request => {
const userController = AppCache.get(process.env.APP_ID).userController
await userController.resendVerificationEmail(
request.user.get('username')
)
return true
})
The other is to take advantage of an endpoint that is used for the verification webpage:
curl -X "POST" "http://localhost:5000/api/apps/press-play-development/resend_verification_email" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{ "username": "7757429624" }'
Both are prone to break if you update Parse and internals get changed, but should be more reliable than changing the users email and then changing it back.
We were setting emails to an empty string, but found that there was a race condition where 2 users would hit it at the same time and 1 would fail because Parse considered it to be a duplicate of the other blank email. In other cases, the user's network connection would fail between the 2 requests and they would be stuck without an email.
Now, with Parse 3.4.1 that I'm testing, you can do (for Javascript):
Parse.User.requestEmailVerification(Parse.User.current().get("email"));
BUT NOTE that it will throw error if user is already verified.
Reference:
http://parseplatform.org/Parse-SDK-JS/api/3.4.1/Parse.User.html#.requestEmailVerification
To resend the verification email, as stated above, you have to modify then reset the user email address. To perform this operation in secure and efficient way, you can use the following cloud code function:
Parse.Cloud.define("resendVerificationEmail", async function(request, response) {
var originalEmail = request.params.email;
const User = Parse.Object.extend("User");
const query = new Parse.Query(User);
query.equalTo("email", originalEmail);
var userObject = await query.first({useMasterKey: true});
if(userObject !=null)
{
userObject.set("email", "tmp_email_prefix_"+originalEmail);
await userObject.save(null, {useMasterKey: true}).catch(error => {response.error(error);});
userObject.set("email", originalEmail);
await userObject.save(null, {useMasterKey: true}).catch(error => {response.error(error);});
response.success("Verification email is well resent to the user email");
}
});
After that, you just need to call the cloud code function from your client code. From Android client, you can use the following code (Kotlin):
fun resendVerificationEmail(email:String){
val progress = ProgressDialog(this)
progress.setMessage("Loading ...")
progress.show()
val params: HashMap<String, String> = HashMap<String,String>()
params.put("email", email)
ParseCloud.callFunctionInBackground("resendVerificationEmail", params,
FunctionCallback<Any> { response, exc ->
progress.dismiss()
if (exc == null) {
// The function executed, but still has to check the response
Toast.makeText(baseContext, "Verification email is well sent", Toast.LENGTH_SHORT)
.show()
} else {
// Something went wrong
Log.d(TAG, "$TAG: ---- exeception: "+exc.message)
Toast.makeText(
baseContext,
"Error encountered when resending verification email:"+exc.message,
Toast.LENGTH_LONG
).show()
}
})
}

Facebook get number of sent requests and accepted request

i need to make a page that will have a request dialog for a facebook page or a facebook app.
I need to get the number of friends the user sent the request to and at the end of the day the number of request that got accpeted from the specific user.
The scenario is for giving awards , the user that sent the most request to freinds gets an award and the user that had the most requests accepted also gets an award.
I dont know if the seccond is possible , but i think it should be , couse games on FB give u points for sent request and also u get new missions when friends accept your request , so there mut be a way.
--
I will record the number of invites sent.
Return Data
request_ids
A comma-separated list of the request_ids that were created. To learn who the requests were sent to, you should loop through the information for each request object identified by a request id.
FB.ui({
method: 'apprequests',
title:'Suggest '+fbAppName+' to your friends',
message: 'I thought you would dig this app!',
data: 'gameID=96'
}, onInviteFriend);
//jquery required for ajax function
onInviteFriend = function(response) {
if (response && response.request_ids) {
var idsLength = response.request_ids.length;
var idList = "";
var data = {};
var ajaxSettings = {};
for (var i = 0; i < idsLength; i++){
idList += response.request_ids[i];
if (i < idsLength-1){
idList += ",";
}
}
if (idsLength > 0){
data.idList = idList;
ajaxSettings = {
type: "GET",
url: sketchnpass.root+"/ajax/log-invite-sent/",
data: data,
success: sketchnpass.onSaveInvites
};
$.ajax(ajaxSettings);
}
//was published
} else {
//was not published
}
}
i think using the code above i can get the number of sent requests.
But when some1 accepts the request how will i know that happened , does the accepted request send the user to my app along with some data?
The Facebook requests dialog documentation basically walks you through how to do this.
When requests are sent, request_ids is returned as return data so you would want to log this information in your system to track who sent how many requests.
To track accepted invitations, the documentation says that this url is called: http://apps.facebook.com/[app_name]/?request_ids=012345678910 so you would just need to parse the request id and look that request id up in your system and mark it as accepted.