[PAN-2508] ShipBob <> Gorgias Sample Integration in Python - #11
[PAN-2508] ShipBob <> Gorgias Sample Integration in Python#11sarahtrefethen wants to merge 3 commits into
Conversation
33da2a8 to
1bbbfd4
Compare
e9b29ef to
6a6cea5
Compare
6a6cea5 to
f3ab08d
Compare
eab44f5 to
29ccfa0
Compare
| 'https://authstage.shipbob.com': 'https://sandbox-api.shipbob.com/2026-01', | ||
| 'https://auth.shipbob.com': 'https://api.shipbob.com/2026-01', | ||
| } | ||
| DEFAULT_BASE_URL = 'https://api.shipbob.com/1.0' |
There was a problem hiding this comment.
Fallback base URL points to outdated ShipBob API version
| logger.info('Processing updated order with id %s', order["id"]) | ||
| process_order(order, gorgias, cache, newest_first) | ||
| # last_update_at is YYYY-MM-DDThh:mm:ss.sss+00:00; trim to 23 chars. | ||
| record['updated_order_start_date'] = shipbob.get_update_date(order, updated_cursor)[:23] |
There was a problem hiding this comment.
It unconditionally overwrites on every order in the loop, rather than taking a running min().
Failure scenario: Paging isn't guaranteed sorted across page boundaries, so the final cursor ends up being whatever the last order of the last page happened to have — not the true oldest processed update. The next run can start from a cursor that's newer than it should be, silently skipping orders updated in between. This contradicts the module's documented "never skips an update" guarantee.
| data.setdefault('pandium', {}) | ||
| if not isinstance(data['pandium'].get('shipbob_orders'), list): | ||
| data['pandium']['shipbob_orders'] = [] | ||
| cache[key] = {'id': existing['id'], 'data': data} | ||
| else: | ||
| cache[key] = gorgias.new_customer_payload(sb_order, key) |
There was a problem hiding this comment.
data.setdefault('pandium', {}) is a no-op if the key already exists with value None. The next line, data['pandium'].get('shipbob_orders'), then raises AttributeError on a NoneType.
Failure scenario: A Gorgias customer record with data: {"pandium": null} (e.g. edited via the Gorgias UI/API, or left over from a different integration) crashes the whole cron run for that page, uncaught before the surrounding try/except.
| orders.append(order_payload) | ||
| orders.sort(key=lambda o: o.get('id', 0), reverse=newest_first) | ||
| if len(orders) > MAX_ORDERS_TO_SYNC: | ||
| orders = orders[:MAX_ORDERS_TO_SYNC] if newest_first else orders[-MAX_ORDERS_TO_SYNC:] | ||
| return orders | ||
|
|
There was a problem hiding this comment.
order list sorted by id, not date. The sb2gorgias in the integrations repo sorted updated orders by actual last_update_at and relied on SortOrder=Oldest for new orders, then just sliced the trimmed list. This version re-sorts by o.get('id', 0) on every upsert, which may not have guaranteed relationship to update recency — an order just updated (lower id) can get bumped out of the kept 10 in favor of a higher-id order that wasn't recently touched. Suggest sorting by created_date / purchase_date instead (note: sort on the raw ISO value, before _format_date — the formatted %d/%m/%Y string doesn't sort chronologically).
|
|
||
| ``customer_ref`` is what Gorgias should attach the ticket to — ``{'id': ...}`` for | ||
| a customer we resolved, or ``{'email': ...}`` to let Gorgias resolve it. | ||
| """ |
There was a problem hiding this comment.
customer_ref is always produced by resolve_customer, and that function only has two return statements — both {'id': ...}. Might need to update the comment.
| deep_get(sb_order, 'recipient.address.address1', '') or '', | ||
| deep_get(sb_order, 'recipient.address.city', '') or '', | ||
| deep_get(sb_order, 'recipient.address.country', '') or '', | ||
| ] |
There was a problem hiding this comment.
Minor: we could reduce traversals here:
address = deep_get(sb_order, 'recipient.address', {})
deep_get(sb_order, 'recipient.name', '')
address.get('address1') or ''
address.get('city') or ''
address.get('country') or ''
https://greenwoodtech.atlassian.net/browse/PAN-2508