From 08ae33635a031cb3c96792a3dc4423b1f79f4082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=87=89=E5=87=89?= Date: Mon, 11 Mar 2019 11:02:35 +0800 Subject: [PATCH] Add: tg channel photo (#1714) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 目前只处理了非私有频道的图片(不包括图片文件)显示 - Closes #903 --- lib/routes/telegram/channel.js | 113 ++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 43 deletions(-) diff --git a/lib/routes/telegram/channel.js b/lib/routes/telegram/channel.js index bb62a5ff21..6b41e3b655 100644 --- a/lib/routes/telegram/channel.js +++ b/lib/routes/telegram/channel.js @@ -1,6 +1,7 @@ const axios = require('../../utils/axios'); const config = require('../../config'); const logger = require('../../utils/logger'); +const cheerio = require('cheerio'); let botName = ''; axios({ @@ -18,6 +19,22 @@ module.exports = async (ctx) => { const username = ctx.params.username; const cacheDays = 30; const cacheLength = 5; + const fomatPhoto = async (link) => { + const imgList = []; + const { data } = await axios.get(link + '?embed=1&single=1'); + const $ = cheerio.load(data); + + $('.tgme_widget_message_photo_wrap').each(function() { + const bg = $(this).css('background-image'); + imgList.push(bg.match(/url\('(.+)'\)/)[1]); + }); + return imgList.reduce((acc, img) => { + if (img) { + acc += ``; + } + return acc; + }, ''); + }; let response = await axios({ method: 'get', @@ -41,54 +58,64 @@ module.exports = async (ctx) => { ctx.cache.set(`RSSHubTelegramChannelName${username}`, data[0].channel_post.chat.title, cacheDays * 24 * 60 * 60); // cache post - post = data.map((item) => { - item = item.channel_post; - let text = item.text || item.caption || ''; - const media = ['photo', 'audio', 'document', 'game', 'sticker', 'video', 'voice', 'contact', 'location', 'venue']; - media.forEach((me) => { - if (item[me]) { - text += ` [${me}]`; - } - }); - - let html = text; - - if (item.entities) { - const enter = []; - item.entities.forEach((entity) => { - switch (entity.type) { - case 'text_link': - enter.push([entity.offset, ``], [entity.offset + entity.length, '']); - break; - case 'bold': - enter.push([entity.offset, ''], [entity.offset + entity.length, '']); - break; - case 'hashtag': - case 'italic': - enter.push([entity.offset, ''], [entity.offset + entity.length, '']); - break; + post = await Promise.all( + data.map(async (item) => { + item = item.channel_post; + let text = item.text || item.caption || ''; + let html = text; + const link = `https://t.me/${username}/${item.message_id}`; + const media = ['photo', 'audio', 'document', 'game', 'sticker', 'video', 'voice', 'contact', 'location', 'venue']; + // https://css-tricks.com/why-using-reduce-to-sequentially-resolve-promises-works/ + await media.reduce(async (acc, me) => { + if (item[me]) { + if (item.chat.username && me === 'photo') { + // 暂时只处理非私有频道的图片 + const photos = await fomatPhoto(link); + html += ` ${photos}`; + } + text += ` [${me}]`; } - }); - enter.sort((a, b) => a[0] - b[0]); - if (enter.length) { - html = text.slice(0, enter[0][0]); - enter.forEach((en, index) => { - if (index !== enter.length - 1) { - html += enter[index][1] + text.slice(enter[index][0], enter[index + 1][0]); - } else { - html += enter[index][1] + text.slice(enter[index][0]); + return acc; + }, Promise.resolve()); + + if (item.entities) { + const enter = []; + item.entities.forEach((entity) => { + switch (entity.type) { + case 'text_link': + enter.push([entity.offset, ``], [entity.offset + entity.length, '']); + break; + case 'bold': + enter.push([entity.offset, ''], [entity.offset + entity.length, '']); + break; + case 'hashtag': + case 'italic': + enter.push([entity.offset, ''], [entity.offset + entity.length, '']); + break; } }); + enter.sort((a, b) => a[0] - b[0]); + if (enter.length) { + html = text.slice(0, enter[0][0]); + enter.forEach((en, index) => { + if (index !== enter.length - 1) { + html += enter[index][1] + text.slice(enter[index][0], enter[index + 1][0]); + } else { + html += enter[index][1] + text.slice(enter[index][0]); + } + }); + } } - } - return { - title: text, - description: html, - pubDate: new Date(item.date * 1000).toUTCString(), - link: `https://t.me/${username}/${item.message_id}`, - }; - }); + return Promise.resolve({ + title: text, + description: html, + pubDate: new Date(item.date * 1000).toUTCString(), + link, + }); + }) + ); + if (post.length >= cacheLength) { ctx.cache.set(`RSSHubTelegramChannelPost${username}`, post.slice(0, cacheLength), cacheDays * 24 * 60 * 60); } else {