Skip to content

Instantly share code, notes, and snippets.

@pacotole
Last active July 30, 2026 10:27
Show Gist options
  • Select an option

  • Save pacotole/a71afd4878b61516cd6a94ee5bf5b4f4 to your computer and use it in GitHub Desktop.

Select an option

Save pacotole/a71afd4878b61516cd6a94ee5bf5b4f4 to your computer and use it in GitHub Desktop.
Joinchat AI integration with WooCommerce provide product info in markdown to knowlegde base
<?php
/**
* Plugin Name: JoinChat AI - WooCommerce Product Enhancement
* Description: Enhances WooCommerce product content for AI knowledge base
* Version: 1.0.0
* Author: Joinchat
* Author URI: https://join.chat/
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Adds structured WooCommerce product information to content for AI
*/
class JoinChatAI_WooCommerce_Enhancement
{
private $current_sync_post_id = null;
public function __construct()
{
// Add product to AI knowledge base CPTs
add_filter('joinchat_ai_cpts', [$this, 'add_product_post_type']);
// Capture post_id from action hook with high priority
add_action('joinchat_schedule_ai_update_post', [$this, 'capture_post_id'], 1);
// Modify content when in KB sync context - low priority to receive filtered content
add_filter('the_content', [$this, 'enhance_product_content'], 999);
}
/**
* Capture post_id from action hook
*
* @param int $post_id The post ID to sync
*/
public function capture_post_id($post_id)
{
$this->current_sync_post_id = $post_id;
}
/**
* Add 'product' to post types for knowledge base
*
* @param array $post_types Current post types
* @return array Modified post types
*/
public function add_product_post_type($post_types)
{
if (!in_array('product', $post_types, true)) {
$post_types[] = 'product';
}
return $post_types;
}
/**
* Enhance WooCommerce product content with structured information
*
* @param string $content The post content
* @return string The enhanced content
*/
public function enhance_product_content($content)
{
$post_id = $this->current_sync_post_id;
// Verify we have a valid post_id
if (!$post_id) {
return $content;
}
// Verify WooCommerce is active and this is a product
if (!function_exists('wc_get_product') || get_post_type($post_id) !== 'product') {
return $content;
}
$product = wc_get_product($post_id);
if (!$product) {
return $content;
}
// Build AI-optimized markdown
$enhanced_content = $this->build_product_markdown($product, $post_id);
// Add original content after structured markdown
return $enhanced_content . "\n" . $content;
}
/**
* Build structured markdown for product
*
* @param WC_Product $product The WooCommerce product
* @param int $post_id The post ID
* @return string The generated markdown
*/
private function build_product_markdown($product, $post_id)
{
$markdown = [];
$product_name = $product->get_name();
$product_url = get_permalink($post_id);
$currency_symbol = get_woocommerce_currency_symbol();
// Product header with link
$markdown[] = "";
$markdown[] = "# {$product_name}";
$markdown[] = "";
$markdown[] = "**Product URL**: {$product_url}";
$markdown[] = "";
// Build product introduction sentence
$intro_parts = [];
// Get categories
$categories = wp_get_post_terms($post_id, 'product_cat', ['fields' => 'names']);
if (!empty($categories) && !is_wp_error($categories)) {
$intro_parts[] = implode(' and ', $categories);
}
// Get brand
$brand = $this->get_product_brand($post_id);
if ($brand) {
$intro_parts[] = "from {$brand}";
}
// Get SKU
if ($product->get_sku()) {
$intro_parts[] = "(SKU: " . $product->get_sku() . ")";
}
if (!empty($intro_parts)) {
$markdown[] = "This is a " . implode(' ', $intro_parts) . " product.";
$markdown[] = "";
}
// Product image - placed early for visibility
$image_url = get_the_post_thumbnail_url($post_id, 'large');
if ($image_url) {
$markdown[] = "![{$product_name}]({$image_url})";
$markdown[] = "";
}
// Short description if available
$short_description = $product->get_short_description();
if ($short_description) {
$short_description = wp_strip_all_tags($short_description);
$short_description = trim($short_description);
if ($short_description) {
$markdown[] = $short_description;
$markdown[] = "";
}
}
// Pricing section - conversational format
$markdown[] = "## PRICING AND AVAILABILITY";
$markdown[] = "";
$is_variable = $product->is_type('variable');
$pricing_text = $this->format_pricing_text($product, $currency_symbol, $is_variable);
$markdown[] = $pricing_text;
$markdown[] = "";
// Stock status
$stock_status = $product->get_stock_status();
if ($stock_status === 'instock') {
$stock_text = "✅ **Currently in stock**";
if ($product->managing_stock() && $product->get_stock_quantity() !== null) {
$quantity = $product->get_stock_quantity();
$stock_text .= " ({$quantity} units available)";
}
$markdown[] = $stock_text;
// Add direct "Add to cart" link for simple products
if (!$is_variable && $product->is_purchasable()) {
$add_to_cart_url = add_query_arg('add-to-cart', $post_id, wc_get_cart_url());
$markdown[] = "";
$markdown[] = "🛒 **[Add to cart]({$add_to_cart_url})**";
}
} else {
$markdown[] = "❌ **Currently out of stock**";
}
$markdown[] = "";
// Product attributes and variations
$attributes = $product->get_attributes();
if (!empty($attributes)) {
$markdown[] = "## PRODUCT OPTIONS";
$markdown[] = "";
$attribute_lines = [];
foreach ($attributes as $attribute) {
if ($attribute->get_visible()) {
$name = wc_attribute_label($attribute->get_name());
$values = [];
if ($attribute->is_taxonomy()) {
$terms = wp_get_post_terms($post_id, $attribute->get_name(), ['fields' => 'names']);
if (!is_wp_error($terms)) {
$values = $terms;
}
} else {
$values = $attribute->get_options();
}
if (!empty($values)) {
$attribute_lines[] = "**{$name}**: " . implode(', ', $values);
}
}
}
if (!empty($attribute_lines)) {
$markdown[] = implode(" \n", $attribute_lines);
$markdown[] = "";
}
}
// Product tags
$tags = wp_get_post_terms($post_id, 'product_tag', ['fields' => 'names']);
if (!empty($tags) && !is_wp_error($tags)) {
$markdown[] = "**Tags**: " . implode(', ', $tags);
$markdown[] = "";
}
$markdown[] = "---";
$markdown[] = "";
return implode("\n", $markdown);
}
/**
* Get product brand from common taxonomies
*
* @param int $post_id The post ID
* @return string|null The brand name or null
*/
private function get_product_brand($post_id)
{
$brand_taxonomies = ['product_brand', 'pwb-brand', 'yith_product_brand', 'brand'];
foreach ($brand_taxonomies as $taxonomy) {
if (taxonomy_exists($taxonomy)) {
$brands = wp_get_post_terms($post_id, $taxonomy, ['fields' => 'names']);
if (!empty($brands) && !is_wp_error($brands)) {
return implode(', ', $brands);
}
}
}
return null;
}
/**
* Format pricing text in conversational style
*
* @param WC_Product $product The product
* @param string $currency_symbol Currency symbol
* @param bool $is_variable Whether product is variable
* @return string Formatted pricing text
*/
private function format_pricing_text($product, $currency_symbol, $is_variable)
{
if ($is_variable) {
$min_regular = $product->get_variation_regular_price('min');
$max_regular = $product->get_variation_regular_price('max');
$min_sale = $product->get_variation_sale_price('min');
$max_sale = $product->get_variation_sale_price('max');
if ($product->is_on_sale()) {
$price_range = $min_sale === $max_sale
? "{$currency_symbol}{$min_sale}"
: "{$currency_symbol}{$min_sale} - {$currency_symbol}{$max_sale}";
$regular_range = $min_regular === $max_regular
? "{$currency_symbol}{$min_regular}"
: "{$currency_symbol}{$min_regular} - {$currency_symbol}{$max_regular}";
$discount = round((($max_regular - $min_sale) / $max_regular) * 100);
return "🏷️ **ON SALE** - Price: **{$price_range}** (Regular price: {$regular_range}, save up to {$discount}%)";
} else {
$price_range = $min_regular === $max_regular
? "{$currency_symbol}{$min_regular}"
: "{$currency_symbol}{$min_regular} - {$currency_symbol}{$max_regular}";
return "Price: **{$price_range}**";
}
} else {
// Simple product
if ($product->is_on_sale()) {
$regular = $product->get_regular_price();
$sale = $product->get_sale_price();
$discount = round((($regular - $sale) / $regular) * 100);
return "🏷️ **ON SALE** - Price: **{$currency_symbol}{$sale}** (Regular price: {$currency_symbol}{$regular}, save {$discount}%)";
} else {
$price = $product->get_regular_price();
return "Price: **{$currency_symbol}{$price}**";
}
}
}
}
// Initialize the enhancement
new JoinChatAI_WooCommerce_Enhancement();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment