Retrieving Single Contact in Google Contacts API version 3.0 - c#

Trying to retrieve a single contact. In the link, it says:
public static Contact retrieveContact(ContactsRequest cr)
{
Contact contact = cr.Retrieve<Contact>("https://www.google.com/m8/feeds/contacts/default/full/contactId");
return contact;
}
How would one know what's the contact's selflink URL, or even the contactId? I tried different variations:
https://www.google.com/m8/feeds/contacts/default/full/firstname.lastname
https://www.google.com/m8/feeds/contacts/ourdomain.com/full/firstname.lastname
https://www.google.com/m8/feeds/contacts/firstname.lastname%40ourdomain.com/full/firstname.lastname
But I can't seem to get a proper return value. All I am getting is Not Found exception.
Full error message is:
{"The remote server returned an error: (404) Not Found."}
I am able to connect to the service, as I am able to do a proper query if I retrieve all contacts. But getting a bit stumped on retrieving a single contact.
Anyone already worked on this?
Appreciate any advice.
Update:
If for example you use the ContactsQuery such as:
ContactsQuery query =
new ContactsQuery("https://www.google.com/m8/feeds/profiles/domain/" + this.domain + "/full");
query.Query = ?????
What can we specify in the query object so that we can actually just go retrieve one user (based on user name or email address)?
Update:
I used GAM (https://code.google.com/p/google-apps-manager/) to retrieve a particular user and there was an ID field there composed of a bunch of numbers. I tried to use that in lieu of the ContactID field in the URI as above, but all variations just returns a 403 Not Found error.

public Contact GetContact(ContactsRequest cr, string email)
{
string qstring = "https://www.google.com/m8/feeds/contacts/default/full?q=" + email + "&v=3.0";
Uri thisuri = new Uri(qstring);
Contact contact = cr.Retrieve<Contact>(thisuri);
return contact;
}

You need to know the contactId ahead of time. It is not possible to look up a Contact record from their email address with the Contacts API.
If you are just looking for users in your domain, then check out the Directory API - https://developers.google.com/admin-sdk/directory/v1/guides/manage-users#get_user

When you use the search: www.google.com/m8/feeds/contacts/default/full?q=lastname+firstname+... you can limit the results to those you want to update. When fetching the "id" from the "entry" results you will notice it is formed like
"http://www.google.com/m8/feeds/contacts/yourself%40gmail.com/base/7e"
The id, 7e in this case, is after "/base/".
When using www.google.com/m8/feeds/contacts/default/full/7e , you will get the entry of the requested user.
You can deduce this from the info at https://developers.google.com/google-apps/contacts/v3/#retrieving_a_single_contact

Related

Selecting a user by ID doesn't work, but works by email

I am using the Microsoft Graph API to access some events in my company's Azure AD Outlook.
The problem I am now having is that I can not access the CalendarView (or really I can't access the user at all) when I try to specify the user with an UUID instead of an email. The strange thing is that email works just fine, but I am not allowed to store emails outside of the Azure AD, so ID would be the preferred method.
Here is the exact API call I try to make: https://learn.microsoft.com/en-us/graph/api/user-list-calendarview?view=graph-rest-1.0&tabs=csharp
But all examples only use the .Me accessor and not the .Users[{ID | userPrincipalName}]
I am quite sure that the UUID I use is correct since it comes from an API call earlier. Or does the documentation article mean something else than the user UUID by {ID | userPrincipalName}?
A room looks like this (when read as a JSON object):
{
"id": "00000000-0000-0000-0000-000000000000"
"emailAdress": "room#company"
...
}
This works:
await graphClient.Users["room#company"].CalendarView.Request(queryOptions).GetAsync();
While this does not work:
await graphClient.Users["00000000-0000-0000-0000-000000000000"].CalendarView.Request(queryOptions).GetAsync();
When using the UUID I get (IDs not shown here):
Code: ErrorInvalidUser
Message: The requested user '<UUID>' is invalid
ClientRequestId: <some ID>
I did test this with a hardcoded room id and email but also with the ID object I get from calling the roomlist in C#.
Another inconsistency I encountered is that I can read the whole list of microsoft.graph.room via a http request but not using the C# Microsoft.Graph.Auth package. Reading the data of a room I know the email from does however work.
So does this just not work and the doc doesn't say so?
Does the Microsoft.Graph.Auth package not support those kind of requests?
Or do I use a wrong ID?
Saladino
According to some test, only when I use incorrect object id of user it shows same error message as yours.
If I use another user's object id(not object id of the user do authentication), it will show ErrorAccessDenied because do not have permission.
If I use the object id which the user not exist in Azure AD(incorrect object id), it will show same error message with yours. So please check if the uuid which you mentioned is the user's object id(shown in below screenshot) in your Azure AD and please check if you input the correct format of object id in your code by Console.WriteLine(object id)

How to reply to an email using the EWS Managed API?

I have created an application that uses the EWS Managed API 2.2.
This application uses pull notifications to get new emails and saves a copy of the email in a database.
Then in the application I want to get the email from database and reply to it.
In order to reply to the message, I need to retrieve it from EWS using the ItemId I have stored in my database.
Of course I can create a new EmailMessage and send it but then the new email will have a different ConversationId which is not acceptable for the application scenario.
So, in order to achieve this I use the the following line of code
EmailMessage.Bind(service, itemId);
For this method to work I have to instantiate the ItemId from my database but the ItemId constructor takes as parameter only the UniqueId, and creates it with null ChangeKey.
If I use this ItemId (with null ChangeKey) I get the following error:
Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the store.
I think that this is because of the null ChangeKey. Am I correct?
Is there a workaround about this?
Instead of identifying a message by ItemId, use EntryID. Using EntryID, you can bind to the same email without needing ChangeKey.
Here is the definition of such property:
ExtendedPropertyDefinition EntryIDProperty = new ExtendedPropertyDefinition(0x0FFF, MapiPropertyType.Binary);
When you do your search for messages, make sure you instruct EWS to include such property in the list of retrieved items.
Here is an example to obtain EntryIDs when you invoke FindItems:
ExtendedPropertyDefinition EntryIDProperty = new ExtendedPropertyDefinition(0x0FFF, MapiPropertyType.Binary);
ItemView item_view = new ItemView(10) { PropertySet = new PropertySet(ItemSchema.Id, EntryIDProperty) };
var result = service.FindItems(WellKnownFolderName.Inbox, item_view);
foreach (var item in result.Items)
{
byte[] entry_id = (byte[])item.ExtendedProperties.Single(x => x.PropertyDefinition == EntryIDProperty).Value;
string entry_id_hex = ByteArrayToHexString(entry_id); //This is the entry ID that you should store
}
Use the following method to convert a EntryID to ItemID if you want to use EmailMessage.Bind:
This method accepts string EntryID.
mailbox_address is the SMTP address of the mailbox (e.g. test#domain.com)
'service' is the ExchangeService object.
private ItemId ConvertEntryIdToItemId(string entryid, string mailbox_address, ExchangeService service)
{
AlternateId id = new AlternateId(IdFormat.HexEntryId, entryid, mailbox_address);
AlternateId new_id = (AlternateId)service.ConvertId(id, IdFormat.EwsId);
ItemId item_id = new_id.UniqueId;
return item_id;
}
Now you can use the returned ItemId to bind your EmailMessages.
The specified object was not found in the store.
That error generally means that you don't have rights to the Mailbox your trying to access or the Item your trying to access no longer exists in the store. Eg in a pull notification application that can mean the Item that you being notified about has already been deleted or moved to another folder (in each of these case the Item will be assigned a new Id). If you also listing to Move event you should be able to see the corresponding move event which will have the OldItemId that correlates the newMailEvent notification.
The Change Key only matters when your updating an Item so in the case the error you getting on Bind means that Item your trying doesn't exist (or has been moved) or you don't have rights to access it binding with just the UniqueId is perfectly okay see also https://msdn.microsoft.com/en-us/library/office/dn605828(v=exchg.150).aspx
Cheers
Glen

Magento: Getting the transaction ID via soap

i recently tried to connect to a magento webshop via magentos SOAPv2 adapter.
Sharpdevelop did generate some c# wrappers getting the WSDL.
I could login and query orders, but when it comes to payment methods I was wondering why there's no way to get the transaction ID.
Here's what I tried:
salesOrderEntity ent = ms.salesOrderInfo(mlogin,"<my_order_id>");
The salesOrderEntity class contains a salesOrderPaymentEntity which should contain an attribute last_trans_id, but it doesn't.
Does anyone have an idea where to get the transaction ID from payment information? I didn't even find a reference to last_trans_id in the proxy code generated by sharpdevelop.
Thanks in advance for any suggestions.
-chris-
After some time i took up this question again and found a solution in my case.
A salesOrderEntity contains a list of salesOrderStatusHistoryEntity objects.
And those contain a field named 'comment' where in my case the Transaction IDs can by found in a textual way like
Transaction ID:"800736757864..."
This helped me.
Chris the OP has answered the question, but just to add some extra value to this Q&A here's the code I've got working.
As some background, the reason I am using Transaction IDs at all is because they are used by Paypal. I'm writing a cron job that pulls the Paypal orders from the Paypal API for the previous 24 hours, then we pull all orders from Magento via SOAP for the previous 24 hours, get the transaction IDs and match them to the Paypal list. It's to make sure there are no Paypal orders which are not on Magento, occasionally we get an IPN failure which prevents Magento quotes being converted to orders and the customer gets billed by Paypal but no product is shipped to them as the order is never created. If there's a mismatch an email alert is sent to customer services.
$startDate = gmdate('Y-m-d H:i:s', strtotime('-1 day', time()));
$complex_params =array(
array('key'=>'created_at','value'=>array('key' =>'from','value' => $startDate))
);
$result = $client_v2->salesOrderList($session_id, array('complex_filter' => $complex_params));
// We've got all the orders, now we need to run through them and get the transaction id from the order info
// We create an array just to hold the transaction Ids
$ikoTransactionIds = array();
foreach ($result as $invoice) {
$invoiceInfo = $client_v2->salesOrderInfo($session_id, $invoice->increment_id);
$history = $invoiceInfo->status_history;
$comments = $history[0]->comment;
// Only the Paypal based records have transaction Ids in the comments, orders placed via credit card do not. In these cases $comments are null
if ($comments) {
// Check if the text 'Transaction ID:' exists at all
if ((strpos($comments, "Transaction ID:")) !== FALSE) {
list($before, $transactionId) = explode('Transaction ID: ', $comments);
// Remove the trailing period
$transactionId = rtrim($transactionId ,".");
// Remove the quotes
$transactionId = str_replace('"', '', $transactionId);
// We add the id to our array of ids for this Magento install
$ikoTransactionIds[] = $transactionId;
}
}
}

CrmService.Update method does not work for certain attribute

This is my problem:
all I want to do is update a "contact" entity in Crm 4 using the webservice.
This is my code:
CrmService eatupCrmService = CrmInteraction.InitializeCrmService();
contact updatedDelegate = new contact();
CeatupCrmService.Key contactPrimaryKey = new CeatupCrmService.Key();
contactPrimaryKey.Value = delegateId;
updatedDelegate.contactid = contactPrimaryKey;
updatedDelegate.address2_postalcode = delegateDetails.ContactDetailsPhysicalAddressCode;
eatupCrmService.Update(updatedDelegate);
I use the InitializeCrmService() to also retrieve and it works.
When updating the address2_postalcode attribute, I get the following error:
"Server was unable to process request."
with the exception Detail\InnerText :
"0x80040216 An unexpected error occurred. Platform".
If I change the code to update another attribute, say I try to update the mobilephone attribute
instead of address2_postalcode it works without any exceptions thrown.
As soon as I try to update address2_postalcode then I get that error. The address2_postalcode data type in Crm is nvarchar, and the value it is being assigned (delegateDetails.ContactDetailsPhysicalAddressCode) is of c#'s string type.
Anyone have any idea why this could be happening?
This same error and situation happened to me because I did an SSIS dts to load contacts in CRM from a flat file, in unsopported way, and I forgot to fill the CustomerAddressBase table. After filling this table "correctly" (two rows for each contact) the attributes of the View CustomerAddress(address1_addressid and address2_addressid) became not null. If you don't know how to fill this table (CustomerAddressBase) just create one new contact directly with address fields filled in CRM and then go to SQL Server management studio and by query you can see and know how the fields are filled.
Hope it helps somebody,
Alex
After many attempts at trying to understand why this error was occurring, I finally succeeded.
When I started working on this project, the client instructed me to test using only a specific contact, because we were working directly on the production environment. (the client does not have a development environment yet)
After doing some database queries to compare this contact to others (updates were failing only for the test contact) I noticed that my contact's address2_addressid attribute was NULL.
I then went to CRM under Customization\Customize Entities and opened up the contact entity. Under attributes, I ordered by type and saw that the contact has 3 primarykey attributes: contactid, address1_addressid and address2_addressid.
The test contact's address1_addressid and address2_addressid fields were NULL and this caused the CRM web service to throw the 0x80040216 An unexpected error occurred. Platform error upon me trying to update any of the address fields.
I don't know why this contact had those IDs set to NULL, I asked and the person that created the contact had no explanation of how this could have happened. I guess this will remain a mystery, but at least I now have an answer to the error I was getting and I can cater for this in my code.
I don´t know ho it can work...
I think you have to do CrmService.Create(contact) and then with the returned Guid you can perform updates...
Update is not going to work since the record with the Id you are setting on your contact entity doesn´t exist in the db...
contact updatedDelegate = new contact();
CeatupCrmService.Key contactPrimaryKey = new CeatupCrmService.Key();
You could do something like:
crmService eatupCrmService = CrmInteraction.InitializeCrmService();
contact updatedDelegate = new contact();
updatedDelegate.address2_postalcode = delegateDetails.ContactDetailsPhysicalAddressCode;
Guid cId = eatupCrmService.Create(updatedDelegate);
updatedDelegate.contactid = new Key(cId);
//set more fields if you want
eatupCrmService.Update(updatedDelegate);//update record
Wish I have helped you.

Using "ContactsQuery" for searching particular contact in Google contact using Google API Ver 2

Currently i am searching particular as below:
Feed<Contact> f = contactsRequest.GetContacts();
foreach (Contact e in f.Entries)
{
if (e.Title == "MyContact")
{
MesageBox.Show("Contact already exist");
}
}
This will work fine if no of contacts are less.But above code will become slow for large no of contacts.
I read about "ContactsQuery".How can i use it for above scenario ?
There is no support for full-text queries or locating a contact by email address
If you want to find a particular contact, you have to retrieve all contacts then search for the contact yourself, there's no other way at the moment.
ContactsQuery allow you to filter by:
NumberToRetrieve
StartIndex
StartDate
ShowDeleted
OrderBy
last-modifieddate
SortOrder
Group
and other parameters defined in:
Contact Data API reference
Google Data API refence
Google.GData.Contacts namespace

Categories