Email_hashes with Facebook Connect and connect.registerUsers

Dec 18, 2008 at 6:05 PM
Edited Dec 18, 2008 at 6:06 PM

Since connect.registerUsers is not part of the Toolkit how can it be called using API.SendRequest?

I've managed to get the email_hash variable generated properly with CRC32 and MD5 as the documentation suggests, but then can't figure out how to push that through the API.SendRequest.

Here's my code which errors because the Dictionary value needs to be both a string (for the "method") and another Dictionary (for the "accounts"):

Dim accounts As New Dictionary(Of String, String)
accounts.Add("email_hash", Email_Hash(mary@example.com))
accounts.Add("account_id", "572453")

 

Dim param As New Dictionary(Of String, Dictionary(Of String, String))
param.Add("method", "facebook.connect.registerUsers")
param.Add("accounts", accounts)

 

Dim ret As String
ret = Master.API.SendRequest(param)

 

Dec 31, 2008 at 9:04 PM
How were you able to get the email_hash?

Thanks!
Jan 1, 2009 at 3:41 AM
I figured out how to get the email_hash, and now I need to do connect.registerUsers. I looked at otint's code and came up with this (C#):

var user = Membership.GetUser();
IDictionary<string, string> connectAccount = new Dictionary<string, string>();
connectAccount.Add("method", "connect.registerUsers");
connectAccount.Add("accounts", "{{email_hash: " + getEmailHash(user.Email) + ",  account_id: " + user.ProviderUserKey.ToString() + "}}");

string email_hash = api.SendRequest(connectAccount);

This returns the error: facebook.Utility.FacebookException: Invalid parameter

Can anyone help? Thanks!
Jan 9, 2009 at 5:36 PM
Edited Jan 9, 2009 at 5:41 PM
Here's how I ended up doing it:

Dim accounts As New Dictionary(Of String, String
accounts.Add(
"email_hash", Trim(Email_Hash(xxx@yyy.com)))
Dim accountsData = JSONHelper.ConvertToJSONAssociativeArray(accounts)
Dim accountsMap As New Dictionary(Of String, String)

accountsMap.Add(
"0", accountsData)

Dim
accountsMapData = JSONHelper.ConvertToJSONAssociativeArray(accountsMap)
Dim param As New Dictionary(Of String, String)
param.Add(
"method", "facebook.connect.registerUsers")
param.Add(
"accounts", accountsMapData)

Dim paramData = JSONHelper.ConvertToJSONAssociativeArray(param)

Try

Dim fields = JSONHelper.ConvertFromJSONArray(Master.API.SendRequest(param))
 
Dim resu As String = ""
For Each field In fields 
    resu &= field.ToString &
"<br>"
 
Next

Master.SendExternalEmail("aaa@bbb.com", "", "email_hash response", (resu.ToString))

Catch ex As Exception 

 Master.SendExternalEmail(
"aaa@bbb.com", "", "Error with email_hash", (ex.ToString & "<br /><br />param: " & paramData))

End Try
Jan 12, 2009 at 12:19 PM
Hi,

  I tried with the above code and its showing an error "Invalid email hash specified." Any idea what happened

  Between, which email id should be given for hashing, my facebook login id or anyother id?

Thanks,
Rejeev.
Developer
Jan 13, 2009 at 4:30 AM
Have you verified that your own email hashing method correctly produces the results that the API expects? You would provide the email associated with any user in your Connect site.
Jan 13, 2009 at 5:31 AM

Yes the email hashing method generates the correct result (checked with the email hash given in the facebook for mary@example.com (http://wiki.developers.facebook.com/index.php/Connect.registerUsers))

I am developing a sample app to connect to facebook where I will pass a user(emailid) in my app to Facebook using the connect.RegisterUser, I am not doing this from inside Facebook canvas...Is this the way to do this. Please correct me if I am wrong.


 Dictionary<string, string> accounts = new Dictionary<string, string>();
            accounts.Add("email_hash", makeEmailHashes(txtEmail.Text).Trim());

   public bool connectRegister(Dictionary<string, string> accounts)
        {
            var parameterList = new Dictionary<string, string> { { "method", "facebook.connect.registerUsers" } };
                     
            _api.AddJSONAssociativeArray(parameterList, "accounts", accounts);            
           
            var response = _api.SendRequest(parameterList);
            return string.IsNullOrEmpty(response);
        }


Rejeev.




Jan 30, 2009 at 7:32 PM
your "invalid email hash specified" is because accounts is an array of arrays - create an associative array for each account, add each of those to a List<string>, and then add that List<string> using ConvertToJSONArray as the accounts parameter.
Feb 17, 2009 at 6:15 PM
Edited Feb 17, 2009 at 6:37 PM
Using the above, with all the corrections that were suggested along the way, the following is a full working example in C# including the Email Hash method:

using facebook;
using facebook.Utility;
using System.Security.Cryptography;
:
:
public static bool IsUserRegistered(string email)
{
        Dictionary<string, string> accounts = new Dictionary<string, string>();
        string hash = EmailHash(email);
        accounts.Add("email_hash", hash);
        string accountsJson = JSONHelper.ConvertToJSONAssociativeArray(accounts);

        Dictionary<string, string> accountsMap = new Dictionary<string, string>();
        accountsMap.Add("0", accountsJson);
        string accountsMapJson = JSONHelper.ConvertToJSONAssociativeArray(accountsMap);

        Dictionary<string, string> param = new Dictionary<string, string>();
        param.Add("method", "facebook.connect.registerUsers");
        param.Add("accounts", accountsMapJson);
        param.Add("format", "JSON");

        string paramJson = JSONHelper.ConvertToJSONAssociativeArray(param);

        try {
            API api = new API();
            api.ApplicationKey = DonateMate.Facebook.Utility.ApiKey();
            api.Secret = DonateMate.Facebook.Utility.SecretKey();
            List<string> fields = JSONHelper.ConvertFromJSONArray(api.SendRequest(param, false));
            return (hash == fields[0]);
        }
        catch(Exception exp)
        {
            Trace.Write(exp.Message);
            return null;
        }
}

public static string EmailHash(string email)
{
        email = email.ToLower().Trim();
        byte[] rawBytes = System.Text.UTF8Encoding.UTF8.GetBytes(email);

        CRC32 crc= new CRC32();
        UInt32 crcResult = crc.GetCrc32(new System.IO.MemoryStream(rawBytes));

        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] md5Result = md5.ComputeHash(rawBytes);
        string md5Data = this.ToHexString(md5Result).ToLower();

        return crcResult.ToString() + "_" + md5Data;
}

public static string ToHexString(byte[] bytes)
{
       string hexString = "";
       for (int i = 0; i < bytes.Length; i++)
           hexString += bytes[i].ToString("X2");
       return hexString;
}

The code for the CRC32 can be found at:
http://www.vbaccelerator.com/home/net/code/libraries/CRC32/Crc32_zip_CRC32_CRC32_cs.asp

I hope this saves you all some time...