-
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 Contacts and Leads 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
Userfaculty_statusto "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