Files
evo-sync/run/vk/send-products.sh

258 lines
11 KiB
Bash
Raw Permalink Normal View History

2026-02-02 19:52:58 +03:00
#!/usr/bin/env bash
# Rename to better reflect purpose - only applied to weight measures (г, г., грамм, etc)
WEIGHT_PRICE_MULTIPLIER=${WEIGHT_PRICE_MULTIPLIER:-10}
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
source $SCRIPT_DIR/constants.sh
source $ROOT_DIR/run/evo/constants.sh
source $SCRIPT_DIR/functions.sh
# Setup logging
setup_logging
# Trap signals to ensure proper cleanup
trap 'cleanup 1' HUP INT QUIT TERM
# Function to check if a measure is a weight measure
is_weight_measure() {
local measure="$1"
# Convert to lowercase for case-insensitive comparison
local measure_lower=$(echo "$measure" | tr '[:upper:]' '[:lower:]')
# Check for various weight measure formats
if [[ "$measure_lower" == "г" ||
"$measure_lower" == "г." ||
"$measure_lower" == "грамм" ||
"$measure_lower" == "граммов" ||
"$measure_lower" == "гр" ||
"$measure_lower" == "гр." ]]; then
return 0 # True - it is a weight measure
else
return 1 # False - it is not a weight measure
fi
}
function uploadPhoto() {
getUploadPhotoResp=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
"$VK_API_GET_PHOTO_UPLOAD_URL&group_id=$VK_API_GROUP_ID")
http_code=${getUploadPhotoResp: -3}
response_body=${getUploadPhotoResp:0:-3}
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
# Check if the first request was successful
if [[ "$http_code" != "200" ]]; then
echo "$(timestamp) [ERROR] Failed to get photo upload URL" >> "$LOG_FILE"
return 1
fi
uploadPhotoUrl=`echo $response_body | yq -pj '.response.upload_url'`
uploadPhotoObj=`curl -s -X POST --header "Content-Type: $VK_API_CONTENT_TYPE_MULTIPART" $uploadPhotoUrl -F "file=@$VK_API_PHOTO_PATH"`
uploadPhotoResp=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
-F upload_response=$uploadPhotoObj \
-F v=$VK_API_VERSION \
$VK_API_UPLOAD_PHOTO_URL)
http_code=${uploadPhotoResp: -3}
response_body=${uploadPhotoResp:0:-3}
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
# Check if the second request was successful
if [[ "$http_code" != "200" ]]; then
echo "$(timestamp) [ERROR] Failed to upload photo" >> "$LOG_FILE"
return 1
fi
# Extract and return the photo ID - update to use the correct JSON path
local photoId=$(echo "$response_body" | yq -pj '.response.photo_id')
echo "$(timestamp) [INFO] Uploaded photo with ID: $photoId" >> "$LOG_FILE"
echo $photoId
}
evoPath=$EVO_PRODUCTS_PATH/$EVO_API_STORE_ID
evoFileName=`ls $evoPath -Art | tail -1`
evoFilePath=$evoPath/$evoFileName
evoGroupsPath=$EVO_GROUPS_PATH/$EVO_API_STORE_ID
evoGroupsFileName=`ls $evoGroupsPath -Art | tail -1`
evoGroupsFilePath=$evoGroupsPath/$evoGroupsFileName
vkPath=$VK_PRODUCTS_PATH/$VK_API_GROUP_ID
vkFileName=`ls $vkPath -Art | tail -1`
vkFilePath=$vkPath/$vkFileName
vkAlbumPath=$VK_ALBUMS_PATH/$VK_API_GROUP_ID
vkAlbumFileName=`ls $vkAlbumPath -Art | tail -1`
vkAlbumFilePath=$vkAlbumPath/$vkAlbumFileName
# Load whitelist
readarray -t whitelist < "$ROOT_DIR/vk/whitelist"
readarray items < <(yq -o=j -I=0 '.items[]' $evoFilePath )
for item in "${items[@]}"; do
evoTitle=`echo $item | yq .name`
evoGroupId=`echo $item | yq .parent_id`
evoGroupName=`evoGroupId="$evoGroupId" yq -r '.items[] | select(.id==strenv(evoGroupId)) | .name' $evoGroupsFilePath`
# Check if group is whitelisted
if [[ ! " ${whitelist[@]} " =~ " ${evoGroupName} " ]]; then
continue
fi
vkAlbumId=`albumName="$evoGroupName" yq '.response.items[] | select(.title==strenv(albumName)) | .id' $vkAlbumFilePath`
name=`echo $item | yq .name | xargs`
# Replace semicolons with commas for VK API compatibility
name_for_vk="${name//;/,}"
measure=`echo $item | yq .measure_name`
# Calculate price based on measure type
base_price=$(echo $item | yq .price)
if is_weight_measure "$measure"; then
# Apply multiplier for weight measures
price=$((base_price * WEIGHT_PRICE_MULTIPLIER))
price_info="${WEIGHT_PRICE_MULTIPLIER}$measure"
else
# No multiplier for non-weight measures
price=$base_price
price_info="$measure"
fi
quantity=`echo $item | yq .quantity`
allow_to_sell=`echo $item | yq .allow_to_sell`
# Set stock amount based on allow_to_sell flag
if [[ "$allow_to_sell" = "true" ]]; then
stock_amount=$VK_STOCK_AMOUNT
else
stock_amount=0
fi
desc="$name (цена за ${price_info}.)
"
description=$(echo $item | yq '.description // ""')
if [[ -n "$description" ]]; then
desc+="$description"
fi
article=`echo $item | yq .article_number`
found=0
readarray vkItems < <(yq -o=j -I=0 '.response.items[]' $vkFilePath )
for vkItem in "${vkItems[@]}"; do
vkTitle=`echo $vkItem | yq .title`
vkTitleTrimmed="$(echo "$vkTitle" | xargs)"
evoTitleTrimmed="$(echo "$evoTitle" | xargs)"
# For comparison, transform EVO title the same way (replace ; with ,)
evoTitleForVk="${evoTitleTrimmed//;/,}"
if [[ "$vkTitleTrimmed" = "$evoTitleForVk" ]]; then
found=1
originalName=$(echo "$vkItem" | yq .title | xargs)
originalDesc=$(echo "$vkItem" | yq .description | xargs)
originalPrice=$(echo "$vkItem" | yq .price.amount)
originalPrice=$((originalPrice / 100))
originalArticle=$(echo "$vkItem" | yq .sku | xargs)
originalStockAmount=$(echo "$vkItem" | yq .stock_amount)
# Debug output to log file
echo "$(timestamp) [DEBUG] name='$name' originalName='$originalName'" >> "$LOG_FILE"
echo "$(timestamp) [DEBUG] desc='$desc' originalDesc='$originalDesc'" >> "$LOG_FILE"
echo "$(timestamp) [DEBUG] price='$price' originalPrice='$originalPrice'" >> "$LOG_FILE"
echo "$(timestamp) [DEBUG] stock_amount='$stock_amount' allow_to_sell='$allow_to_sell'" >> "$LOG_FILE"
# Normalize descriptions more carefully to maintain proper spacing
# Replace newlines with spaces first, then normalize spaces and trim
normalized_desc=$(echo "$desc" | sed 's/\n/ /g' | tr -s ' ' | xargs)
normalized_orig_desc=$(echo "$originalDesc" | sed 's/\n/ /g' | tr -s ' ' | xargs)
# Apply semicolon-to-comma transformation for consistent comparison
normalized_desc="${normalized_desc//;/,}"
normalized_orig_desc="${normalized_orig_desc//;/,}"
# Check for changes
if [[ "$(echo "$name_for_vk" | xargs)" != "$originalName" ]]; then
name_changed="true"
else
name_changed="false"
fi
if [[ "$price" != "$originalPrice" ]]; then
price_changed="true"
else
price_changed="false"
fi
if [[ "$normalized_desc" != "$normalized_orig_desc" ]]; then
desc_changed="true"
else
desc_changed="false"
fi
if [[ "$stock_amount" != "$originalStockAmount" ]]; then
stock_changed="true"
else
stock_changed="false"
fi
# Check if update is needed
if [[ "$name_changed" == "true" || "$price_changed" == "true" || "$desc_changed" == "true" || "$stock_changed" == "true" ]]; then
productId=$(echo "$vkItem" | yq .id)
echo "$(timestamp) [REQUEST] Updating product: $name_for_vk (name_changed=$name_changed, price_changed=$price_changed, desc_changed=$desc_changed, stock_changed=$stock_changed)" >> "$LOG_FILE"
response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
-F owner_id="$VK_API_PARAM_OWNER_ID" \
-F item_id=$productId \
-F name="$name_for_vk" \
-F description="$normalized_desc" \
-F category_id=$VK_API_CATEGORY_ID \
-F price="$price" \
-F stock_amount="$stock_amount" \
$VK_API_EDIT_PRODUCT)
http_code=${response: -3}
response_body=${response:0:-3}
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
fi
fi
done
if [[ "$found" = 0 ]] && [[ "$allow_to_sell" = "true" ]] ; then
photoId=$(uploadPhoto)
# Check if photo upload was successful
if [[ -z "$photoId" || "$photoId" == "null" ]]; then
echo "$(timestamp) [ERROR] Failed to get valid photo ID, skipping product: $name" >> "$LOG_FILE"
continue
fi
echo "$(timestamp) [REQUEST] Creating product: $name_for_vk" >> "$LOG_FILE"
response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
-F owner_id=$VK_API_PARAM_OWNER_ID \
-F name="$name_for_vk" \
-F description="$desc" \
-F category_id=$VK_API_CATEGORY_ID \
-F price=$price \
-F main_photo_id=$photoId \
-F stock_amount="$stock_amount" \
$VK_API_ADD_PRODUCT)
http_code=${response: -3}
response_body=${response:0:-3}
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
# Check if product creation was successful
if [[ "$http_code" != "200" ]] || [[ $(echo $response_body | grep -c "error") -gt 0 ]]; then
echo "$(timestamp) [ERROR] Failed to create product: $name" >> "$LOG_FILE"
continue
fi
productId=$(echo $response_body | yq .response.market_item_id)
# Only proceed if we got a valid product ID
if [[ -n "$productId" && "$productId" != "null" ]]; then
resp=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
"$VK_API_ADD_PRODUCT_TO_ALBUM&owner_id=$VK_API_PARAM_OWNER_ID&item_ids=$productId&album_ids=$vkAlbumId")
http_code=${resp: -3}
response_body=${resp:0:-3}
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
else
echo "$(timestamp) [ERROR] Invalid product ID, skipping album addition for: $name" >> "$LOG_FILE"
fi
fi
done
# Use the cleanup function instead of directly exiting
cleanup 0