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 "[email protected]" }
$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 ...
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 !