Skip to content

Instantly share code, notes, and snippets.

@gregjotau
Created October 1, 2023 17:18
Show Gist options
  • Save gregjotau/7897c36ec02c0de33ad6322f82cb64f1 to your computer and use it in GitHub Desktop.
Save gregjotau/7897c36ec02c0de33ad6322f82cb64f1 to your computer and use it in GitHub Desktop.
merge customer profiles and fix wrong emails due to typos, shopify api
import json
import logging
from shopify_utils import get_store
logging.basicConfig(level=logging.INFO)
def generate_variations(domain, max_distance=2):
alphabet = "abcdefghijklmnopqrstuv"
variations = {domain}
for variant in {domain}:
for i in range(len(variant) + 1):
for c in alphabet:
variations.add(variant[:i] + c + variant[i:])
for i in range(len(variant)):
variations.add(variant[:i] + variant[i + 1 :])
for i in range(len(variant)):
for c in alphabet:
variations.add(variant[:i] + c + variant[i + 1 :])
for i in range(len(variant) - 1):
variations.add(variant[:i] + variant[i + 1] + variant[i] + variant[i + 2 :])
# Special case for two deletions when max_distance is 1
if max_distance == 1:
for i in range(len(domain)):
for j in range(i + 1, len(domain)):
variations.add(domain[:i] + domain[i + 1 : j] + domain[j + 1 :])
# Double edit distance
if max_distance == 2:
single_variations = variations.copy()
for variant in single_variations:
for i in range(len(variant) + 1):
for c in alphabet:
variations.add(variant[:i] + c + variant[i:])
for i in range(len(variant)):
variations.add(variant[:i] + variant[i + 1 :])
for i in range(len(variant)):
for c in alphabet:
variations.add(variant[:i] + c + variant[i + 1 :])
for i in range(len(variant) - 1):
variations.add(
variant[:i] + variant[i + 1] + variant[i] + variant[i + 2 :]
)
return variations
# Domains and their variations
domains = [
"gmail.com",
"outlook.com",
"hotmail.no",
"icloud.com",
"hotmail.com",
"yahoo.com",
"live.no",
"live.dk",
"live.com",
"yahoo.no",
"yahoo.com",
"msn.com",
"me.com",
"outlook.no",
"online.no",
"outlook.dk",
]
domain_variations_map = {
domain: generate_variations(domain, max_distance=1) for domain in domains
}
# Initialize Shopify store
shopify_store = get_store()
# Main logic
for correct_domain, variations in domain_variations_map.items():
incorrect_customers = shopify_store.get_customers_by_domain_variations(variations)
logging.info(f"Found {len(incorrect_customers)} customers with incorrect domain.")
for customer in incorrect_customers:
correct_email = customer["email"].rsplit("@", 1)[0] + "@" + correct_domain
customer_url = f"https://admin.shopify.com/store/famme-international/customers/{customer['id']}"
customer_id_wrong_email = customer["id"]
if shopify_store.email_exists(correct_email):
logging.info(
f"Found customer: {customer_url} - merging with existing customer for email: {correct_email}"
)
# Merge customers
customer_id_correct_email = shopify_store.get_customer_id(correct_email)
merge_result = shopify_store.merge_customers(customer_id_wrong_email, customer_id_correct_email)
logging.info(f"Merge result: {merge_result}")
merge_result_dict = json.loads(merge_result)
user_errors = merge_result_dict.get("data", {}).get("customerMerge", {}).get("userErrors", [])
if user_errors:
for error in user_errors:
if "gift cards" in error.get("message", "").lower():
logging.warning(f"Failed to merge due to gift cards: {customer_url}")
else:
logging.info(
f"Found customer: {customer_url} - changing email to: {correct_email}"
)
# Update email
shopify_store.update_customer_email(customer_id_wrong_email, correct_email)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment