Merge pull request #2100 from coreos-inc/report-marketo

Report the user's name and company to Marketo
This commit is contained in:
josephschorr 2016-11-14 23:37:37 -05:00 committed by GitHub
commit e57eece6c1
8 changed files with 78 additions and 24 deletions

View file

@ -337,7 +337,8 @@ class User(BaseModel):
enabled = BooleanField(default=True)
invoice_email_address = CharField(null=True, index=True)
name = CharField(null=True)
given_name = CharField(null=True)
family_name = CharField(null=True)
company = CharField(null=True)
def delete_instance(self, recursive=False, delete_nullable=False):

View file

@ -1,23 +1,25 @@
"""Add user metadata fields
Revision ID: 491a530df230
Revision ID: faf752bd2e0a
Revises: 6c7014e84a5e
Create Date: 2016-11-04 18:03:05.237408
Create Date: 2016-11-14 17:29:03.984665
"""
# revision identifiers, used by Alembic.
revision = '491a530df230'
revision = 'faf752bd2e0a'
down_revision = '6c7014e84a5e'
from alembic import op
import sqlalchemy as sa
from util.migrate import UTF8CharField
def upgrade(tables):
### commands auto generated by Alembic - please adjust! ###
op.add_column('user', sa.Column('company', UTF8CharField(length=255), nullable=True))
op.add_column('user', sa.Column('name', UTF8CharField(length=255), nullable=True))
op.add_column('user', sa.Column('family_name', UTF8CharField(length=255), nullable=True))
op.add_column('user', sa.Column('given_name', UTF8CharField(length=255), nullable=True))
### end Alembic commands ###
op.bulk_insert(tables.userpromptkind,
@ -29,7 +31,8 @@ def upgrade(tables):
def downgrade(tables):
### commands auto generated by Alembic - please adjust! ###
op.drop_column('user', 'name')
op.drop_column('user', 'given_name')
op.drop_column('user', 'family_name')
op.drop_column('user', 'company')
### end Alembic commands ###

View file

@ -355,10 +355,11 @@ def list_entity_robot_permission_teams(entity_name, include_permissions=False):
return TupleSelector(query, fields)
def update_user_metadata(user, name=None, company=None):
def update_user_metadata(user, given_name=None, family_name=None, company=None):
""" Updates the metadata associated with the user, including his/her name and company. """
with db_transaction():
user.name = name or user.name
user.given_name = given_name or user.given_name
user.family_name = family_name or user.family_name
user.company = company or user.company
user.save()

View file

@ -213,9 +213,13 @@ class User(ApiResource):
'type': ['string', 'null'],
'description': 'Custom email address for receiving invoices',
},
'name': {
'given_name': {
'type': 'string',
'description': 'The optional entered name for the user',
'description': 'The optional entered given name for the user',
},
'family_name': {
'type': 'string',
'description': 'The optional entered family name for the user',
},
'company': {
'type': 'string',
@ -332,10 +336,14 @@ class User(ApiResource):
code = model.user.create_confirm_email_code(user, new_email=new_email)
send_change_email(user.username, user_data['email'], code.code)
else:
user_analytics.change_email(user.email, new_email)
model.user.update_email(user, new_email, auto_verify=not features.MAILING)
if 'name' in user_data or 'company' in user_data:
model.user.update_user_metadata(user, user_data.get('name'), user_data.get('company'))
if 'given_name' in user_data or 'family_name' in user_data or 'company' in user_data:
model.user.update_user_metadata(user, user_data.get('given_name'),
user_data.get('family_name'), user_data.get('company'))
user_analytics.change_metadata(user.email, user_data.get('given_name'),
user_data.get('family_name'), user_data.get('company'))
# Check for username rename. A username can be renamed if the feature is enabled OR the user
# currently has a confirm_username prompt.
@ -353,6 +361,7 @@ class User(ApiResource):
raise request_error(message='Username is already in use')
user = model.user.change_username(user.id, new_username)
user_analytics.change_username(user.email, new_username)
elif confirm_username:
model.user.remove_user_prompt(user, 'confirm_username')

View file

@ -122,7 +122,8 @@ def common_login(db_user, permanent_session=True):
session.permanent_session_lifetime = convert_to_timedelta(session_timeout_str)
# Inform our user analytics that we have a new "lead"
user_analytics.create_lead(db_user.email, db_user.username)
user_analytics.create_lead(db_user.email, db_user.username, db_user.given_name,
db_user.family_name, db_user.company)
return True
else:
logger.debug('User could not be logged in, inactive?.')

View file

@ -42,19 +42,28 @@
<form name="metadataForm" ng-submit="updateUser(metadata)" style="margin-top: 20px;">
<div class="form-group nested">
<label for="name">Name</label>
<label for="givenName">Given Name</label>
<div class="field-row">
<span class="field-container">
<input type="text" class="form-control" placeholder="Name" ng-model="metadata.name"></span>
<input type="text" class="form-control" placeholder="Given Name" ng-model="metadata.given_name" name="givenName">
</span>
</div>
</div>
<div class="form-group nested">
<label for="firstName">Company</label>
<label for="familyName">Family Name</label>
<div class="field-row">
<span class="field-container">
<input type="text" class="form-control" placeholder="Company name" ng-model="metadata.company"></span>
<input type="text" class="form-control" placeholder="Family Name" ng-model="metadata.family_name" name="familyName">
</span>
</div>
</div>
<div class="form-group nested">
<label for="company">Company</label>
<div class="field-row">
<span class="field-container">
<input type="text" class="form-control" placeholder="Company name" ng-model="metadata.company" name="company"></span>
</span>
</div>
</div>

Binary file not shown.

View file

@ -27,13 +27,29 @@ class _MarketoAnalyticsClient(object):
self._munchkin_private_key = munchkin_private_key
self._lead_source = lead_source
def create_lead(self, email, username):
def _get_lead_metadata(self, given_name, family_name, company):
metadata = {}
if given_name:
metadata['firstName'] = given_name
if family_name:
metadata['lastName'] = family_name
if company:
metadata['company'] = company
return metadata
def create_lead(self, email, username, given_name, family_name, company):
lead_data = dict(
email=email,
Quay_Username__c=username,
leadSource='Web - Product Trial',
Lead_Source_Detail__c=self._lead_source,
)
lead_data.update(self._get_lead_metadata(given_name, family_name, company))
self._marketo.create_update_leads(
action='createOrUpdate',
leads=[lead_data],
@ -65,16 +81,30 @@ class _MarketoAnalyticsClient(object):
lookupField='id',
)
def change_username(self, email, new_username):
found = self._find_leads_by_email(email)
def change_metadata(self, email, given_name, family_name, company):
lead_data = self._get_lead_metadata(given_name, family_name, company)
if not lead_data:
return
# Update using their user id.
updated = [dict(id=lead['id'], Quay_Username__c=new_username) for lead in found]
# Update using their email address.
lead_data['email'] = email
self._marketo.create_update_leads(
action='updateOnly',
leads=updated,
leads=[lead_data],
asyncProcessing=True,
lookupField='id',
lookupField='email',
)
def change_username(self, email, new_username):
# Update using their email.
self._marketo.create_update_leads(
action='updateOnly',
leads=[{
'email': email,
'Quay_Username__c': new_username,
}],
asyncProcessing=True,
lookupField='email',
)
@AsyncExecutorWrapper.sync