Batch Contact creation/update with contact photo - c#

I am using EWS managed API to create and update contacts on the Exchange Server.
I am creating a contact like this (where user is an Active Directory Principal object with some custom properties):
Contact addContact = new Contact(service);
exchangeContact.NickName = GenerateNickName(user);
exchangeContact.DisplayName = exchangeContact.NickName;
exchangeContact.FileAs = user.DisplayName;
...
exchangeContact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = user.Phone;
exchangeContact.PhoneNumbers[PhoneNumberKey.MobilePhone] = user.MobilePhone;
ExtendedPropertyDefinition adGuidPropDef = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "ADGUID", MapiPropertyType.String);
exchangeContact.SetExtendedProperty(adGuidPropDef, user.Guid.ToString());
if (user.ThumbnailPhoto != null)
{
exchangeContact.SetContactPicture(user.ThumbnailPhoto);
}
exchangeContact.Save(parentFolderId);
This code part is called for around 500 * 500 contacts, and it is taking too long. I am looking to improve its performance. I tried to use the batch create/update methods but I found out they do not support "attachments", and that a contact photo is an attachment.
Is there another way to lower EWS calls or improve performance otherwise in this case?

There is nothing you can use to batch the Attachment creation but when you say 500 * 500 contacts are you creating 500 contact in 500 different mailboxes. That is to say you creating the same 500 contacts in each of those different mailboxes ?. If that's case the fastest way would be to create the contact once in a Master Mailbox and then copy the contact in to each of the Target Mailboxes. If you batch everything bar the Add Attachments that should give the best result.

Related

Problem fetching contact container Xamarin.iOS

I got a problem with a little application I'm developing using Xamarin.iOS
My goal is simply to get every contacts present on an iPhone.
I have this code, it worked until now on my phone and at least 3 others.
Yesterday I added someone in my provisioning profile, since, I can't get any other value than 'null' on my phone when I try to fetch a container.
My phone is an iPhone 7 iOS 13.1.2 - I can't test it on any other phone until a little moment.
It still works on a simulator (iPhone 8 iOS 13.1).
I have the contact authorization request in my info.plist.
I just don't understand what getting 'null' means when fetching a default container ...
try
{
var keysTOFetch = new[] { CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.Nickname, CNContactKey.JobTitle, CNContactKey.DepartmentName, CNContactKey.OrganizationName, CNContactKey.PostalAddresses, CNContactKey.UrlAddresses, CNContactKey.EmailAddresses, CNContactKey.PhoneNumbers };
NSError error;
CNContact[] contactList;
var ContainerId = new CNContactStore().DefaultContainerIdentifier; <---- //This where I get a null I never got before ...
if (ContainerId != null)
{
using (var predicate = CNContact.GetPredicateForContactsInContainer(ContainerId))
using (var store = new CNContactStore())
contactList = store.GetUnifiedContacts(predicate, keysTOFetch, out error);
var contacts = new List<UserContact>();
status = writeCSV(contactList, user);
}
else
Console.WriteLine("Didn't get any container identifier ..");
}
Apple documentation says it can return 'null' but without further explanation ..
Thanks a lot for your help
You are facing this issue on some phones and not other because the phone that work have only one container that it is trying load contacts from, while the phones that don't work have more than one container (i.e. Gmail, Exchange, iCloud accounts used to store contacts). So you are only loading the contacts from the account that is configured as the default, which has 0 contacts. Therefore, it would not load all contacts as requested.
Solution: Get all the containers and iterate over them to extract all contacts from each of them. You might be able to find some samples of it on Github.

How to add contact from two different Telegram servers?

