简体   繁体   中英

PowerShell/.Net - Google API Contacts Modification : PUT Request 401 Unauthorized

I'm trying to modify Contacts in Gmail account, using the .Net API, and Loading it in powershell. I'm following the steps described here (Updating contacts, Doh !)

To update a contact, first retrieve the contact entry, modify the data and send an authorized PUT request to the contact's edit URL with the modified contact entry in the body.

OK, got it so I'm succesfull to retrieve contact informations using this code :

$Settings = New-Object Google.GData.Client.RequestSettings( "MyApp", $username , $password )
$Credentials = New-Object System.Net.NetworkCredential( $username, $password )

$Request = New-Object Google.Contacts.ContactsRequest( $Settings )
$Contacts = $Request.GetContacts()
$GoogleContact = $Contacts.Entries |? { $_.PrimaryEmail.Address -eq "john.doe@gmail.com" }
$GoogleContact.Title

Of course, I had a Mail message from google indicating that an external App was bloqued, and I changed a security parameter to allow this code to work ... And it works, the code is prompting my Google Contact Title.

And now, my problem:
I'm changing a property on my Object:

$GoogleContact.Title = "Mac Gyver"

I'm using a function called Execute-HTTPPostCommand , slightly modified to add the Etag value, required by google to make sure I'm not modifying an entry that is actually modified somewhere else :

function Execute-HTTPPostCommand() {
    param(
        [string] $TargetUrl = $null
        ,[string] $PostData = $null
        ,$Credentials
        ,$Etag
    )

    $ErrorActionPreference = "Stop"
    $global:webRequest = [System.Net.WebRequest]::Create($TargetUrl)
    $webRequest.Headers.Add("etag", $Etag )
    $webRequest.ContentType = "text/html"
    $PostStr = [System.Text.Encoding]::UTF8.GetBytes($PostData)
    $webrequest.ContentLength = $PostStr.Length
    $webRequest.ServicePoint.Expect100Continue = $false
    $webRequest.Credentials = $Credentials

    $webRequest.PreAuthenticate = $true
    $webRequest.Method = "PUT"

    $Global:requestStream = $webRequest.GetRequestStream()
    $requestStream.Write($PostStr, 0,$PostStr.length)
    $requestStream.Close()

    [System.Net.WebResponse] $global:resp = $webRequest.GetResponse();
    $rs = $resp.GetResponseStream();
    [System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
    [string] $results = $sr.ReadToEnd();

    return $results;
}

And calling it this way:

Execute-HTTPPostCommand -TargetUrl $GoogleContact.Id -PostData $GoogleContact -Credentials $Credentials -Etag $GoogleContact.ETag

the Contact.ID value is the URL required by google to update the contact, it looks like this : https://www.google.com/m8/feeds/contacts/userEmail/full/ {contactId}

I'm getting an error 401 : unautorized. Being a Windows Sysadmin, I'm not familiar with webservices PUT requests ... I'm using the same credentials to Read Datas and trying to update datas. What am I missing?

Ok, that was pretty easy, I should have RTFM ...

#Loading Google API
$Settings = New-Object Google.GData.Client.RequestSettings( "MyApp", $username , $password )
$Credentials = New-Object System.Net.NetworkCredential( $username, $password )

#Loading Contacts, and getting the one I want
$Request = New-Object Google.Contacts.ContactsRequest( $Settings )
$Contacts = $Request.GetContacts()
$GoogleContact = $Contacts.Entries |? { $_.PrimaryEmail.Address -eq "john.doe@gmail.com" }

#Updating the fields
$GoogleContact.Name.FullName = "Mac Gyver"
$GoogleContact.Name.GivenName = "Mac"
$GoogleContact.Name.FamilyName = "Gyver"
$GoogleContact.Title = "Handyman Masterchief"

#Update
$MAJ = $ContactRequest.Update($GoogleContact)

And it works as is, just like the .Net example.

No need to load a heavy PUT request, the API do his Job.

Sorry for loss of time guys !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM