Skip to content

Commit

Permalink
Added Google merchant product feed
Browse files Browse the repository at this point in the history
  • Loading branch information
mrvautin committed Sep 27, 2020
1 parent 2b9a0f1 commit b65ebd8
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public/uploads
.vscode
**.DS_Store
env.yaml
ecosystem.config.js
ecosystem.config.js
bin/googleproducts.xml
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,18 @@ You may want to create a static page to show contact details, about us, shipping

New static pages are setup via `/admin/settings/pages`.

## Google data

By default the product data is updated into a Google feed format here: `/googleproducts.xml`.

You can setup Google to read this data [here](https://merchants.google.com/)

1. Products > Feeds > (+)
2. Set the Country and language
3. Set A name and `Scheduled fetch`
4. Set the url to `https://mydomain.com/googleproducts.xml`
5. Complete

## TODO

- Modernize the frontend of the admin
Expand Down
8 changes: 8 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const { getConfig, getPaymentConfig, updateConfigLocal } = require('./lib/config
const { runIndexing } = require('./lib/indexing');
const { addSchemas } = require('./lib/schema');
const { initDb, getDbUri } = require('./lib/db');
const { writeGoogleData } = require('./lib/googledata');
let handlebars = require('express-handlebars');
const i18n = require('i18n');

Expand Down Expand Up @@ -481,6 +482,13 @@ initDb(config.databaseConnectionString, async (err, db) => {
});
});

await writeGoogleData(db);

// Fire up the cron job to create google product feed
cron.schedule('0 * * * *', async () => {
await writeGoogleData(db);
});

// Set trackStock for testing
if(process.env.NODE_ENV === 'test'){
config.trackStock = true;
Expand Down
1 change: 1 addition & 0 deletions config/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"injectJs": "",
"customCss": "",
"currencySymbol": "£",
"currencyISO": "USD",
"paymentGateway": [
"stripe"
],
Expand Down
67 changes: 67 additions & 0 deletions lib/googledata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const convert = require('xml-js');
const {
getConfig
} = require('./config');

const writeGoogleData = async (db) => {
const config = getConfig();
const fileName = path.join('bin', 'googleproducts.xml');

// Remove old file
try{
fs.unlinkSync(fileName);
}catch(ex){}

console.log('config', config);

// Get products
const products = await db.products.find({ productPublished: true }).toArray();

// Setup the XML
const xmlOpt = { compact: true, ignoreComment: true, spaces: 4 };
const jsonObj = {
_declaration: { _attributes: { version: '1.0', encoding: 'utf-8' } },
rss: {
_attributes: {
'xmlns:g': 'http://base.google.com/ns/1.0',
version: '2.0'
},
channel: {
title: config.cartTitle,
description: config.cartDescription,
link: config.baseUrl,
item: []
}
}
};

// Add products
_.forEach(products, (product) => {
const item = {
'g:title': product.productTitle,
'g:id': product._id.toString(),
'g:link': `${config.baseUrl}/product/${product.productPermalink}`,
'g:description': product.productDescription,
'g:price': `${product.productPrice} ${config.currencyISO}`,
'g:availability': 'in stock'
};
// Add image if exists
if(product.productImage){
item['g:image_link'] = `${config.baseUrl}/${product.productImage}`;
}
jsonObj.rss.channel.item.push(item);
});

// Generate XML
const xml = convert.js2xml(jsonObj, xmlOpt);

// Write product file
fs.writeFileSync(fileName, xml);
};

module.exports = {
writeGoogleData
};
15 changes: 14 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"strip-bom": "^3.0.0",
"stripe": "^7.12.0",
"uglifycss": "0.0.27",
"xml-js": "^1.6.11",
"yenv": "^2.1.1"
},
"devDependencies": {
Expand Down
14 changes: 14 additions & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const router = express.Router();
const colors = require('colors');
const stripHtml = require('string-strip-html');
const moment = require('moment');
const fs = require('fs');
const path = require('path');
const _ = require('lodash');
const {
getId,
Expand Down Expand Up @@ -30,6 +32,18 @@ const {
} = require('../lib/menu');
const countryList = getCountryList();

// Google products
router.get('/googleproducts.xml', async (req, res, next) => {
let productsFile = '';
try{
productsFile = fs.readFileSync(path.join('bin', 'googleproducts.xml'));
}catch(ex){
console.log('Google products file not found');
}
res.type('text/plain');
res.send(productsFile);
});

// These is the customer facing routes
router.get('/payment/:orderId', async (req, res, next) => {
const db = req.app.db;
Expand Down

0 comments on commit b65ebd8

Please sign in to comment.