[Nodejs] FB Page post comment/reply event engine

岩岩寫左隻FB Page post comment/reply event engine既Nodejs module。

個module目的係幫FB page owner去mon住個FB page係咪有新comment,然後generate event & 俾個位d人自己去寫callback logic。

實際做法就係佢背底會行個schedule job去call FB graph API黎check post既new comments。

NodeJS module for keep track Facebook Page Posts New Comments

NodeJS module “fb-page-comment-event”

This module can keep track your Facebook page posts’ first level comment events. Hence, if someone commented on your post, you will be notified by an event.

This module support running an event-engine which would manage a background schedule job to check new comment and generating events. This module also support raw APIs which you can check new comments and digest as events by yourself via APIs.


Related Pages

Github page: https://github.com/airicyu/fb-page-comment-event
NPM: https://www.npmjs.com/package/fb-page-comment-event



This module can keep track your Facebook page posts’ first level comment events. Hence, if someone commented on your post, you will be notified by an event.

This module support running an event-engine which would manage a background schedule job to check new comment and generating events. This module also support raw APIs which you can check new comments and digest as events by yourself via APIs.

Running the event engine

You may use the lib.pageCommentEventApp(options) API to get a event engine app and then start it with run function. This event engine app would manage a schedule job to auto pull data.


  • Remarks: pageId is the facebook page ID. postId is the facebook page post ID of post which you want to monitor its comment. accessToken is the Facebook page access token(remember to use the long live token) which Facebook page owner can generate in developer dashboard.

Sample console log output:

(DIY) Use the APIs to check new comments and generating events


event engine APIs

let app = lib.pageCommentEventApp({accessToken, pullInterval})


Initializing the event engine app.


  • accessToken: The required accessToken(need permission manage_pages) for the API calls.
  • pullInterval: The sleep time(ms) interval between each scheduled page post new comment checking.


The event engine app.

app.registerMonitorPost({pageId, postId})


Registering a page post which the event engine would tracking for new comments


  • pageId: The page ID.
  • postId: The post ID.



Start running the event engine and register the new-comment-events callback. Once users write new comments, new-comment-events would be fired and handled by the callback.


  • eventsCallback: The batch new-comment-events handling function.



Stop the event engine


let queryPostCommentAgent = lib.api.getQueryPostCommentAgent(options)


Initialize a agent for query post comments.


  • options: object with attribute accessToken which holding the required accessToken(need permission manage_pages) for the API calls.


The agent object.

let postCommentFetcher = lib.api.getPostCommentFetcher(queryPostCommentAgent)


Initialize a fetcher for fetching new post comment.


  • queryPostCommentAgent: The agent object which come from lib.api.getQueryPostCommentAgent(options)


The fetcher object.

let postCommentObj = await postCommentFetcher.fetch(postObjId, since)


Use the fetcher object to fetch post object with comments. We can use this API to get all new comments under the target post which those comments are created since the since time.


  • postObjId: The post object ID which is in format of ${pageId}_${postId} in Facebook Graph API.
  • since: The timestamp in second


The post object with comments (All comments child objects are new comments).

let postDigestor = lib.api.getPostDigestor();


Getting a digestor object which can turn the post-comment object from postCommentFetcher.fetch() result into new-comment-events.


The digestor object.

let newCommentEvents = await postDigestor.digest(postWithNewComments)


Use the digestor object to digest post-comment object into new-comment-events


  • postWithNewComments: The post object with attaching new comments.


New comment event objects

stateful-result – nodejs module for represent operation result with status code

Nodejs stateful-result module

This module can be used for representing an operation(e.g: function return) result with a meaningful status code. By default, we suggest to make use of HTTP status code. Hence, code 200 for status of operation OK, and code 404 for status of operation target not found, etc.


Github: https://github.com/airicyu/stateful-result
NPM: https://www.npmjs.com/package/stateful-result


Sample 1: Getting success result (code 200 OK)

console output


Simple enough, isn’t it?

Sample 2: Getting fail result (code 404 Not found)

console output

Description: The error object is an extended error object which has the “code” attribute. In this case, the code is 404.

Sample 3: Get result if success result or throw error if returning fail result (code 404 Not found)

console output

Description: This time we called method “getOrThrow”. If the result is success, the result would be returned as previous samples. If the result is fail, the error object would be thrown.

