Need a working example of grabbing post data



  • Hello. I was curious about plugin development on Nodebb and I'm relatively new to javascript.

    Could you write me a working example - so that I could learn - of how to get post topic, post sender and link to the post?

    I have a basic setup working where I can get 'hello, world' but that's the extent of it. Somehow I can't get anything useful out of the hooks.

    So could you please write me a working example (preferrably with extensive comments 😄 ) where:

    1. User writes or replies to a post and presses "send".
    2. Save name of forum user to a variable, for example 'name'.
    3. Save topic of the post to a variable, for example 'topic'.
    4. Save link to the new post to a variable, for example 'link'.

    And then I was going to do "stuff" with this information but I don't really seem to get the hang of this. I'm doing something wrong and I can't find a similar plugin anywhere from which I could learn, so...

    Help, please?


  • Community Rep

    Glad to help.

    Pretty simple to do those things. Here's a whole plugin. Put in as many comments as I could think of.

    library.js

    (function(module){
    	"use strict";
    
    	// The modules we need.
    	var User   = module.parent.require("./user");
    	var Topics = module.parent.require("./topics");
    	var nconf  = require('nconf');
    
    	var Plugin = {};
    
    	// This event is fired whenever a post is created. (reply or new topic)
    	Plugin.postSave = function (postData) {
    
    		// If you wanted to see what's inside use
    		// console.log(postData);
    
    		// Get the topic info...
    		// We only need the title and slug, so we use getTopicFields, but you could call getTopicData if you wanted all the topic fields.
    		Topics.getTopicFields(postData.tid, ['title', 'slug'], function (err, topicData) {
    
    			// If there is an error or missing data, bail out and log it.
    			if (err || !topicData.title || !topicData.slug) return console.log("Couldn't find topic data.");
    
    			// Save the data we need.
    			var topic = topicData.title;
    			var topicSlug = topicData.slug;
    			
    			// Get the user info...
    			// We only need the name, but again we could use getUserData if we wanted all fields.
    			User.getUserField(postData.uid, 'username', function (err, name) {
    
    				// If there is an error or missing data, bail out and log it.
    				if (err || !name) return console.log("Couldn't find username.");
    		
    				// Links always follow this same structure.
    				// the site url + "topic/" + the topic slug + "/" + the post id
    				var link = nconf.get('url') + "topic/" + topicSlug + "/" + postData.pid;
    
    				// Now do whatever we want with the data.
    				someCoolThing({
    					name: name,
    					topic: topic,
    					link: link
    				});
    			});
    		});
    	};
    
    	function someCoolThing(data) {
    		console.log("We get signal!!!");
    		console.log("Username: " + data.name);
    		console.log("Topic: " + data.topic);
    		console.log("Link: " + data.link);
    	}
    
    	module.exports = Plugin;
    
    }(module));
    

    Most of the nodebb modules follow the same 'get' structure.

    • getThingData() takes the Thing ID. Then returns an object with all fields.
    • getThingFields() takes the Thing ID and an array with the fields wanted. Then returns an object with the fields wanted.
    • getThingField() the Thing ID and a field name string. Then returns the field value.

    All of them return an Error object as the first parameter, which is null if no error occured.

    For completeness, here are the plugin.json and package.json:

    {
    	"id": "nodebb-plugin-test",
    	"name": "NodeBB Test",
    	"description": "Test",
    	"url": "https://github.com/yariplus/nodebb-plugin-test",
    	"library": "./library.js",
    	"hooks": [
    		{ "hook": "action:post.save", "method": "postSave" }
    	]
    }
    
    {
      "name": "nodebb-plugin-test",
      "version": "1.0.0"
    }
    

    If you have trouble with hooks:

    The 'action' hooks will typically return nothing or an object with the fields used to process that action.

    Ex.

          Plugin.someAction = function (someObject) {
               console.log(someObject);
          }
    

    The 'filter' hooks will typically return an object and a callback function. You must call the callback function or bad things happen. The callback function typically needs an Error object (or null if no error) and the sent object as it's parameters.

    Ex.

          Plugin.someFilter = function (objectToFilter, callback) {
               callback(null, objectToFilter);
          }
    


  • Thank you @yariplus, I will be sure to study this and I will try to understand what is happening here.

    My earlier approach seems to have been quite a bit off.


  • Community Rep

    Cool, let me know if you have any other questions. 🙂



  • @yariplus, I've been playing around with the code and got it working pretty well like I wanted but now I can't figure out how to get data out of getUserData().

    It gives me null, complains that user is not defined, crashes Nodebb and does all kinds of stuff depending on how I try to do it but it doesn't give me any useful data.

    I've been trying to get it working with action:user.loggedIn so I could display "user <name here> logged in" when an user logs in. And also with action:user.create so I could display something like "<name here> registered at forums" when an user registers at the forums.


  • Community Rep

    @Pilvinen Hmm, sounds like you're sending or reading the wrong parameters somewhere. If it's crashing NodeBB, you might have forgot the return statement in your if (err).

    	Plugin.loggedIn = function (uid) {
    		User.getUserData(uid, function (err, userData) {
    			if (err || !userData) return console.log("Couldn't find user: " + uid);
    
    			console.log("User '" + userData.username + "' has logged in.");
    		});
    	};
    


  • I'm pretty sure I already tried to do it like that but I must have had an error there somewhere - it's working now with your example. Thanks again for the help.



  • @yariplus,Your guide is simple but very helpful to write plugin, thanks


  • Community Rep

    @LLLRH said:

    @yariplus,Your guide is simple but very helpful to write plugin, thanks

    Thanks for your feedback! Glad to help anyone getting into NodeBB development. 🙂


  • Admin

    @yariplus said:

    @LLLRH said:

    @yariplus,Your guide is simple but very helpful to write plugin, thanks

    Thanks for your feedback! Glad to help anyone getting into NodeBB development. 🙂

    If you are interested in writing a beginners guide to plugin development, we'd be happy to feature it on our blog 🙂

    (I have to update ghost first, so that we can post it under your username)


  • Community Rep

    @psychobunny said:

    @yariplus said:

    @LLLRH said:

    @yariplus,Your guide is simple but very helpful to write plugin, thanks

    Thanks for your feedback! Glad to help anyone getting into NodeBB development. 🙂

    If you are interested in writing a beginners guide to plugin development, we'd be happy to feature it on our blog 🙂

    (I have to update ghost first, so that we can post it under your username)

    Actually, yes. That is something I've been wanting to do. I jumped into NodeBB development as a total newbie to Javascript, so I probably have a good perspective for beginners. I have some formal education in technical writing as well. 📖



  • @yariplus said:

    Actually, yes. That is something I've been wanting to do. I jumped into NodeBB development as a total newbie to Javascript, so I probably have a good perspective for beginners. I have some formal education in technical writing as well. 📖

    Please do this! 👍 We need more tutorials and technical guides. I've been trying to immerse myself more in the source and writing plugins so I can write some stuff for the community.


Log in to reply
 


Looks like your connection to NodeBB was lost, please wait while we try to reconnect.