Search for google contact based on Email - google-api

I'm trying to find a contact by his email using Google People API.
We are using the Create Contact method.
I'm run this method with all the relevant scopes and using oAuth2.0 with refresh token.
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential googleCredential = new GoogleCredential.Builder()
.setJsonFactory(jsonFactory)
.setTransport(transport)
.setClientSecrets(googlePeopleKey.getClientId(), googlePeopleKey.getClientSecret())
.build().setRefreshToken(googlePeopleKey.getRefreshToken());
this.peopleService = new PeopleService.Builder(transport, jsonFactory, googleCredential)
.setApplicationName(APPLICATION_NAME)
.build();
When we use the Create Contact method - Google search for the given email in the system (google plus and more tools) and enrich the contact with an existing data about the user such as photos, gender, profiles and a lot more.
public Person createContact(String email) {
Person requiredPerson = new Person();
EmailAddress emailAddress = new EmailAddress();
emailAddress.set("value", email);
requiredPerson.setEmailAddresses(Arrays.asList(emailAddress));
try {
PeopleService.People.CreateContact createContact = peopleService.people().createContact(requiredPerson);
return createContact.execute();
} catch (IOException e) {
log.error("Could not perform Google people search for email {}", email, e);
}
return null;
}
But, I struggled to get all the information about the users.
We have limitations of 90 calls per second but our system not near this limit.
With two different users, it seems like after 40-50 calls the API start to return empty contact (without photos, gender and more..)
Although the next day it found all the data about a specific person that the day before it returns me fewer data.
I know we have limitations of 25,000 contacts per day but we are not near this limit too.
I can really use your help to find why after 40/50 new contact, google people API start to create the contact without retrieving all the possible data in google systems.
Thank you!

Related

Microsoft Graph update user profile using Xamarin

I have been stuck on this for hours now.
I have the following code:
string[] scopes = new string[] {
"User.ReadWrite"
};
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create(OAuthSettings.ApplicationId)
.Build();
InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClientApplication, scopes);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = new User
{
Country = "ZA"
};
await graphClient.Me
.Request()
.UpdateAsync(user);
Yet every time I execute this I get the following error:
Code: generalException
Message: An error occurred sending the request
What am I doing wrong?
Updating user info is very limited unfortunately. Updating the country with delegated auth isn't possible. It should be doable with app-only auth and the User.ReadWrite.All permission. This is (admittedly) not well explained.
From the information here:
User.ReadWrite and User.Readwrite.All delegated permissions allow the app to update the following profile properties for work or school accounts:
aboutMe
birthday
hireDate
interests
mobilePhone
mySite
pastProjects
photo
preferredName
responsibilities
schools
skills
There are some other gotchas as well (such as if the user is an admin, etc.).

Different result

I'm trying to pull google contacts information (photos, gender and more) and we used Google People API to do that.
I use in createContact service to search contact by an Email.
I created a client id and client secret, and with the simple code of oAuth2.0, I got a refresh token that my server used to generate credentials.
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
String clientId = "";
String clientSecret = "";
String scope = "https://www.googleapis.com/auth/contacts";
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, jsonFactory, clientId, clientSecret,
Arrays.asList(scope))
.setAccessType("offline")
.setApprovalPrompt("force")
.build();
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8089).build();
Credential credential = new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
In that way, I get the refreshToken and save it offline in a secured file.
After that, my application connect to google and get the clientId, ClientToken, and RefreshToken from that file and try to connect -
GoogleCredential googleCredential = new GoogleCredential.Builder()
.setJsonFactory(jsonFactory)
.setTransport(transport)
.setClientSecrets(googlePeopleKey.getClientId(), googlePeopleKey.getClientSecret())
.build().setRefreshToken(googlePeopleKey.getRefreshToken());
It seems that the result is different per user. When I operate with a refresh code that my user authenticate earlier, I can't get all the information that another user in my company (that authorized by the same way) does. Today, it flipped, and in another test, I get results that he didn't. Very strange.
I was looking up about limit rate but, it seems that I even not near the limitations.
Do you have any idea why it returns different result for different users? The different result means that sometimes one of the users can see the profile picture but the other one can't.
Thank you!