Adding a contact from a country like Iran to a telegram account from Canada, causes an error says:
Unfortunately -name- has not joined telegram yet. But you can send
them an invitation.
I think that's because there are two different accounts from two different servers that aren't synced well.
Sometimes Iranian account can add Canadian account, and then Canadian can add Iranian as well, even if Iranian deletes Canadian from contacts. Or if a third person share their contacts or forward a message from one to another, they can add each other. I think these signs shows that telegram servers are not synced well.
As I'm using TLsharp to accomplish that, I can add two telegram accounts, one plays as that third person role, and shares Iranian contact to Canadian, and then he can save that contact.
My step by step plan is:
What I have is an Iranian Telegram account and Canadian one.
Iranian Customer opens my web site.
she/he fills telegram phone number field and submits.
we are going to start sending message in telegram by Canadian account.
try to add contact by Canadian account.
If failed, try to add contact by Iranian account. Else, we are done!
Share contact to Canadian Account.
Add contact by Canadian account.
My problem is:
how to have multiple telegram accounts in my code, because session file name is always "session.dat"
how to share contact in TLSharp
I can't forward message because there isn't any message yet. We should start messaging.
I also tried retrieving UserId and AccessHash by Iranian account, and using by Canadian account in this method:
await client.SendMessageAsync(new TLInputPeerUser() { UserId = xxx, AccessHash= yyyy}, "Hello");
but it has PEER_ID_INVALID error. (That is not true, I just took UserId from telegram!)
The problem is in number of contacts!
Telegram only supports about 1000 contacts (I found it experimental, there isn't any official source to prove this), and it will show you error when you want to add more contacts.
Trying to delete some contacts and reduce the count to 900, allowed me to add new contacts. So, the problem is not in telegram servers, it is in number of contacts limitation. Maybe they have a line of code like this:
Contact[] contacts = new Contact[1000]; //LOL
And for other two questions:
how to have multiple telegram accounts in my code, because session
file name is always "session.dat"
TLSharp.Core.TelegramClient clientAlt = new TLSharp.Core.TelegramClient(api_id, api_hash, sessionUserId: "sessionAlt");
There isn't any good documentation for TLSharp, but the problem solved by using sessionUserId as an optional parameter.
how to share contact in TLSharp?
TLInputMediaContact contact = new TLInputMediaContact()
{
FirstName = FirstName,
LastName = LastName,
PhoneNumber = PhoneNumber
};
TLRequestSendMedia req = new TLRequestSendMedia()
{
Media = contact,
Peer = new TLInputPeerUser() { UserId = AnotherTelegramAccountUserID.Id },
RandomId = UniqueNumber_ToPreventDuplicateMessages,
};
await clientAlt.SendRequestAsync<TLUpdates>(req);

Searching for certain mail addresses: The Method "Contains" is not supported

using Microsoft.Azure.ActiveDirectory.GraphClient, I want to get twenty accounts from Azure Active Directory; given their email addresses. I could now send twenty requests to the Azure AD server, but in the meantime, my script times out. So I tried a single request:
public override IEnumerable<IDirectoryEntry> GetEntriesForMails(IEnumerable<MailAddress> emails)
{
foreach(IUser user in _connection.Client.Users.Where(x => emails.Contains(x.Mail)).FlattenPages())
{
yield return new AzureDirectoryEntry(user, this);
}
This throws the error that
"Contains" is not supported.
Is there another, supported, way to get all user accounts for twenty email addresses in a single round trip to the server?
Try the code :
List<IUser> users = activeDirectoryClient.Users.ExecuteAsync().Result.CurrentPage.ToList();
List<IUser> user1 = users.Where(u => emails.Any(e => e.Contains(u.Mail))).ToList();
As per a Microsoft employee, there is no direct solution in the library.
The best solution we could come up with is to keep a client-side lookup table that maps email adresses to ObjectIds; and update that table regularly (daily/weekly, and whenever a lookup failed).
One can then get the Objects for 20 ObjectIds from Azure AD in a single call (GetObjectsByObjectIdsAsync method).

Retrieve all mobile devices Google Directory API in .NET Application

I want to Manage Device using Google API in my appilcation.How to retrieve all mobile/chrome OS device ?
CODE :
var listReq1 = service.Mobiledevices.List(serviceAccountEmail);
MobileDevices allUsers = listReq1.Execute();
Here,
serviceAccountEmail = "Service accounts Key" (Console.developer.google.com)
I am getting error like
Google.Apis.Requests.RequestError
Bad Request [400]
I tried using
var listReq= new Google.Apis.Admin.Directory.directory_v1.MobiledevicesResource.ListRequest(service,serviceAccountEmail);
Still not working ? I want all details of User just like Below Image
If you check the documentation for Mobiledevices: list
Retrieves a paginated list of all mobile devices for an account.
I will see that it takes a customer id as a parmater.
customerId The unique ID for the customer's Google account. As
an account administrator, you can also use the my_customer alias to
represent your account's customerId. The customerId is also returned
as part of the Users resource.
var listReq1 = service.Mobiledevices.List(customerId);
MobileDevices allUsers = listReq1.Execute();
You are sending service account email address which I really don't think is your customer id.

Facebook Graph API {id}/feed?limit=x - restrict to messages since a certain message id

I have a small problem, I am working on an aggregation application that is collecting messages from pages in realtime.
This is working fine, but I get the same message on every call and then filter out the messages that I have already seen manually.
This means that a large amount of data is being transferred every time I make a call to the graph api.
Is there a way to limit the message as messages since this message id?
currently using the c# Facebook SDK
var fb = new FacebookClient("access_token");
dynamic parameters = new ExpandoObject();
parameters.limit = _facebookMessagesToRetrieveAtATime.ToString(CultureInfo.InvariantCulture);
//Want to add a new param here to say messages since this id.
var facebookUrl = String.Format("{0}/feed", "Page ID");
dynamic resp = fb.Get(facebookUrl, parameters);
Thanks in advance.
You can use the since url parameter in your calls, as described at https://developers.facebook.com/docs/graph-api/using-graph-api/v2.1#paging
This would make it necessary that you store somewhere in your application the timestamp when you last requested the respective feed
This would yield in
var facebookUrl = String.Format("{0}/feed?since={last_update_timestamp}", "Page ID");
where {last_update_timestamp} is the timestamp (unixtime in seconds) of the last update.

Categories