diff --git a/package.json b/package.json index 73ea3d1930ef1b1b73712fa5b17dc7e7083ffb4a..d0192a9fd81dd743d2e11faa4acc79c477082de5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wechaty", - "version": "0.29.9", + "version": "0.29.11", "description": "Wechaty is a Bot SDK for Wechat Personal Account", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -87,6 +87,7 @@ "in-gfw": "^1.2.0", "memory-card": "^0.6.9", "npm-programmatic": "0.0.12", + "open-graph": "^0.2.4", "opencollective": "^1.0.3", "opencollective-postinstall": "^2.0.2", "pkg-dir": "^4.0.0", @@ -115,6 +116,7 @@ "@types/glob": "^5.0.0p", "@types/mime": "^2.0.0", "@types/node": "^12.12.3", + "@types/open-graph": "^0.2.0", "@types/promise-retry": "^1.1.3", "@types/qr-image": "^3.2.1", "@types/raven": "^2.1.0", diff --git a/src/helper-functions/impure/open-graph.ts b/src/helper-functions/impure/open-graph.ts new file mode 100644 index 0000000000000000000000000000000000000000..4e92824161d179c38dc4919980a8e00ee93651fa --- /dev/null +++ b/src/helper-functions/impure/open-graph.ts @@ -0,0 +1,13 @@ +import og from 'open-graph' + +export async function openGraph (url: string): Promise { + return new Promise((resolve, reject) => { + og(url, (err, meta) => { + if (err) { + reject(err) + } else { + resolve(meta) + } + }) + }) +} diff --git a/src/user/url-link.ts b/src/user/url-link.ts index a326b1b2ae0970b04f137ed34c398d2c570706fd..f132847521889810ae3d053a116c0bfd1a00391e 100644 --- a/src/user/url-link.ts +++ b/src/user/url-link.ts @@ -1,3 +1,5 @@ +import Url from 'url' + import { UrlLinkPayload, } from 'wechaty-puppet' @@ -6,6 +8,10 @@ import { log, } from '../config' +import { + openGraph, +} from '../helper-functions/impure/open-graph' + export class UrlLink { /** @@ -16,11 +22,51 @@ export class UrlLink { public static async create (url: string): Promise { log.verbose('UrlLink', 'create(%s)', url) - // TODO: get title/description/thumbnailUrl from url automatically + const meta = await openGraph(url) + + let description: string | undefined + let imageUrl: string | undefined + let title: string + + if (Array.isArray(meta.description)) { + description = meta.description[0] + } else if (meta.description) { + description = meta.description + } + + if (meta.image) { + if (typeof meta.image === 'string') { + imageUrl = meta.image + } else if (Array.isArray(meta.image)) { + imageUrl = meta.image[0] + } else { + if (Array.isArray(meta.image.url)) { + imageUrl = meta.image.url[0] + } else if (meta.image.url) { + imageUrl = meta.image.url + } + } + } + + if (Array.isArray(meta.title)) { + title = meta.title[0] + } else { + title = meta.title + } + + if (!imageUrl || !description) { + throw new Error('imageUrl or description not found!') + } + + if (!imageUrl.startsWith('http')) { + const resolvedUrl = new Url.URL(imageUrl, url) + imageUrl = resolvedUrl.toString() + } + const payload: UrlLinkPayload = { - description : 'todo', - thumbnailUrl : 'todo', - title : 'todo', + description, + thumbnailUrl: imageUrl, + title, url, }