Is your question:
- how to capture the avatar at signup?
- how to choose which avatar if there are multiple social accounts?
- how to hook the signup and instead connect the potential new user to an existing accout?
I'll address all three.
Capturing avatar at signup
My approach to this is receive the user_signed_up
signal. I also extract the user name (if available) at this time.
This is the function I use:
@receiver(user_signed_up)
def set_initial_user_names(request, user, sociallogin=None, **kwargs):
"""
When a social account is created successfully and this signal is received,
django-allauth passes in the sociallogin param, giving access to metadata on the remote account, e.g.:
sociallogin.account.provider # e.g. 'twitter'
sociallogin.account.get_avatar_url()
sociallogin.account.get_profile_url()
sociallogin.account.extra_data['screen_name']
See the socialaccount_socialaccount table for more in the 'extra_data' field.
From http://birdhouse.org/blog/2013/12/03/django-allauth-retrieve-firstlast-names-from-fb-twitter-google/comment-page-1/
"""
preferred_avatar_size_pixels = 256
picture_url = "http://www.gravatar.com/avatar/{0}?s={1}".format(
hashlib.md5(user.email.encode('UTF-8')).hexdigest(),
preferred_avatar_size_pixels
)
if sociallogin:
# Extract first / last names from social nets and store on User record
if sociallogin.account.provider == 'twitter':
name = sociallogin.account.extra_data['name']
user.first_name = name.split()[0]
user.last_name = name.split()[1]
if sociallogin.account.provider == 'facebook':
user.first_name = sociallogin.account.extra_data['first_name']
user.last_name = sociallogin.account.extra_data['last_name']
# verified = sociallogin.account.extra_data['verified']
picture_url = "http://graph.facebook.com/{0}/picture?width={1}&height={1}".format(
sociallogin.account.uid, preferred_avatar_size_pixels)
if sociallogin.account.provider == 'google':
user.first_name = sociallogin.account.extra_data['given_name']
user.last_name = sociallogin.account.extra_data['family_name']
# verified = sociallogin.account.extra_data['verified_email']
picture_url = sociallogin.account.extra_data['picture']
profile = UserProfile(user=user, avatar_url=picture_url)
profile.save()
user.guess_display_name()
user.save()
That's from a Django-allauth starter example I wrote
When the user signs in that function is called. It grabs the user's name and avatar data if it can.
Choosing which avatar if there are multiple accounts
My view is that this is a user choice thing. A user can't sign up with multiple social providers in the same instant.
There is always a sequence, e.g. Google first then they connect Facebook.
As such, my view is the system uses the avatar from the first social provider. The allauth UI lets the user add
other social providers once they've set up the initial one (try the deo-allauth-bootrap above and you'll see).
If the user adds another social network, add some UI to choose that avatar when they want to.
Hook signup to connect existing account
This would take some experimentation but overall I feel like this is not solving a real problem.
The built-in allauth UI allows the user (once registered) to add existing social providers. That's the correct
way to do it and it works out-of-the-box.
If the user signs up with another social provider then it's arguably either a mistake or they want two
separate accounts.
Granted, this needs some experimentation with users to see what is the most intuitive experience.
It could be, for example, that the site notes that the user has signed in with Google before and shows the Google
button slightly differently or "sign in again with Google", so the user doesn't accidentally sign up with a
different social account.