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