How to restore topic posters as topic followers?

Solved Technical Support
  • @juan-g Here is a one time script to get the posters of each topic and have them follow that topic. Make sure you take a backup of your database before running this as I haven't tested it on a live database. Hope it helps.

    /*globals require, console, process */
    'use strict';
    
    var nconf = require('nconf');
    var async = require('async');
    
    nconf.file({
    	file: 'config.json'
    });
    
    nconf.defaults({
    	base_dir: __dirname,
    });
    
    var db = require('./src/database');
    
    db.init(function(err) {
    	if (err) {
    		console.log("NodeBB could not connect to your database. Error: " + err.message);
    		process.exit();
    	}
    
    	followTopics(function (err) {
    		if (err) {
    			console.error(err);
    			process.exit();
    		}
    		console.log('done');
    		process.exit();
    	});
    });
    
    function followTopics(callback) {
    	db.getSortedSetRange('topics:tid', 0, -1, function (err, tids) {
    		if (err) {
    			return callback(err);
    		}
    		
    		async.eachSeries(tids, followTopicByPosters, callback);
    	});
    }
    
    function followTopicByPosters(tid, callback) {
    	db.getSortedSetRange('tid:' + tid + ':posters', 0, -1, function (err, uids) {
    		if (err) {
    			return callback(err);
    		}
    
    		if (!uids.length) {
    			return callback();
    		}
                    db.setAdd('tid:' + tid + ':followers', uids, callback);
    	});
    }
    

    You have to place this in your NodeBB root folder and run it with node myScript.js

  • @baris Wow, thank you, that's amazing. A doubt before running it. As said, the first poster of each topic is already a follower (although not the rest of posters), however I think db.setAdd will prevent duplicate uids when adding them this way, to avoid maybe duplicate notifications for the OPs. But I'm not sure. Is that so? Thanks!

  • @juan-g yes db.setAdd won't add duplicates.

  • @baris Almost there, this is really wonderful. I did, from the nodebb folder:

    ./nodebb stop
    
    mongodump -u nodebb -p [password] -d nodebb -o dump/nodebb-2018-05-03
    
    node restoreTopicFollowers.js
    

    Then verified the MongoDB database (I use Robo 3T for that), e.g.:

    db.getCollection('objects').find({_key: /:followers/})
    

    and indeed the followers had been correctly added to each topic on the database!

    So I did:

    ./nodebb start
    

    And testing NodeBB there is a final glitch: Those added followers still show "This user hasn't watched any topics yet" in their "Watched" sections. I've tried rebuilding and restarting NodeBB, and deleting browser cache, but no change there.

    Is there anything I can try for that?

  • Oh knew I forgot something, run the below to create those sets.

    /*globals require, console, process */
    'use strict';
    
    var nconf = require('nconf');
    var async = require('async');
    
    nconf.file({
    	file: 'config.json'
    });
    
    nconf.defaults({
    	base_dir: __dirname,
    });
    
    var db = require('./src/database');
    
    db.init(function(err) {
    	if (err) {
    		console.log("NodeBB could not connect to your database. Error: " + err.message);
    		process.exit();
    	}
    
    	followTopics(function (err) {
    		if (err) {
    			console.error(err);
    			process.exit();
    		}
    		console.log('done');
    		process.exit();
    	});
    });
    
    function followTopics(callback) {
    	db.getSortedSetRange('topics:tid', 0, -1, function (err, tids) {
    		if (err) {
    			return callback(err);
    		}
    
    		async.eachSeries(tids, followTopicByPosters, callback);
    	});
    }
    
    function followTopicByPosters(tid, callback) {
    	db.getSortedSetRange('tid:' + tid + ':posters', 0, -1, function (err, uids) {
    		if (err) {
    			return callback(err);
    		}
    
    		if (!uids.length) {
    			return callback();
    		}
    
    		var keys = uids.map(function (uid) {
    			return 'uid:' + uid + ':followed_tids';
    		});
    		db.sortedSetsAdd(keys, now, tid, callback);
    	});
    }
    
  • @baris It returns an error now is not defined for the line 56:

    db.sortedSetsAdd(keys, now, tid, callback);
    
  • Maybe I can try using Date.now() instead of now, but I don't know if that's right for this.

  • This is great. It works! 🎆

    So, if I'm not wrong, to fix other imported forums we should also run both scripts (restoreTopicFollowers.js and restoreTopicFollowers2.js), the second one with the minor replacement now -> Date.now()

    Really, thank you very much! 👍

  • Yes, typically when you see now used in our code there's probably a var now = Date.now(); nearby 😆

  • @juan-g Yeah you can declare now above the code with var now = Date.now()


Suggested Topics