fortel-codex.js – 中國術數基本codex (陰陽/五行/天干/地支)

Project info

Project code: fortel-codex
Type: node.js module
Version: 0.01
Last update date: 2017-03-23



A Node.js Library for Chinese Astrology Common Codex. (中國術數基本codex)


I am planning to write a bundle of node.js modules which are related to Chinese Astrology/Divination, including 紫微斗數, 八字, 九宮飛星 ……
And I find that most of Chinese Astrology/Divination system actually sharing some common codex.
So I write this common module to represent the common codex, including 陰陽, 五行, 天干, 地支, 時辰, 生肖, 氣節, 農曆 etc



Github: https://github.com/airicyu/fortel-codex
NPM: https://www.npmjs.com/package/fortel-codex


Dev Log

  • 2017-03-23: v0.0.1
    • Support features:
      • basic codex for 陰陽, 五行, 天干, 地支, 時辰, 生肖
    • Pending to do:
      • include 氣節, 農曆
      • implement some more utility functions (e.g: check生肖by year)
      • Update API document

Java及Node.js對dependency module的不同管理方式

自己有玩過Java又玩過Node.js,兩者對於library dependency是頗不同的做法,這篇文是想講講兩者的分別。


Java,多數是用maven or gradle來做library dependency management。
而我作為一個application developer,常常遇到一個問題:
但有時version conflict會出問題。

在Java裡面,不同library大多都是直接把class load到同一個class loader來用,所以不能存在multiple version的class。
很多時一些針對某些library來做的動作,都是直接hack/inject logic到那些class。

這樣把library都放在global空間好處就是,如果我是身為framework developer,這會較方便我去做middleware library,因為我可以直接掌控不同library。
而壞處就是,global空間如果library都各自有dependency,就很難統一manage,所以當library upgrade時就會較多問題/較痛苦。


另一方面,Node.js的dependency management是另一種做法。
如果你用上module A與module B而它們分別depends on module C的不同version,
那麼module A會在其下depends on它需要的module C的某version,
而module B會在其下depends on它需要的module C的另一個version。


因為module順手沾來就能用,較少機會會有module version conflict的問題。

不過Node.js這樣的design的short side是,假如我是framework developer,我就較難去建構middleware library。
我不是說你不能做middleware(express.js的那種),我是指你很難去針對其他library來作出一套全面掌控的framework library。
但express是較為多人adopt的web framework,而它本身也沒有很aggressive地去inject logic到其他library之上。

所以寫Node.js的話,如果你是app developer,你固然能把你到手的library都hack掉來for your usage。
但如果你是作為framework developer,你的心態就可能要調整一下,不要用寫java framework的心態及思維去做這件事。

Nodejs v7.6.0 release would support async/await

Node.js v7.6.0 is just released

Node.js v7.6.0 release change log: node/CHANGELOG_V7.md at master · nodejs/node · GitHub

One of the shining change is that this release contains V8 engine 5.5.
V8 engine is the javascript engine which node.js is underlining using. With V8 engine 5.5, it would support async/await features. ( V8 JavaScript Engine: V8 Release 5.5 )

Async programming – Promise/async & await

In Javascript/node.js, there are multiple ways to dual with async programming.
With ES2016, people can use Promise syntax.
And with ES2017, people can use async/await syntax.

Promise style async programming:

Equivalent async/await style async programming:

Why async/await is better than Promise?

There are multiple advantages:

  • The async/awwait style is much cleaner with less coding block/scopes. Promise would wrap the codes in difference function scopes.
  • We can use try catch to catch errors for sync/async codes.
  • Less lines. The general coding style of most people usually need several lines to write a wrapping function.




Node.js actually support async/await since v7, but it is locked in harmony flag until v7.6.0.

ahp.js – nodejs module for Analytic Hierarchy Process (AHP)

AHP node.js module

Recently I wrote a node.js library for AHP.

If you do not know what is AHP, you may see a brief AHP intro post I wrote. Basically it is a methodology to help decision making scenario which we have to evaluate several choices against multiple criteria.

Example problem:

Github: https://github.com/airicyu/ahp
NPM: https://www.npmjs.com/package/ahp

Sample code:


Console output:


The overall rank score(higher is better) of the choices are:
VendorA: 0.3652
VendorB: 0.2852
VendorC: 0.3495
Hence, “VendorA” is preferred in overall ranking.