How to get contact's photo from exchange server

Based on this tutorial, I'm trying to get contacts photos
private String createPhoto() {
try {
AttachmentCollection attachments = contact.getAttachments();
for (Attachment attachment : attachments.getItems()) {
if (attachment instanceof FileAttachment) {
boolean isPhoto = ((FileAttachment) attachment).isContactPhoto();
if (isPhoto) {
attachment.load();
FileAttachment photo = contact.getContactPictureAttachment();
String filename = photo.getName() + ".jpg";
photo.load(new FileOutputStream(filename, true));
return filename;
}
}
}
} catch (Exception ex) {
LOGGER.info("" + ex);
}
return null;
}
However, attachments.getItems() is always an empty array.
On my mailbox, I have few contacts with photos, and I can receive them by calling URL https://companyname.exchange.com/EWS/Exchange.asmx/s/GetUserPhoto?email=name#company.exchange.com&size=HR360x360
Why I can't get a photo from the code?
On my mailbox, I have few contacts with photos, and I can receive them by calling URL https://companyname.exchange.com/EWS/Exchange.asmx/s/GetUserPhoto?email=name#company.exchange.com&size=HR360x360
That request gets the Userphoto which is stored in the (Source)Users Mailbox (or low res in ActiveDirectory) and made available by that operation.
Your code is trying to retrieve the ContactPhoto which can be stored as an attachment on Contacts in a UserMailbox.
So these are two separate things so which one are you dealing with ?, As you haven't shown it you need to make sure you ExchangeServerRequest Version is set to 2010 or greater as Contact photos aren't returned in 2007. You might also want to test quickly the contacts in Question with the EWS Editor https://ewseditor.codeplex.com/ that will allow you to get the objects and see if there is a ContactPhoto Attachments using EWS.

Using Google API to modify google contacts

I want to start developing with Google API’s with a .NET client. For first step I tried to get all google contacts and now I want to insert contacts.
I have read a lot about Google API’s to CRUD (create, read, update and delete) contacts. There are the Contact API, the People API and other(?). What is the best way to CRUD contacts?
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "xyz.apps.googleusercontent.com",
ClientSecret = " xyz"
},
new[] { "profile", "https://www.google.com/m8/feeds/contacts/xy%40gmail.com/full" },
"me",
CancellationToken.None).Result;
// Create the service.
var peopleService = new PeopleService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "WindowsClient-Google-Sync",
});
ListRequest listRequest = peopleService.People.Connections.List("people/me");
listRequest.SyncToken = null;
ListConnectionsResponse result = listRequest.Execute();
foreach (Person person in result.Connections)
{
foreach (Name name in person.Names)
{
Console.WriteLine("Name: " + name.DisplayName);
}
}
How can I extend this sample to create or update contacts?
Thanks
Andreas
If you will check Google Contacts API:
The Google Contacts API allows client applications to view and update a user's contacts. Contacts are stored in the user's Google Account; most Google services have access to the contact list.
Your client application can use the Google Contacts API to create new contacts, edit or delete existing contacts, and query for contacts that match particular criteria
Creating Contact
To create a new contact, send an authorized POST request to the user's contacts feed URL with contact data in the body.
The URL is of the form:
https://www.google.com/m8/feeds/contacts/{userEmail}/full
Upon success, the server responds with an HTTP 201 Created status code and the created contact entry with some additional elements and properties (shown in bold) that are set by the server, such as id, various link elements and properties.
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactGroupFeed;
import com.google.gdata.data.extensions.City;
import com.google.gdata.data.extensions.Country;
import com.google.gdata.data.extensions.Email;
import com.google.gdata.data.extensions.ExtendedProperty;
import com.google.gdata.data.extensions.FormattedAddress;
import com.google.gdata.data.extensions.FullName;
import com.google.gdata.data.extensions.Im;
import com.google.gdata.data.extensions.Name;
import com.google.gdata.data.extensions.PhoneNumber;
import com.google.gdata.data.extensions.PostCode;
import com.google.gdata.data.extensions.Region;
import com.google.gdata.data.extensions.Street;
import com.google.gdata.data.extensions.StructuredPostalAddress;
// ...
public static ContactEntry createContact(ContactsService myService) {
// Create the entry to insert.
ContactEntry contact = new ContactEntry();
// Set the contact's name.
Name name = new Name();
final String NO_YOMI = null;
name.setFullName(new FullName("Elizabeth Bennet", NO_YOMI));
name.setGivenName(new GivenName("Elizabeth", NO_YOMI));
name.setFamilyName(new FamilyName("Bennet", NO_YOMI))
contact.setName(name);
contact.setContent(new PlainTextConstruct("Notes"));
// Set contact's e-mail addresses.
Email primaryMail = new Email();
primaryMail.setAddress("liz#gmail.com");
primaryMail.setDisplayName("E. Bennet");
primaryMail.setRel("http://schemas.google.com/g/2005#home");
primaryMail.setPrimary(true);
contact.addEmailAddress(primaryMail);
Email secondaryMail = new Email();
secondaryMail.setAddress("liz#example.com");
secondaryMail.setRel("http://schemas.google.com/g/2005#work");
secondaryMail.setPrimary(false);
contact.addEmailAddress(secondaryMail);
// Set contact's phone numbers.
PhoneNumber primaryPhoneNumber = new PhoneNumber();
primaryPhoneNumber.setPhoneNumber("(206)555-1212");
primaryPhoneNumber.setRel("http://schemas.google.com/g/2005#work");
primaryPhoneNumber.setPrimary(true);
contact.addPhoneNumber(primaryPhoneNumber);
PhoneNumber secondaryPhoneNumber = new PhoneNumber();
secondaryPhoneNumber.setPhoneNumber("(206)555-1213");
secondaryPhoneNumber.setRel("http://schemas.google.com/g/2005#home");
contact.addPhoneNumber(secondaryPhoneNumber);
// Set contact's IM information.
Im imAddress = new Im();
imAddress.setAddress("liz#gmail.com");
imAddress.setRel("http://schemas.google.com/g/2005#home");
imAddress.setProtocol("http://schemas.google.com/g/2005#GOOGLE_TALK");
imAddress.setPrimary(true);
contact.addImAddress(imAddress);
// Set contact's postal address.
StructuredPostalAddress postalAddress = new StructuredPostalAddress();
postalAddress.setStreet(new Street("1600 Amphitheatre Pkwy"));
postalAddress.setCity(new City("Mountain View"));
postalAddress.setRegion(new Region("CA"));
postalAddress.setPostcode(new PostCode("94043"));
postalAddress.setCountry(new Country("US", "United States"));
postalAddress.setFormattedAddress(new FormattedAddress("1600 Amphitheatre Pkwy Mountain View"));
postalAddress.setRel("http://schemas.google.com/g/2005#work");
postalAddress.setPrimary(true);
contactOne.addStructuredPostalAddress(postalAddress);
// Ask the service to insert the new entry
URL postUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
ContactEntry createdContact = myService.insert(postUrl, contact);
System.out.println("Contact's ID: " + createdContact.getId());
return createdContact;
}
Update Contact
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.
The URL is of the form:
https://www.google.com/m8/feeds/contacts/userEmail/full/{contactId}
To ensure that the data sent to the API doesn't overwrite another client's changes, the contact entry's Etag should be provided in the request header.
If-Match: Etag
Upon success, the server responds with an HTTP 200 OK status code and the updated contact entry.
public static ContactEntry updateContactName(
ContactsService myService, URL contactURL)
throws ServiceException, IOException {
// First retrieve the contact to updated.
ContactEntry entryToUpdate = myService.getEntry(contactURL, ContactEntry.class);
entryToUpdate.getName().getFullName().setValue("New Name");
entryToUpdate.getName().getGivenName().setValue("New");
entryToUpdate.getName().getFamilyName().setValue("Name");
URL editUrl = new URL(entryToUpdate.getEditLink().getHref());
try {
ContactEntry contactEntry = myService.update(editUrl, entryToUpdate);
System.out.println("Updated: " + contactEntry.getUpdated().toString());
return contactEntry;
} catch (PreconditionFailedException e) {
// Etags mismatch: handle the exception.
}
return null;
}
Delete Contact
To delete a contact, send an authorized DELETE request to the contact's edit URL.
The URL is of the form:
https://www.google.com/m8/feeds/contacts/{userEmail}/full/{contactId}
To ensure that the data sent to the API doesn't overwrite another client's changes, the contact entry's Etag should be provided in the request header.
If-Match: Etag
Upon success, the server responds with an HTTP 200 OK status code.
public static void deleteContact(ContactsService myService, URL contactURL)
throws ServiceException, IOException {
// Retrieving the contact is required in order to get the Etag.
ContactEntry contact = myService.getEntry(contactURL, ContactEntry.class);
try {
contact.delete();
} catch (PreconditionFailedException e) {
// Etags mismatch: handle the exception.
}
}
while People API:
The People API lets you list authenticated users' Contacts and retrieve profile information for authenticated users and their contacts.
For example, let's say the authenticated user, Jen, has Fabian and Ranjith in her private contacts. When your app calls people.connections.list to retrieve a list of her connections, Jen is presented with a consent screen asking to give the app access to the list. If Jen consents, the app retrieves a list containing Fabian and Ranjith (with a resource name for each person). The app can then call people.get, passing in a resource name, to get private contact and public profile data for each person.

