0

I have set the MS Azure API permissions of contacts.read.write but when executing the following code I get this message:

Uncaught GuzzleHttp\Exception\ClientException: Client error: POST https://graph.microsoft.com/beta/contacts resulted in a 400 Bad Request response: { "error": { "code": "Request_BadRequest", "message": "A value without a type name was found and no expecte (truncated...) in C:\Program Files\Ampps\www\weedo\weedo2\content\libraries\MicrosoftGraph\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php:113

My post code:

$graph = new Graph();
        $graph
          ->setBaseUrl("https://graph.microsoft.com/")
          ->setApiVersion("beta")
          ->setAccessToken($this->accessToken);
        $data = array(
            "GivenName" => "Test",
            "Surname" => "account",
            "EmailAddresses" => array(
                array(
                    "Address" => "testaccount@mail.com",
                    "Name" => "Mail Name"
                )
            )
        );
        
  
        $user = $graph->createRequest("POST", "/contacts")
                    ->addHeaders(array("Content-Type" => "application/json"))
                    ->setReturnType(Model\User::class)
                    ->attachBody($data)
                    ->setTimeout("1000")
                    ->execute();

I believe I followed these pages correctly, but the examples are not all given for PHP so I'm not sure where to go from here: https://github.com/microsoftgraph/msgraph-sdk-php https://learn.microsoft.com/en-us/graph/api/user-post-contacts?view=graph-rest-1.0&tabs=http

I also wrapped the $data parameter in a json_encode just for testing, but no luck. Where to go? What to do?

EDIT: So as seems i was confused with organizational contacts (which are obtained by /contacts) and personal contacts (which are obtained by /me/contacts). Now it is not (yet) supported to create organizational contacts, which i find rediculous but for some reason i'm not allowed to create contacts on application based either. any thoughts / ideas on this?

Mart
  • 475
  • 4
  • 21
  • The error mesg in your question is 'Client error: POST https://graph.microsoft.com/beta/contacts' and when I searched graph [api docs](https://learn.microsoft.com/en-us/graph/api/user-post-contacts?view=graph-rest-beta&tabs=http#http-request), I found that if you wanna create contacts, you need to use 'POST https://graph.microsoft.com/beta/users/{userid}/contacts'. So have you checked if it is a correct url? – Tiny Wang Feb 14 '21 at 15:25
  • Hmm when i use 'get', i do get the contacts without mentioning /users. – Mart Feb 14 '21 at 15:53
  • When i use /beta/me/contacts (which should work according to the docs) i get a invalid credentials message which is odd because of when i use 'get' it all seems to work – Mart Feb 14 '21 at 16:02
  • @Mart looks like the issue is with the payload. According to the document you should not have arrays inside an array in emailAddress. It should be array of objects. Change it accordingly and give a try. – Shiva Keshav Varma Feb 15 '21 at 02:13
  • @Mart I've seen what you updated in question and I haven't found the way to create a contact by application rather than a user. – Tiny Wang Feb 15 '21 at 02:39

1 Answers1

2

You are right, currently, there is no Microsoft Graph API for creating organizational contacts, only list and get method provided. When I tried to create a new one, I got this error: enter image description here

This issue also has been confirmed by a Microsoft engineer here.

So the only 2 ways I know to add organizational contacts is on Microsoft 365 admin Center =>Users => Contacts blade to add manually:

enter image description here

Add my self as a org contat and I can get the new record from /contacts calling: enter image description here

The second way is using the PowerShell command:New-MailContact to do this: enter image description here enter image description here

All of these 2 ways I have tested on my side and all works for me.

UPDATE:

If you are looking for some sample code about adding a user's personal contacts by an Azure AD application, just try code below:

use Microsoft\Graph\Graph;
use Microsoft\Graph\Http\GraphRequest;

$tenantId= '<your tenant name/ID>';
$clientId = '<azure ad app id>';
$clientSecret ='<azure ad app secret>';
$targetUser = '<target user UPN/ID>';

$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
$token = json_decode($guzzle->post($url, [
    'form_params' => [
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'resource' => 'https://graph.microsoft.com/',
        'grant_type' => 'client_credentials',
    ],
])->getBody()->getContents());

$accessToken = $token->access_token;

$data = array(
    "GivenName" => "Test2",
    "Surname" => "account2",
    "EmailAddresses" => array(
        array(
            "Address" => "testaccount2@mail.com",
            "Name" => "Mail Name2"
        )
    )
);

$graph = new Graph();
$graph->setAccessToken($accessToken);

$graph->createRequest("POST", "/users/$targetUser/contacts")
        ->addHeaders(array("Content-Type" => "application/json"))
        ->attachBody($data)
        ->execute();

Result: enter image description here

Stanley Gong
  • 11,522
  • 1
  • 8
  • 16
  • Hey @stanley, thanks for the response. My goal is to create a mailing list from within my websystem. So i'd like to systematically add and remove email adresses from the contact list such that i can add them into a distribution list. Your first 'work-around' does not offer such a solution if i'm getting it correctly, right? – Mart Feb 15 '21 at 08:23
  • @Mart,No, my answer is all about organizational contacts. If you want to use an Azure AD application to manage user's personal contacts, it is supported by Microsoft Graph API, you can just see this api reference: https://learn.microsoft.com/en-us/graph/api/user-post-contacts?view=graph-rest-1.0&tabs=http – Stanley Gong Feb 15 '21 at 08:40
  • thanks! I'm not following the first solution though on creating an organizational contact using Azure AD application with the graph api. Could you elaborate on that a bit more? – Mart Feb 15 '21 at 11:12
  • @Mart If you are looking for some sample code about adding a user's personal contacts by an Azure AD application, I have appended a simple demo in my answer, please accept the answer if it helps :) – Stanley Gong Feb 16 '21 at 03:16
  • @Mart,how's going? Has your issue got resolved? – Stanley Gong Feb 17 '21 at 01:32
  • Sorry, had a day off. But well, I understand your explanation and I very much appreciate it but I guess it is not kind of what I'm looking for. The thing is, in order to make a distribution list, I need an organizational contact list as I'm aware of. So making a personal contact list will not help for the use of my application or am I not getting it right?? – Mart Feb 17 '21 at 11:49