-
Notifications
You must be signed in to change notification settings - Fork 7
Scheduled sync with salesforce
Bryan Eli edited this page Oct 14, 2020
·
9 revisions
Accounts does a sync with salesforce on a schedule basis. It pulls information about Contact
s and Lead
s from Salesforce and updates User
records in Accounts accordingly.
All the code for this is in one file, here: https://github.com/openstax/accounts/blob/35629624f3569327afa552900490e72d2372ae51/app/routines/update_user_salesforce_info.rb#L1
It does is the following:
- Goes through all users that have already have a Salesforce Contact ID, pulls their Salesforce information, and saves it in the User record.
- For users who do not yet have a Contact ID, looks for any leads with the given user's email address. If we find any, we check their lead's
Status
, and if all their leads have the status as "Converted", then it means that the user has been rejected as faculty. - For all other users who we don't have a contact or a lead for in SF, we change their
User
faculty_status
to "no_faculty_info".
Here's the schedule on which it runs: https://github.com/openstax/accounts/blob/660711e8985fa40e0fddc531f0115d7746048eac/config/schedule.rb#L12-L18
every '5,35 * * * *' do
runner <<-CMD
OpenStax::RescueFrom.this{
UpdateUserSalesforceInfo.call(allow_error_email: Time.zone.now.hour == 0 && Time.zone.now.min < 10)
}
CMD
end
- openstax_salesforce (Interface gem for accessing OpenStax's Salesforce instance) which uses openstax_active_force (Use SalesForce as an ActiveModel) which in turn uses restforce (A lightweight Ruby client for the Salesforce REST API)
- Lead https://github.com/openstax/openstax_salesforce/blob/master/lib/openstax/salesforce/remote/lead.rb
- Contact https://github.com/openstax/openstax_salesforce/blob/master/lib/openstax/salesforce/remote/contact.rb
# Go through all users that don't yet have a Salesforce Contact ID and populate their
# salesforce info when they have verified emails that match SF data.
@contacts_by_email.keys.each_slice(1000) do |emails|
# eager_load by default produces a LEFT OUTER JOIN
# But we can use an INNER JOIN here since we have a WHERE condition on contact_infos
# So we use joins to convert the LEFT OUTER JOIN to an INNER JOIN
User.activated.joins(:contact_infos)
.eager_load(:contact_infos)
.where(salesforce_contact_id: nil)
.where( ci_table[:value].lower.in(emails) )
.where( ci_table[:verified].eq(true).or(ci_table[:is_school_issued].eq(true)) )
.each do |user|
begin
# The query above limits us to only verified email addresses
# eager_load ensures only the verified email addresses are returned
contacts = user.contact_infos
.map{|ci| @contacts_by_email[ci.value.downcase]}
.uniq
if contacts.size > 1
error!(message: "More than one SF contact (#{contacts.map(&:id).join(', ')}) " \
"for user #{user.id}")
else
contact = contacts.first
cache_contact_data_in_user!(contact, user)
end
rescue StandardError => ee
error!(exception: ee, user: user)
end
end
end