I have this specific problem:
From our application a client can connect to Salesforce CRM. After the connection is successful the client can export contacts from our application to their salesforce app. The payload looks roughly like this:
export_data = {
FirstName: contact.first_name,
LastName: contact.surname.presence || "-",
Title: contact.job_title,
Email: contact.safe_email,
Fax: contact.fax,
Phone: contact.phone_for_export,
MailingCity: contact.contact_city,
MailingCountry: contact.contact_country,
OwnerId: owner_id,
LeadSource: "MyApplication"
}
And the owner_id method looks like:
Rails.cache.fetch([:account_owner_id, @user.id], expires_in: 1.month) do
@api_client.user_info&.dig("user_id")
end
Now given this flow:
- Client app is named let's say Education App.
- Education App owner is initially the same who connected their salesforce app to our app
- They change the owner of the app(account) ticking the Transfer and keep account team
- Now when they export another contact/lead from our app, we obviously pass the OwnerId from cache, but client insists that this is not a problem but the fact that after that import and a refresh the app(account)owner is changed back to the old one(the one that initially connected. don't know if it's because of ownerId we pass or just because the token we nmake API calls with is associated with it)
My question is, why this happens. As long as from our side we just use update/create for leads/contacts, we do not manipulate any other data through other available endpoints. Is a flow/trigger on their side?
I do not have access to client org, so my tries to debugg/understand better were limited. Though, before starting to change my code, connecting to another account/sandbox, as I suspect the issue may be on their side with a trigger/flow/assignment rule, I'd love some salesforce developers opinions.
EDIT: Thank you for your answer. Here are some clarifications:
- We provide a link in front-end app where user goes, login with their credentials, and after we come to a callback in Rails and store the tokens we receive to further be used for any upcoming API calls.
@api_client.user_info&.dig("user_id")is just an API call touser_infoendpoint provided by salesforce. So I'd say it return id of current running user is true. - I am not sure what type of account it is but from a video they showed me, it's the guy who owns the company so most probably is a sysadmin.
- We assign an AccountId too, which I did not share the code initially
export_data[:AccountId] = company_id if company_id.present?Internally our records(which translate to a lead/contact after export is associated with a company, so the company_id will be the AccountId. - From their video, when we export it goes to them as a Lead.
- Requirement is that if they export let's say 2 leads, after that from the salesforce interface they change the account owner, the third export will not change back the account owner back to the original.
Not a 100% answer but too long for a comment.
What does that
@api_client.user_info&.dig("user_id")do? Does it return id of current running user (who you're logged in as?) then yes, it'd keep referencing the person that originally authorised the app to use their account (or gave you the username and password, yuck... don't know which login method you're using).Or is it similar to
SELECT OwnerId FROM Account WHERE Id = '001...'? In which case maybe all you'd need to do is to reduce the cache time? (Did you forget to include mapping forAccountIdin your sample payload?)You could remove the
OwnerIdfrom the field mapping but net result would be same, the field would default to who's creating the record.You're using the key words in weird way, like the apparent link between account id and user id... I have a feeling you're not connecting as an internal Salesforce user. Do you know if it's internal (like some sysadmin) or maybe a Community user (customer community, experience bundle, rings any bells?).
Do you know what are you creating in Salesforce, a Contact or say a Lead? For Leads you could utilise "assignment rules" where client controls who will become the lead's owner. But
MailingCitysuggests Contacts and it's very unusual to insert Contacts without Account Id linked.What's the requirement? That Contacts would have same Owner as Accounts, even after transfer? Your client could easily enforce that on their end with an "early flow" or "before insert" trigger. Or you could waste 1 API call to query that before inserting them...
Edit
"the third export will not change back the account owner back to the original" - but you don't update accounts, you upsert Contacts (doesn't look like leads, not with "MailingCity"). I suspect what you send ends up as Contact (if account id is set) or Lead (if it's not set). Which in some twisted way mimics Salesforce's core bahaviour (if "Account Name" text field is populated on Lead during conversion it'll become Account + possibly more).
I'd be tempted to simplify it, ditch setting the OwnerId (it'll be set to current running user anyway). If they do have some weird automation that on contact insert goes to account and edits them - that's on them? Ask if they could enable debug logging during next sync, could help nailing it down. And/or "field history" for Account -> Owner Name field. Their admin can also check "Flow Explorer" for Contact and if there are any triggers on Contact object...
Can you say what endpoint you're sending the data to? Does it have
/apexrest/in the url? That'd indicate custom service they built to map data into Contacts/Leads/what have you. As opposed to standard API likedata/v59.0/sobjects/Contact/