first
This commit is contained in:
		
						commit
						d28b93fecc
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					node_modules
 | 
				
			||||||
							
								
								
									
										7
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					FROM node:8-alpine
 | 
				
			||||||
 | 
					WORKDIR /data
 | 
				
			||||||
 | 
					COPY . .
 | 
				
			||||||
 | 
					RUN apk add --no-cache curl vim ca-certificates \
 | 
				
			||||||
 | 
					  && npm install
 | 
				
			||||||
 | 
					EXPOSE 3000
 | 
				
			||||||
 | 
					CMD ["npm", "start"]
 | 
				
			||||||
							
								
								
									
										118
									
								
								facebook-parser.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								facebook-parser.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,118 @@
 | 
				
			|||||||
 | 
					const request = require('request')
 | 
				
			||||||
 | 
					const cheerio = require('cheerio')
 | 
				
			||||||
 | 
					const qs = require('querystring')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @typedef lastPost
 | 
				
			||||||
 | 
					 * @prop {string} txt post body
 | 
				
			||||||
 | 
					 * @prop {string} id post id
 | 
				
			||||||
 | 
					 * @prop {string} link post link
 | 
				
			||||||
 | 
					 * @prop {string} time timestamp
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * get facebook fan page last post
 | 
				
			||||||
 | 
					 * @param {string} pageid facebook fan page id
 | 
				
			||||||
 | 
					 * @return {Promise<lastPost>}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const getLastPost = async (pageid = '') => {
 | 
				
			||||||
 | 
					  if (typeof pageid !== 'string' || pageid.trim().length === 0) return null
 | 
				
			||||||
 | 
					  pageid = pageid.trim()
 | 
				
			||||||
 | 
					  // console.log('access facebook fan page :::: ' + pageid)
 | 
				
			||||||
 | 
					  let page = await new Promise((resolve) => {
 | 
				
			||||||
 | 
					    request({
 | 
				
			||||||
 | 
					      baseUrl: 'https://www.facebook.com',
 | 
				
			||||||
 | 
					      url: `/${encodeURIComponent(pageid)}/posts`,
 | 
				
			||||||
 | 
					      method: 'get',
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0'
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }, (err, res, body) => {
 | 
				
			||||||
 | 
					      if (err) {
 | 
				
			||||||
 | 
					        resolve(null)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (body && typeof body !== 'string' && !(body instanceof String)) {
 | 
				
			||||||
 | 
					        resolve(null)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      resolve(body)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  if (page === null) return null
 | 
				
			||||||
 | 
					  console.log(`${pageid} page length :::: `, Buffer.from(page).length)
 | 
				
			||||||
 | 
					  let $ = cheerio.load(page, {
 | 
				
			||||||
 | 
					    lowerCaseTags: true,
 | 
				
			||||||
 | 
					    lowerCaseAttributeNames: true
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let posts = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $('div.userContentWrapper').each((i, el) => {
 | 
				
			||||||
 | 
					    let t = cheerio.load(el)
 | 
				
			||||||
 | 
					    let timeEl = t('abbr')
 | 
				
			||||||
 | 
					    let time = timeEl.attr('data-utime')
 | 
				
			||||||
 | 
					    let link = timeEl.parent().attr('href')
 | 
				
			||||||
 | 
					    let p = t('div.userContent')
 | 
				
			||||||
 | 
					    let txt = p.text() || ''
 | 
				
			||||||
 | 
					    let id = p.first().attr('id')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!id) {
 | 
				
			||||||
 | 
					      if (/[\?|&]id\=(\d+)/.test(link)) { // eslint-disable-line
 | 
				
			||||||
 | 
					        let m = link.match(/[\?|&]story_fbid\=(\d+)/) // eslint-disable-line
 | 
				
			||||||
 | 
					        if (m !== null && m.length > 1) {
 | 
				
			||||||
 | 
					          id = m[1]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else if (/\/posts\/(\d+)/.test(link)) {
 | 
				
			||||||
 | 
					        let m = link.match(/\/posts\/(\d+)/)
 | 
				
			||||||
 | 
					        if (m !== null && m.length > 1) {
 | 
				
			||||||
 | 
					          id = m[1]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else if (/\/photos\/.+?\/(\d+)/.test(link)) {
 | 
				
			||||||
 | 
					        let m = link.match(/\/photos\/.+?\/(\d+)/)
 | 
				
			||||||
 | 
					        if (m !== null && m.length > 1) {
 | 
				
			||||||
 | 
					          id = m[1]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else if (/\/videos\/(\d+)/.test(link)) {
 | 
				
			||||||
 | 
					        let m = link.match(/\/videos\/(\d+)/)
 | 
				
			||||||
 | 
					        if (m !== null && m.length > 1) {
 | 
				
			||||||
 | 
					          id = m[1]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // console.log(time, link, txt, id)
 | 
				
			||||||
 | 
					    if (!time || !link || !id) return null
 | 
				
			||||||
 | 
					    let tmp = {
 | 
				
			||||||
 | 
					      txt,
 | 
				
			||||||
 | 
					      id,
 | 
				
			||||||
 | 
					      link,
 | 
				
			||||||
 | 
					      time
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // tmp.link = tmp.link.split('?')[0]
 | 
				
			||||||
 | 
					    posts.push(tmp)
 | 
				
			||||||
 | 
					    el = null
 | 
				
			||||||
 | 
					    t = null
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  $ = null
 | 
				
			||||||
 | 
					  if (posts.length === 0) return null
 | 
				
			||||||
 | 
					  posts.sort((a, b) => {
 | 
				
			||||||
 | 
					    return b.time - a.time
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					  let post = posts[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let larr = post.link.split('?')
 | 
				
			||||||
 | 
					  let linkqs = qs.parse(larr[1])
 | 
				
			||||||
 | 
					  let newqs = {}
 | 
				
			||||||
 | 
					  for (let i in linkqs) {
 | 
				
			||||||
 | 
					    if (/id/i.test(i)) {
 | 
				
			||||||
 | 
					      newqs[i] = linkqs[i]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  post.link = larr[0] + '?' + qs.stringify(newqs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  post.link = `https://www.facebook.com/${post.link.replace(/^\//, '')}`.replace(/\?$/, '')
 | 
				
			||||||
 | 
					  return post
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
					  getLastPost
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2695
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2695
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "node-fblook-serv",
 | 
				
			||||||
 | 
					  "version": "1.0.0",
 | 
				
			||||||
 | 
					  "description": "",
 | 
				
			||||||
 | 
					  "main": "index.js",
 | 
				
			||||||
 | 
					  "scripts": {
 | 
				
			||||||
 | 
					    "start": "node index.js",
 | 
				
			||||||
 | 
					    "test": "echo \"Error: no test specified\" && exit 1"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "keywords": [],
 | 
				
			||||||
 | 
					  "author": "",
 | 
				
			||||||
 | 
					  "license": "ISC",
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "axios": "^0.18.0",
 | 
				
			||||||
 | 
					    "cheerio": "^1.0.0-rc.2",
 | 
				
			||||||
 | 
					    "koa": "^2.5.3",
 | 
				
			||||||
 | 
					    "koa-body": "^4.0.4",
 | 
				
			||||||
 | 
					    "koa-logger": "^3.2.0",
 | 
				
			||||||
 | 
					    "koa-router": "^7.4.0",
 | 
				
			||||||
 | 
					    "request": "^2.88.0"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "standard": "^12.0.1"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					const Koa = require('koa')
 | 
				
			||||||
 | 
					const Router = require('koa-router')
 | 
				
			||||||
 | 
					const koaLogger = require('koa-logger')
 | 
				
			||||||
 | 
					const fbparser = require('./facebook-parser')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const verifyKey = process.env.API_KEY || 'mtfos'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const app = new Koa()
 | 
				
			||||||
 | 
					const server = app.listen(3000, () => {
 | 
				
			||||||
 | 
					  console.log(`server start on port ${server.address().port}`)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const rootRouter = new Router()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use(koaLogger())
 | 
				
			||||||
 | 
					app.use(rootRouter.allowedMethods())
 | 
				
			||||||
 | 
					app.use(rootRouter.routes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rootRouter.get('/getpost', async (c, n) => {
 | 
				
			||||||
 | 
					  let key = c.get('x-mtfos-key')
 | 
				
			||||||
 | 
					  if (key !== verifyKey) c.throw(403, 'verify key not match')
 | 
				
			||||||
 | 
					  let fbid = c.query.fbpage || ''
 | 
				
			||||||
 | 
					  if (typeof fbid !== 'string' || fbid.trim().length === 0) c.throw(400, 'facebook page id format error')
 | 
				
			||||||
 | 
					  fbid = decodeURIComponent(fbid.trim())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let postData = await fbparser.getLastPost(fbid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let resData = {}
 | 
				
			||||||
 | 
					  if (postData !== null) {
 | 
				
			||||||
 | 
					    resData.page = fbid
 | 
				
			||||||
 | 
					    resData.postid = postData.id
 | 
				
			||||||
 | 
					    resData.text = postData.txt
 | 
				
			||||||
 | 
					    resData.time = postData.time
 | 
				
			||||||
 | 
					    resData.link = postData.link
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  c.body = {
 | 
				
			||||||
 | 
					    post: resData
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = server
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user