Occasional non-association of a contact and a deal via Ecomm bridge
SOLVE
I ran a simple test recently sending about a 100 deals to our test portal via Ecomm bridge. Out of those, 32 deals ended up in Hubspot with no contact associated.
I checked, and each and every contact for those 32 deals was created (Original source drill-down 1 = INTEGRATIONS_SYNC), it's just the association isn't there.
I'm having a hard time pinpointing a problem, and all API requests were successful, maybe someone has encountered these issues before? Any advice is welcome, thanks!
Details: portal ID 4455895, sample deal ID 678862257 and customer vid 4651.
I took a closer look at the contacts and deals you shared and found that the deal records were created before the contact records, causing the failed associations.
Contact 4651, has the createdate value1555172304098 (4/13/2019, 12:18:24 PM), however deal 678862257 was created 6 milliseconds earlier at 1555172304092.
Similarly, although you sent the sync message to create contact 7701 (externalObjectId: 67ac3a84-4c66-4254-a96a-70be29ff7885) first, it was actually created at 1555429968517 (4/16/2019, 11:52:48 AM) while deal 683619340 (externalObjectId: 1d579b44-71be-4c8d-ad76-d055476e2aef) was created 6 seconds earlier at 1555429962000 (4/16/2019, 11:52:42 AM).
The Ecommerce Bridge creates objects asynchronously, so these associations can and sometimes do get dropped in initial syncs (especially since deals tend to be created more quickly than contacts), but I agree that 5-6 seconds is a long time to wait. I will share your pain with the team and will update here with any actions they take.
As a possible alternative, I also know that the team has also made improvements to the speed and flexibility of the Ecommerce Bridge V2, which is now in developer preview.
Sorry for dropping the ball on this. Thanks for providing those examples!
Are you creating the contact records before the deals?
I just ran some tests where deal sync messages triggered 204 responses even if the contact specified in the hs_assoc__contact_ids property had yet to be created. Per the description for this association property: "Deals are not required to be associated to contacts, so an invalid value for this property will not prevent the successful creation of a deal."
If I created the contacts before syncing the deals, however, the objects were successfully associated.
Yep, we create contact first, then the deal, then the line item. We're seeing this non-association constantly and frankly, it's a bit disappointing.
We came up with a minimal test case (below) and started introducing delays between contact and deal creation. Up until we ramp up the delay to 5 seconds we see non-assocs. From where I stand, it's just some race condition or just a slow endpoint
import json
import datetime
import time
from urllib.parse import urlencode
from urllib.request import Request, urlopen
BASE_URL = 'https://api.hubapi.com/'
HS_KEY = 'd4e6cdb1-wiped-for-security-reasons'
START_FROM = 50
NUMBER = 10
DELAY = 5.0
def upload_fake(start_from, n):
for i in range(start_from, start_from + n):
si = str(i)
print(si)
contact_id = 'fake-contact-' + si
deal_id = 'fake-deal-' + si
contact = {
'integratorObjectId': contact_id,
'action': 'UPSERT',
'changeOccurredTimestamp': unixtime_now(),
'propertyNameToValues': {
'firstname': 'Name' + si,
'lastname': 'Surname' + si,
'email_0': 'user' + si + '@fakeusers.com',
'city': 'Gotham City',
'state': 'NY',
'country': 'US',
}
}
ecomm_sync_contacts([contact])
time.sleep(DELAY)
deal = {
'integratorObjectId': deal_id,
'action': 'UPSERT',
'changeOccurredTimestamp': unixtime_now(),
'propertyNameToValues': {
'dealname': 'deal' + si,
'amount': '100.00',
'dealstage': 'checkout_completed',
'hs_assoc__contact_ids': contact_id,
}
}
ecomm_sync_deals([deal])
time.sleep(DELAY)
def unixtime_now():
UNIX_EPOCH = datetime.datetime(1970, 1, 1)
dt = datetime.datetime.utcnow()
ut = int((dt - UNIX_EPOCH) / datetime.timedelta(seconds=1)) * 1000
return ut
def ua_put_json(suburl, payload):
url = BASE_URL + suburl + '?hapikey=' + HS_KEY
body = json.dumps(payload).encode()
req = Request(url,
data=body,
headers={
'Content-Type': 'application/json',
},
method='PUT')
resp = urlopen(req).read().decode()
# print(resp)
# --- Ecommerce Bridge sync -----------------------------------------------
def ecomm_sync_contacts(contacts):
r = ua_put_json(
'extensions/ecomm/v1/sync-messages/CONTACT', payload=contacts)
return r
def ecomm_sync_products(products):
r = ua_put_json(
'extensions/ecomm/v1/sync-messages/PRODUCT', payload=products)
return r
def ecomm_sync_deals(deals):
r = ua_put_json(
'extensions/ecomm/v1/sync-messages/DEAL', payload=deals)
return r
def ecomm_sync_line_items(items):
r = ua_put_json(
'extensions/ecomm/v1/sync-messages/LINE_ITEM', payload=items)
return r
def main():
upload_fake(START_FROM, NUMBER)
main()
I took a closer look at the contacts and deals you shared and found that the deal records were created before the contact records, causing the failed associations.
Contact 4651, has the createdate value1555172304098 (4/13/2019, 12:18:24 PM), however deal 678862257 was created 6 milliseconds earlier at 1555172304092.
Similarly, although you sent the sync message to create contact 7701 (externalObjectId: 67ac3a84-4c66-4254-a96a-70be29ff7885) first, it was actually created at 1555429968517 (4/16/2019, 11:52:48 AM) while deal 683619340 (externalObjectId: 1d579b44-71be-4c8d-ad76-d055476e2aef) was created 6 seconds earlier at 1555429962000 (4/16/2019, 11:52:42 AM).
The Ecommerce Bridge creates objects asynchronously, so these associations can and sometimes do get dropped in initial syncs (especially since deals tend to be created more quickly than contacts), but I agree that 5-6 seconds is a long time to wait. I will share your pain with the team and will update here with any actions they take.
As a possible alternative, I also know that the team has also made improvements to the speed and flexibility of the Ecommerce Bridge V2, which is now in developer preview.
Occasional non-association of a contact and a deal via Ecomm bridge
SOLVE
Thank you @IsaacTakushi , we'll run the tests using v2 asap, and I'll let you know the outcome.
I wonder, is there some reference Ecomm bridge API implementation to compare ourselves against? It's hard to imagine that nobody faced this association issue before, I still second-guess whether we missed something.
We currently don't have any example implementations, but I have worked with other integrators who have also encountered association issues because deals were created before contact records. I don't think you've missed anything; it is an unfortunate reality of the asynchronous nature of the Bridge. I'll continue to advocate to the team — I hope we can come up with a better way to handle these types of issues going forward.
Starting tomorrow, I will be out of the office until May 8, 2019. I can address any additional comments when I return, however if you have a pressing issue, please feel free to create a new post and cite this discussion. Thanks for your understanding!
I haven't seen reports of this issue recently, but I'd like to investigate further.
Do you happen to have logs of the sync messages you sent for some of the objects missing associations? I'd like to at least see the externalObjectId values you used in an attempt to associate contacts and deals.
Occasional non-association of a contact and a deal via Ecomm bridge
SOLVE
For some reason, I'm getting "This reply was marked as spam and has been removed. If you believe this is an error, submit an abuse report." when trying to post a JSON snippet 😞
I already reported it, any chance you can pull my message out of the spam can? I can use a gist or pastebin if it doesn't work out