Send Odoo Product Updates to Shopify | MESA Workflow Template

Sync Odoo Product Updates to Shopify Products

28 min setup

No coding required

Runs automatically

Keep your product information seamlessly aligned across Odoo and Shopify. Whenever a product is updated in Odoo, this MESA template automatically creates the product and its variants in Shopify if they don't already exist. For existing products, MESA applies any updates from Odoo to Shopify, ensuring your listings are always current. Eliminate the need for manual updates and simplify product management across platforms. Note, the SKUs in Odoo and Shopify must match exactly.

How it works

28 steps to start managing Shopify products from Odoo product updates automatically

Odoo Product Updated

App connector: [Odoo](/content/apps/odoo/integrate "View Odoo integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: This trigger monitors your Odoo products and kicks off the workflow whenever products get updated, catching inventory changes, price updates, and new variants so they flow to Shopify without manual replication.

Get Product By Title

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Before creating or updating anything, you need to know if this Odoo product already exists in Shopify—this search uses the product title to find potential matches and prevent duplicate products.

Filter: Check product title

App connector: [Filter](/content/apps/filter/integrate "View Filter integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: If multiple Shopify products have the same title, the workflow can't reliably determine which one to update—this filter stops processing when duplicate titles exist to prevent accidental data corruption.

Path - No Existing Shopify Product

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: This rule checks whether the Shopify search came back empty—if no product was found, you need to create a brand new product in Shopify rather than update an existing one.

Create Shopify Product

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: New Odoo products need corresponding records in Shopify so customers can discover and purchase them—this step creates the base product with title, description, and initial SKU.

Path - Has 1 Odoo Variant

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Products with only one variant can be processed quickly with a single create operation—this path handles the simple case where no variant looping is needed.

Create Product Variant

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: The base product needs at least one variant with pricing before customers can purchase it—this step adds that variant with the price from Odoo.

Path - Has More Than 1 Odoo Variants

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Products with multiple variants (like different sizes or colors) need special handling to create each variant individually—this path routes to the loop that processes each variant.

Loop: Get Odoo Product Variants

App connector: [Loop](/content/apps/loop/integrate "View Loop integration page"/index.html)• Time to complete: 1 minute

Why this matters: Each Odoo product variant needs to become a separate Shopify variant with its own SKU, title, and price—this loop processes them one at a time to create accurate variant records.

Retrieve Product Variant

App connector: [Odoo](/content/apps/odoo/integrate "View Odoo integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: The variant IDs from the loop don't include the detailed information needed to create Shopify variants—this step fetches the complete variant record including price, SKU, and display name.

Custom: Extract Odoo Variant Title

App connector: [Code](/content/apps/custom/integrate "View Code integration page"/index.html)• Time to complete: 1 minute

Why this matters: Odoo stores variant names within parentheses in the display name field—this code extracts just the variant title (like "Blue" or "Large") needed for the Shopify variant option.

const Mesa = require('vendor/Mesa.js');

/**
 * A MESA Script exports a class with a script() method.
 */
module.exports = new class {

/**
   * MESA Script
   *
   * @param {object} prevResponse The response from the previous step
   * @param {object} context Additional context about this task
   */
  script = (prevResponse, context) => {

// Retrieve the Variables Available to this step
    const vars = context.steps;
    // For storing response
    let response = {};
    // Get Odoo product variant
    const odooProductVariant = vars.odoo_1;
    // Get display name
    let displayNameProductVariant = vars.odoo_1.display_name;

// Extracting variant title
    let variantTitle = this.extractVariantTitle(displayNameProductVariant);

// Add to response
    response.variant_title = variantTitle;

// Call the next step in this workflow
    // response will be the Variables Available from this step
    Mesa.output.next(response);
  }

/**
   * Extract the variant title
   *
   * @param {string} displayName
   */
  extractVariantTitle = (displayName) => {
    // Matches text inside parentheses. Example: Extract Blue from [TESTPRODUCTBLUE] Test Product (Blue)
    const match = displayName.match(/\(([^)]+)\)/);
    // Returns the matched text or null if no match
    return match ? match[1] : null;
  }
}

Create Product Variant

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Each Odoo variant needs to exist in Shopify with its specific title, price, and SKU so customers can select and purchase the exact option they want.

Path - Has Existing Shopify Product

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: This rule handles the opposite scenario—when a product already exists in Shopify, triggering updates to that product instead of creating a duplicate.

Retrieve Product

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: You need the complete product record including all variants before updating it—this step fetches the full Shopify product data so updates can be applied accurately.

Update Shopify Product

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: When an Odoo product changes, those updates need to flow to Shopify to keep your storefront accurate—this step overwrites the Shopify product with current information from Odoo.

Path - Has 1 Odoo Variant

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Products with only one variant can be updated quickly with a single operation—this path handles the simple case where no variant matching or looping is needed.

Update Product Variant

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: The existing Shopify variant needs current pricing from Odoo so customers see accurate costs—this step updates just the price without affecting other variant properties.

Path - Has More Than 1 Odoo Variants

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Products with multiple variants need complex matching between Odoo and Shopify to update existing variants and create new ones—this path routes to the variant synchronization logic.

List Product Variants

App connector: [Odoo](/content/apps/odoo/integrate "View Odoo integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: You need the complete list of Odoo variants with all their details before you can match them to Shopify variants—this step retrieves every variant associated with the Odoo product.

Get List of Product Variants

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: You need the current Shopify variants to compare against Odoo variants—this step retrieves all existing variants so the workflow can match them by SKU and determine what needs updating.

Custom - Match Odoo to Shopify Product Variants

App connector: [Code](/content/apps/custom/integrate "View Code integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Before updating or creating variants, you need to know which Odoo variants already exist in Shopify—this code matches them by SKU and flags each Odoo variant with its corresponding Shopify ID if found.

const Mesa = require('vendor/Mesa.js');

/**
 * A MESA Script exports a class with a script() method.
 */
module.exports = new class {

// Retrieve the Variables Available to this step
    const vars = context.steps;

// For storing response
    let response = {};

// Find a matching Shopify item based on SKU
    // Add has_shopify_match and Shopify variant ID and product ID if a match is found
    let updatedOdooProductVariants = vars.odoo_2.map(odooItem => {
      let shopifyMatch = vars.shopify_7.find(shopifyItem => shopifyItem.sku === odooItem.default_code);

return {
        ...odooItem,
        has_shopify_match: shopifyMatch ? "yes" : "no",
        shopify_variant_id: shopifyMatch ? shopifyMatch.id : null,
        shopify_product_id: shopifyMatch ? shopifyMatch.product_id : null
      };
    });

// Add to response
    response.updated_odoo_product_variants = updatedOdooProductVariants;

// Call the next step in this workflow
    // response will be the Variables Available from this step
    Mesa.output.next(response);
  }
}

Loop: Get Odoo Product Variants

App connector: [Loop](/content/apps/loop/integrate "View Loop integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Each Odoo variant needs to be processed individually to either update an existing Shopify variant or create a new one—this loop handles them one at a time based on the matching data.

Path - No Shopify Match

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: When an Odoo variant doesn't exist in Shopify yet, it needs to be created as a new variant—this path handles variants that are new to your Shopify store.

Code - Extract Odoo Variant Title

App connector: [Code](/content/apps/custom/integrate "View Code integration page"/index.html)• Time to complete: 1 minute

Why this matters: Odoo stores variant names within parentheses in the display name field—this code extracts just the variant title needed for creating the new Shopify variant option.

const Mesa = require('vendor/Mesa.js');

/**
 * A MESA Script exports a class with a script() method.
 */
module.exports = new class {

// Retrieve the Variables Available to this step
    const vars = context.steps;

let response = {};
    // Get Odoo product variant
    const odooProductVariant = vars.loop_2;
    // Get display name
    let displayNameProductVariant = vars.loop_2.display_name;

// Extracting variant title
    let variantTitle = this.extractVariantTitle(displayNameProductVariant);

// Add to response
    response.variant_title = variantTitle;

// Call the next step in this workflow
    // response will be the Variables Available from this step
    Mesa.output.next(response);
  }

/**
   * Extract the variant title
   *
   * @param {string} displayName
   */
  extractVariantTitle = (displayName) => {
    const match = displayName.match(/\(([^)]+)\)/); // Matches text inside parentheses
    return match ? match[1] : null; // Returns the matched text or null if no match
  }
}

Create Product Variant

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: New Odoo variants that don't exist in Shopify yet need to be created so customers can select and purchase all available options.

Path - Has Shopify Match

App connector: [Paths](/content/apps/paths/integrate "View Paths integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: When an Odoo variant already exists in Shopify, it needs to be updated with current information rather than creating a duplicate—this path handles existing variant updates.

Code - Extract Odoo Variant Title

App connector: [Code](/content/apps/custom/integrate "View Code integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Even when updating existing variants, you need the current variant title from Odoo to make sure the Shopify variant label stays accurate—this code extracts that title.

Update Product Variant

App connector: [Shopify](/content/apps/shopify/integrate "View Shopify integration page"/index.html)• Time to complete: 0 minutes (Auto-configured)

Why this matters: Existing Shopify variants need current pricing, titles, and SKUs from Odoo to keep your storefront accurate—this step overwrites the variant with updated information from Odoo.

Frequently asked questions

What happens if I change a product title in Odoo after it's already synced?

The workflow searches Shopify by title, so if you change the product name in Odoo, it will appear as a new product and get created again in Shopify rather than updating the original. To avoid duplicates, maintain consistent product titles across systems or add a custom field to track the relationship between Odoo and Shopify product IDs.

How does the workflow handle variants with the same SKU in both systems?

The matching code uses SKU as the unique identifier to connect Odoo variants with Shopify variants. If SKUs match, the workflow updates the existing Shopify variant. If you have duplicate SKUs in either system, the matching may produce unexpected results—make sure SKUs are unique across all variants.

Can this workflow delete variants from Shopify when they're removed from Odoo?

No, the current workflow only creates and updates variants but doesn't delete them. If you remove a variant from Odoo, the corresponding Shopify variant will remain until you manually delete it.