Invitee is in inviter tenant: Azure AD Invitations Endpoint Error - php

I want to call the Invitations API to invite users to sign in via Microsoft Graph API.
My code works for most of the emails that I call the API on, however for some emails, I get this error:
{
"error": {
"code": "BadRequest",
"message": "Invitee is in inviter tenant",
"innerError": {
"request-id": <request id>,
"date": 2019-06-03T05:51:21
}
}
}
Any idea why this issue occurs?
To be clear, when I first called the API on this email, the invitation email was sent successfully. However, after a few times of testing, I get this error.
I initially suspected that clicking on the 'Get Started' button in the email caused on this error and tested this hypothesis on an Outlook email. However, after clicking on the 'Get Started' button for the test email and calling the API again, the invitation email is still sent as per normal.
My code snippet is as follows:
$curlStat = curl_init();
$feedURL = 'https://graph.microsoft.com/v1.0/invitations';
$data_body = Array(
'invitedUserEmailAddress' => <test-email>,
'inviteRedirectUrl' => <my-redirect-url>,
'sendInvitationMessage' => true
);
$headers = array(
"Authorization: Bearer " . <my-access-token>,
"Content-Type: application/json"
);
$data_body = json_encode($data_body);
curl_setopt($curlStat, CURLOPT_URL, $feedURL);
curl_setopt($curlStat, CURLOPT_POST, true);
curl_setopt($curlStat, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curlStat, CURLOPT_POSTFIELDS, $data_body);
curl_setopt($curlStat, CURLOPT_RETURNTRANSFER, true);
$emailOutput = curl_exec($curlStat);
curl_close($curlStat);

I'm aware of two conditions that cause this (or similar) errors to fire:
You're attempting to invite someone with an address from one of the verified domains. In other words, if your tenant lists company.onmicrosoft.com and company.com as verified domains, attempting to invite an address ending in #company.onmicrosoft.com or #company.com will fail.
The external email address you supplied already exists in the tenant (typically because they've already accepted a previous invitation).
Both of these boil down to the same root cause: you cannot send an invitation to an email address that has already been assigned to an existing user.
As for why you could send an invitation immediately after accepting a prior invitation, this is likely just a race condition. It takes a few moments for the invitation to get processed, the user record created, and the changes to propagate across your AAD tenant. Try waiting for 1 minute after accepting the invite and I suspect you'll consistently see this error.

Related

Whatsapp API - send a notification message to another phone number

I was looking for a way to send notifications directly to the customer phone number using the Whatsapp API
I found an article on a site that explains in detail how to activate and use the Whatsapp API.
Add the phone number +34 644 76 66 43 into your Phone Contacts. (Name it it as you wish)
Send this message "I allow callmebot to send me messages" to the new Contact created (using WhatsApp of course)
Wait until you receive the message "API Activated for your phone number. Your APIKEY is 123123" from the bot.
Note: If you don't receive the ApiKey in 2 minutes, please try again after 24hs.
The WhatsApp message from the bot will contain the apikey needed to send messages using the API.
You can send text messages using the API after receiving the confirmation.
Perfect receipt apikey
How to send WhatsApp Messages from PHP using CURL Library
It is very simple to send WhatsApp messages from PHP using the cURL Library. I would recommend to create a function and then call to the function every time that you want to send a message.
First, create the function "send_whatsapp" in your php code as follow:
function send_whatsapp($message="Test"){
$phone="NUMBER"; // Enter your phone number here
$apikey="YOUR_API_KEY"; // Enter your personal apikey received in step 3 above
$url='https://api.callmebot.com/whatsapp.php?source=php&phone='.$phone.'&text='.urlencode($message).'&apikey='.$apikey;
if($ch = curl_init($url))
{
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$html = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// echo "Output:".$html; // you can print the output for troubleshooting
curl_close($ch);
return (int) $status;
}
else
{
return false;
}
}
Just update the $phone and $apikey variable with the ones that you obtained during the step 3 above.
And then call to the function from any place in your code.
send_whatsapp("this is a test from PHP"); //Text message that your would like to send
You can call to the send_whatsapp function from different places in your code.
QUESTION
Perfect this will send me a message every time to the number I specified to activate the notification system.
But what if I want to send it not to my number but to the customer number?
I believe you're missing two concepts here. If you want to send messages from your personal phone number, you need to host & run your own solution (I don't think you'd like to allow anybody else out there to get all your stuff).
If you are asking for a service provider to set up a number for you and offer you a gateway service for that purpose, there are several alternatives out there. Google them. You'll find two options; Facebook/Whatsapp API connected providers and 'free riders' that will set that up for you at a cost.
The solution you mention is called call me bot and it is just to send self notifications and not for sending out messages to third parties. I am hosting a similar solution (https://github.com/inUtil-info/whin-use-cases) but is the same situation. To prevent span, you are not allowed to send messages to anyone but you.

Can't refund order using Paypal API

I'm integrating PayPal using PHP and cURL and managed to create orders and capture the payments via the https://api.sandbox.paypal.com/v2/checkout/orders and
https://api.sandbox.paypal.com/v2/checkout/orders/<order_id>/capture endpoints
The orders I'm trying to refund have been successfully captured and looking at the details it shows their status is "COMPLETED" and the final_capture field is true, so the order has been placed and I can see the transaction ended successfully in the merchant account
Now I'm trying to test refunds using the capture ID I get from the capture call but it always fails with an error with the following response body
{
"error":"invalid_subject",
"error_description":"Subject Authentication failed"
}
I tracked down the problem behind the Subject Authentication failed problem being a wrong Paypal-Auth-Assertion header, that I printed and double checked multiple times already and it seems to be right. Here's the code I use to make the call
// Codeigniter function to read from $_POST
$capture_id = $this->input->post('paypal_capture_id');
$auth_1 = base64_encode("{\"alg\":\"none\"}");
$auth_2 = base64_encode("{\"payer_id\":<payer_id>,\"iss\":<client_id>}");
$auth_assertion_header = $auth_1 . "." . $auth_2 . ".";
$curlSES=curl_init();
curl_setopt($curlSES,CURLOPT_URL,"https://api.sandbox.paypal.com/v2/payments/captures/$capture_id/refund");
curl_setopt($curlSES, CURLOPT_POST, true);
curl_setopt($curlSES, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: Bearer '. $access_token,
'PayPal-Auth-Assertion:' . $auth_assertion_header
));
curl_setopt($curlSES, CURLOPT_POSTFIELDS, '{}'); // empty payload means full refund
curl_setopt($curlSES, CURLOPT_RETURNTRANSFER, true);
$result=curl_exec($curlSES);
Where payer_id and client_id are filled using a merchant id account used for the sandbox environment and the client_id is the secret id for the application provided by Paypal, the $access_token has been previously generated from a function I use in other parts of the application and it works fine.
Furthermore, if I try to make the same call using Postman (and the PayPal API explorer as well) it produces a different error, that is
{
"error": "invalid_request",
"error_description": "No permissions to set target_client_id"
}
No search result for this error is really helpful so I'm lost on what I'm doing wrong there, although it doesn't seem related to the Paypal-Auth-Assertion as it falls back to the Subject Authentication failed error if I provide a wrong value on purpose.
I was facing the same issue, when trying to refund a captured order for a partner account. It seems to me u are using the string escaped json from the example.
Try using the json_encode function like below:
$header = base64_encode(json_encode(['alg' => 'none']));
$body = base64_encode(json_encode(['payer_id' => $merchantId, 'iss' => $clientId]));
$authHeader = $header . "." . $body . ".";
I was able to refund a captured order with this $authHeader.
Greetings

Slack Slash commands - Not working in private channels or direct messages

I have programmed several slash commands that show a response in public channels without any problems, but they don't show any response in private channels or direct messages.
As shown below, I am using the in_channel response type. Is there any other response type I can use or a workaround so that it works everywhere?
$data = array(
"username" => "My_user",
"channel" => $channel_id,
"response_type" => "in_channel",
"text" => $text,
"mrkdwn" => true,
"icon_url" => $icon_url
);
$json_string = json_encode($data);
$slack_call = curl_init($slack_webhook_url);
curl_setopt($slack_call, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($slack_call, CURLOPT_POSTFIELDS, $json_string);
curl_setopt($slack_call, CURLOPT_CRLF, true);
curl_setopt($slack_call, CURLOPT_RETURNTRANSFER, true);
curl_setopt($slack_call, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Content-Length: " . strlen($json_string))
);
$result = curl_exec($slack_call);
curl_close($slack_call);
Thanks in advance!
I talked to the Slack team, which was extremely helpful, and we figured out what the problem was. I am sharing it here in case anybody else runs into the same problem.
The problem was not about the commands being used in public or private channels. The person who created the webhook set it so that it would work on a private channel (our testing channel), so it would only work in that channel or in any channels that she was a part of (so, all the public channels). As soon as I added her to a private channel, it would work.
The solution was for the creator of the webhook to edit it (not the code, just the webhook) and set it by default to a public channel (any) instead of a private channel. This made it work in every channel, even direct messages.
This way, I was able to use my original code, which also allows me to change the user icon dynamically, instead of sending a message back.
I hope that helps other people as well!
That does not look like the right approach.
Responding to slash commands
For responding to a slash command you must not send a new message back (e.g. via webhook as in your code example). Instead just respond to the request from Slack with the content of your message.
Example
$message = array (
'response_type' => 'in_channel',
'text' => $text
);
header ('content-type: application/json');
echo json_encode ($message);
that is all you need.
response_type defines if the response can be seen by all members of a channel "in_channel" or only by the issuer of the slash command "ephemeral"
Please see the official documentation for more details and options.
Sending additional messages
You can of course also send a message from your script in response to the slash command. However, if you want to send a message to a private channel please note that the slash command request from Slack will not include the correct channel ID if it is used in a non-public channel. I don't think there is currently any solution or workaround for this.
You can however always send a direct message to the user by using the ID of the user as channel ID.

How to set clientUserId for a Recipient in DocuSign using the REST API?

I'm trying to create a RecipientView to send through an app to the recipients of envelopes that are created. With DocuSign's newer API, this requires a userName which is entered by the person who creates the document needed to be signed, an email which is just the email of the recipient, and a clientUserId which is a sender generated string value that authenticates the recipient as an embedded signer so that a RecipientView can be generated to host the signing ceremony.
DocuSign documentation references that I need to set clientUserId, but it doesn't mention how to to do this other than when the envelope is created through the API. However, in this scenario, envelopes will be created by DocuSign Admin clients through the templates on the actual web interface, and not through the API.
My code to generate the RecipientView is all set up here:
$url = "https://demo.docusign.net/restapi/v2/accounts/$account_id/envelopes/$envelope_id/views/recipient";
$body = array("returnUrl" => "http://www.docusign.com/devcenter",
"authenticationMethod" => "None",
"email" => "$email",
"userName" => "$name",
"recipientId" => "$recipientId",
"clientUserId" => "1000"
);
$body_string = json_encode($body);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Accept: application/json',
'Content-Type: application/json',
'Content-Length: '.strlen($body_string),
"Authorization: Bearer $access_token"
));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body_string);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status != 201){
die('Could not connect to end point: '.mysqli_error($conn));
}
$response = json_decode($json_response, true);
$url = $response["url"];
This code does work when the embedded signer is the Admin account, but not when the envelope is sent to an actual recipient. The return JSON from DocuSign after this request should be:
{
"url": "example.example.com"
}
However, the return I get for recipients that are not the Admin of the DocuSign account is:
{
"errorCode": "UNKNOWN_ENVELOPE_RECIPIENT",
"message": "The recipient you have identified is not a valid recipient of the
specified envelope."
}
I believe not setting clientUserId is the reason behind this, since the documentation says I need to set clientUserId and not just create a value when making the call. How do I set a recipient's clientUserId via the REST API?
UPDATE: Within this scenario, I will not be the one creating and sending envelopes. That will be done by the clients I have through my app, and the large majority of them will most likely use the web interface to do this, not the API. I do have access to all information regarding the Admin account for each client, including the Integrator Key, Access Tokens, Envelope IDs, Account IDs, etc.
For Embedded Signing (aka Recipient View) there are two calls you need to make. Well actually 3 calls including the initial Login API but it sounds like you've got that working so I'll focus on the other two.
Step #1: Create an envelope with an embedded recipient. When adding the recipient make sure you set their name, email, recipientId, and clientUserId.
Step #2: Request the Recipient View of the envelope for your signer. To do so you need to call the EnvelopeViews: createRecipient API and you must reference the same exact set of values for the recipient that you set in step 1 (i.e. name, email, recipientId, and clientUserId)
Check out the Signing from Within your App API Recipe for a full code sample.

