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…
Reference in New Issue
Block a user