Google Contacts Importer

Could not get a bunch of contacts to import into Google Contacts the way I wanted.  I had a CSV that I exported from Outlook but no matter what I did to the CSV header names, I did not get the phone numbers spiked out for the contact correctly.  Instead the phone numbers would all be put as text into the Notes of the contact.  Useless.

So I rolled up my sleeves and wrote the following code to import the CSV file.  I made some assumptions (because I could) about the order fields appear in the file and their format.  For instance, the name I have is in the “Last, First M.” format; so the code breaks this up.  Also, all the phone numbers are formatted correctly so no fixing required.

Another assumption is that all the contacts are added to the same group (see the constant at the top) which does not have to be the same as the company name in the CSV file.  Probably could have cleaned this up a bit, but it worked for what I needed.  

Hope this helps someone…

CSV Format
 UserName,Company,Department,Cell Phone,Home Phone,Work Phone,Mobile Phone 2  
"Adams, Gomez",My Co,Accounting,,(212) 555-4805,(212) 555-6748,

C# Code

 using System;  
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Diagnostics;
using Google.Contacts;
using Google.GData.Contacts;
using Google.GData.Client;
using Google.GData.Extensions;
using LumenWorks.Framework.IO.Csv; // http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
namespace UploadContacts
{
class MyContact
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company{ get; set; }
public string Department{ get; set; }
public string CellPhone{ get; set; }
public string HomePhone{ get; set; }
public string WorkPhone{ get; set; }
public string CellPhone2{ get; set; }
}
internal static class Program
{
private const string CompanyNameForGroup = "My Co";
private const string AppName = "Test";
private const string Username = "Me";
private const string Password = "blah";
private static ContactsService _cs;
private static void Main()
{
var himcoGroupId = LookupGroup(CompanyNameForGroup).Id;
var data = ReadCsv();
foreach (var contact in data)
{
var newEntry = CopyData(contact, himcoGroupId);
AddContact(newEntry);
}
}
private static void AddContact(ContactEntry newEntry)
{
if (_cs == null)
{
_cs = new ContactsService(AppName);
_cs.setUserCredentials(Username, Password);
}
var displayName = string.Format("{0} {1}", newEntry.Name.GivenName, newEntry.Name.FamilyName);
var feedUri = new Uri(ContactsQuery.CreateContactsUri("default"));
try
{
_cs.Insert(feedUri, newEntry);
Console.WriteLine("Added {0}", displayName);
}
catch (Exception ex)
{
Console.WriteLine("Error {0} while adding {1}", ex.Message, displayName);
}
}
private static ContactEntry CopyData(MyContact contact, string himcoGroupId)
{
var fullName = string.Format("{0} {1}", contact.FirstName, contact.LastName);
var newEntry = new ContactEntry
{
Title = {Text = fullName},
Name = new Name {GivenName = contact.FirstName, FamilyName = contact.LastName}
};
newEntry.Categories.Add(new AtomCategory(CompanyName));
newEntry.Organizations.Add(new Organization
{
Department = contact.Department,
Name = contact.Company,
Primary = true,
Rel = ContactsRelationships.IsWork
});
if (!string.IsNullOrEmpty(contact.CellPhone))
newEntry.Phonenumbers.Add(new PhoneNumber(contact.CellPhone)
{
Primary = true,
Rel = ContactsRelationships.IsMobile
});
if (!string.IsNullOrEmpty(contact.CellPhone2))
newEntry.Phonenumbers.Add(new PhoneNumber(contact.CellPhone2)
{
Primary = false,
Rel = ContactsRelationships.IsOther
});
if (!string.IsNullOrEmpty(contact.HomePhone))
newEntry.Phonenumbers.Add(new PhoneNumber(contact.HomePhone)
{
Primary = false,
Rel = ContactsRelationships.IsHome
});
if (!string.IsNullOrEmpty(contact.WorkPhone))
newEntry.Phonenumbers.Add(new PhoneNumber(contact.WorkPhone)
{
Primary = false,
Rel = ContactsRelationships.IsWork
});
newEntry.GroupMembership.Add(new GroupMembership {HRef = himcoGroupId});
return newEntry;
}
public static Group LookupGroup(string name)
{
var rs = new RequestSettings(AppName, Username, Password);
var cr = new ContactsRequest(rs);
var feed = cr.GetGroups();
var retVal = feed.Entries.Where(i => i.Title == name);
return retVal.First();
}
public static IEnumerable ReadCsv()
{
var retList = new List();
using (var csv = new CsvReader(new StreamReader(@"C:\Users\Curtis1\Dropbox\Code\UploadContacts\UploadContacts\PhoneNumbers.csv"), true))
{
while (csv.ReadNextRecord())
{
string fname;
string lname;
var wholeName = csv[0];
var nameParts = wholeName.Split(new [] { ',' });
if (nameParts.Length >= 2)
{
fname = nameParts[1];
lname = nameParts[0];
}
else
{
nameParts = wholeName.Split(new [] {' '});
fname = nameParts[0];
lname = nameParts[1];
}
if (fname.Length == 0 || lname.Length == 0)
Debug.Assert(false);
var newContact = new MyContact
{
FirstName = fname,
LastName = lname,
Company = csv[1],
Department = csv[2],
CellPhone = csv[3],
HomePhone = csv[4],
WorkPhone = csv[5],
CellPhone2 = csv[6]
};
retList.Add(newContact);
}
}
return retList;
}
}
}

Is Google the New Microsoft?

I just got an email from Google on a new “feature” that is integrated into the gmail client; called Buzz. At first glance this looks and feels a lot like Facebook. So it got me thinking…

Is Google starting to feel like the next Microsoft? Is this path something Google is consciously trying to do or is it just a path that is inevitable?

First, a full disclosure. [I like both these company's technologies. I used to work for Microsoft and I still have a Microsoft technology bias (but I do own a MacBook). And my primary email account is my Google account and I own an Android phone. Phew, so now that I got that off my chest here is what I mean.]

There are at least four ways I have seen recently that made me want to write this blog entry…

  1. Leapfrog Innovation
  2. Purchase Innovation.
  3. ABG (anything but Google).
  4. All these lead to one thing…can you say Antitrust.

Leapfrog Innovation. I consider taking a good idea and making better – innovation. I am all for companies that can make something better than their competition; whether they came up with original idea is just an excuse the losers use. Of course if you use your size and power as a way of strong arming your friends and enemies – that’s a whole other story. Certainly Microsoft had some questionable practices back in the day. My whole take on that was stop the “packaging” and just make your software kick ass.

Purchase Innovation. This is a perfectly legitimate way of larger companies using their size and power (aka capital) to buy an innovator or a market leader. One of the companies I started had as a hidden part of the business plan to get bought out. I used to talk to a number of other people who were doing similar things who would admit the same goal to me. Google is just the new guy with all the money.

ABG. This reminds me of the Anything But Microsoft movement 10 years (maybe more now). I think this just comes down to people not liking really big companies; probably because they don’t trust them as much or just don’t identify with them. In both cases of these company’s respective histories they have been underdogs and people heralded their greatness. Then at some inflection point all that changes. There is probably more written on this than I care to read.

Antitrust. Obama’s antitrust czar and the EU are looking into this. Watch out. It was the combination of the Internet bubble and the antitrust rulings against Microsoft that caused the stock to tumble where it has been for the past 8 years (or so). As fortune would have it that is also right around the time that I looked like a financial genius and cashed in my options. The truth is that I had to cash them in and resemblance of genius was actually pure coincidence.