Send a mail from outlook by getting To list from SQl server

I am stuck with a issue from 5 days.
I need a way to attain following requirement.
mailing list is present in Database(SQL server)
I have a mail in Outlook
now i have to send mail to all the 200,000 mail ids in Database
**Note one mail can have only 200 mail IDs so
200,000/200=1000 mails **Note: this 200,000 count is not fixed it will decrease and increase>
like jhon#xyz.com will be present today , next day we may need not send to him
his name might be completely removed (so DL is not an option)
I need a way to automate this
All i have a sleep less nights and coffee cups on my desk
I work in ASP.net any PL which meets this need is fine.
I assume that you know how to create sql statement for what you need and how to retrieve data from database in .NET. This means that only issue is actually sending this from outlook.
Here is an article that describes this in detail and piece of code copied from there.
using System;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookAddIn1
{
class Sample
{
public static void SendEmailFromAccount(Outlook.Application application, string subject, string body, string to, string smtpAddress)
{
// Create a new MailItem and set the To, Subject, and Body properties.
Outlook.MailItem newMail = (Outlook.MailItem)application.CreateItem(Outlook.OlItemType.olMailItem);
newMail.To = to;
newMail.Subject = subject;
newMail.Body = body;
// Retrieve the account that has the specific SMTP address.
Outlook.Account account = GetAccountForEmailAddress(application, smtpAddress);
// Use this account to send the e-mail.
newMail.SendUsingAccount = account;
newMail.Send();
}
public static Outlook.Account GetAccountForEmailAddress(Outlook.Application application, string smtpAddress)
{
// Loop over the Accounts collection of the current Outlook session.
Outlook.Accounts accounts = application.Session.Accounts;
foreach (Outlook.Account account in accounts)
{
// When the e-mail address matches, return the account.
if (account.SmtpAddress == smtpAddress)
{
return account;
}
}
throw new System.Exception(string.Format("No Account with SmtpAddress: {0} exists!", smtpAddress));
}
}
}
What I would suggest is to skip using outlook unless that’s really necessary and send email by directly communicating with SMTP server.
Just search for “how to send email from C#” or something similar and you’ll find a ton of examples.

Resources