How to send in Deals using a web form?

I'm trying to add a new Deal with the Pipedrive API.
To do so I've followed this tutorial: http://support.pipedrive.com/customer/portal/articles/1271064-how-to-send-in-deals-using-a-web-form
But there's something I didn't understand:
"Email API gives your company a special email address you can use to
automate lead generation and adding of new contacts and
organizations."
Where can I get this email address, there's no other mention of it at the tutorial?
Since I'm unable to follow the tutorial I'm trying to add a new deal with cURL, this is the code:
<?php
$deal = array("item_type" => "deal","stage_id" => 1,"title" => "Atendimento Web Site","organization" => "Company","owner" => "johndoe#company.com.br","visible_to" => 2,"person" => array("name" => $nome,"email" => $email,"organization" => $empresa,"phone" => $tel));
$deal_string = json_encode($deal);
$ch = curl_init('https://api.pipedrive.com/v1/deals?api_token=TOKEN');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $deal_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json, charset=UTF-8',
'Content-Length: ' .strlen($deal_string))
);
echo $deal_string;
echo curl_exec($ch);
?>
And this is what I get:
iten sent -> {"item_type":"deal","stage_id":1,"title":"Atendimento","organization":"Company","owner":"owner#mail.com.br","visible_to":2,"person":{"name":"Jo\u00e3o Neto","email":"mail#mail.com.br","organization":"Company 2","phone":"7112345678"}}
return from api -> {"success":false,"error":"Deal title must be given.","data":null,"additional_data":null}
Where's the error?
About the email support it's true that you are mixing two thing, although it was also happened to me the first time. I admit it would seem strange, an API in which you can use emails.
Anyway, I was working on a simple integration between Pipedrive and another platform and I used the full REST API.
I noticed every time you have an error creating a Deal or you make a mistake in the Json (even if title is ok), you always get the same answer "error":"Deal title must be given.". Of courses it won't help you too much.
So, I recommend you to use some tools like RESTClient for Firefox to simplify the problem at the beginning or even Firebug to sniff it from https://developers.pipedrive.com/v1 making use of their tools to understand the request a little bit better. After that, you can do it more complex.
I am putting you a screenshot in which you can see the simplest example. I hope it will be useful for anyone
I'd receive an email from Pipedrive Support with a full anwser.
*Hi,
Thanks for reaching out!
I'm sorry to hear about the trouble!
So you're mixing up two completely separate things. You're sending in the JSON object needed for the Email API into the REST API.
You have 2 options.
You could go full on with the email API. To do this you need to log into your Pipedrive account, navigate to the Settings, Features page and enable the Email API feature. Then click through to the email API page and get the email address you need to send the object to. And then alter your PHP code to send in that object to that email address as a plain text email. No curl or API token needed for that.
You could clean up the data object you're sending in with the REST API. But you need to understand that the REST API works a little different from the Email API. So you can't just send in the person object along with the deal. You would first need to POST in the person with all the details to the persons endpoint and get back the ID. You can then use the person ID in the deals POST.
I hope this helps
Martin Henk | Co-Founder, Head of Customer Support
Pipedrive*

Categories