-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [add] - link-preview-js * [add] - 履歴用DBの構造処理を更新 URLプレビュー用データ追加 * [add] - リンクプレビューデータ用のinterface追加 * [add] - linkDataを追加するmigrationスクリプト作成 * [change] - linkDataのカラムデータタイプを変更 * [add] - migraitonスクリプトを適用 * [change] - SQLiteにblobを適用したことによりinterfaceを更新 * [add] - 型補間 * [fix] - 重複したカラムへの対応忘れてた * [change] - リンクプレビューデータの型をblobからテキストへ JSONだけで保存することにした * [change] - リンクプレビューデータ用のinterface更新 * [change] - linkDataの型更新を適用 * [change] - interfaceの一部統一 * [add] - メッセージ単体取得用のパース処理にリンクプレビューデータ分も追加 * [remove/add] - link-preview-jsからopen-graph-scaperへ * [add] - WIP リンクプレビュー生成関数の土台作成 * [add] - リンクプレビューデータのinterface更新 * [add] - これも * [add] - 履歴取得時、リンクプレビューがnullだった時空JSONにするように * [add] - リンクのプレビュー処理"だけ"をしてみる * [change] - コメント * [add] - WIP プレビュー時データをマージして送信するように * [add] - URLプレビュー用のOGデータを単一URLだけパース、記録するように * [change] - プレビューデータが取れた時のみ更新するように * [change] - 美化 * [add] - linkData用interfaceにfavicon * [change] - メッセージへのURLプレビュー追加処理の返し方更新 * [fix] - !WIP:リンクプレビューデータのJSONマージができていなかった * [add] - favionもパースするように * [add] - メッセ用Interfaceのリンクデータにtitle追加 * [add] - リンクデータプレビュー処理時titleのパースを追加 * [add] - ウェブサイトに加えてmediaTypeがarticleのものもパースするように * [change] - 画像用のリンクデータのinterface更新 ?をつけただけ * [change] - URL判別用regexを改善 * [change] - 画像用リンクならリンクプレビュー処理をしないように * [change] - メディア系以外のURLなら無理やりパースするように * [add] - FxTwitter用のパース方法を追加 * [fix] - 画像用のinterfaceが違う * [change] - URLメタデータパース部分を関数化 * [change] - importの位置 * [change] - リンクプレビューデータ用のinterfaceを全体的に更新 * [change] - リンクデータのinterface更新に伴うパース処理途中の型定義 * [change] - URL配列のパース処理に対応 * [add] - 画像単体用のためのmediaTypeも追加 * [fix] - Twitterのリンクデータ取得に使うURLが最初の1個目しか使われていなかった * [remove] - 不要なログ
- Loading branch information
Showing
10 changed files
with
546 additions
and
34 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import sqlite3 from "sqlite3"; | ||
const db = new sqlite3.Database("./records/MESSAGE.db"); | ||
|
||
/** | ||
* すべてのチャンネル履歴テーブルへlinkDataカラムを追加 | ||
*/ | ||
export default async function migration20240603() { | ||
//チャンネル分のテーブルへlinkDataカラムを追加 | ||
db.all( | ||
` | ||
SELECT name FROM sqlite_master WHERE type='table'; | ||
`, | ||
(err:Error, tables:[{name:string}]) => { | ||
//console.log("20240603 :: tables->", tables); | ||
|
||
//ループしてlinkDataカラムを追加 | ||
for (let channelName of tables) { | ||
db.run(`ALTER TABLE ` + channelName.name + ` ADD linkData TEXT DEFAULT '{}'`, (err:Error)=>{}); | ||
} | ||
return; | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
import sqlite3 from "sqlite3"; | ||
import { IMessage } from "../type/Message"; | ||
const db = new sqlite3.Database("./records/MESSAGE.db"); | ||
import ogs from 'open-graph-scraper'; | ||
|
||
//取得できるOpenGraphデータのinterface | ||
interface IOGData { | ||
ogSiteName: string, | ||
ogTitle: string, | ||
ogType: string, | ||
ogUrl: string, | ||
ogImage: {url:string, type:string}[], | ||
ogDescription: string, | ||
favicon: string, | ||
requestUrl: string, | ||
success: boolean | ||
}; | ||
|
||
//取得したメタデータをパースしたもの | ||
interface IURLParsed { | ||
contentType: "text/html", | ||
mediaType: string, | ||
url: string, | ||
siteName: string, | ||
title: string, | ||
description: string, | ||
images: {url:string, type:string}[], | ||
favicon: string | ||
}; | ||
|
||
export default async function genLinkPreview( | ||
urls:RegExpMatchArray, | ||
channelId:string, | ||
messageId: string | ||
):Promise<IMessage["linkData"]|null> { | ||
try { | ||
|
||
//プレビューデータの格納用変数 | ||
let previewResult:IMessage["linkData"] = { | ||
//"0":{} | ||
}; | ||
|
||
//URLの配列分フェッチ、パース処理 | ||
for (let index in urls) { | ||
|
||
//もしURLが画像用ならここで処理して終了 | ||
if (urls[index].match(/(https?:\/\/.*\.(?:png|jpg))/g) !== null) { | ||
previewResult[index] = { | ||
contentType: "image", | ||
mediaType: "image", | ||
url: urls[index], | ||
}; | ||
} else { | ||
|
||
//Twitter用だったら二重処理 | ||
if (urls[index].includes("fxtwitter")) { | ||
//プレビューデータ化処理 | ||
const resultForThis = await fetchURLForTwitter(urls[index]); | ||
//挿入 :: ToDo | ||
//previewResult = { | ||
// "0": resultForThis | ||
//}; | ||
previewResult[index] = resultForThis; | ||
} else { | ||
//プレビューデータ化処理 | ||
const resultForThis = await fetchURL(urls[index]); | ||
//挿入 :: ToDo | ||
previewResult[index] = resultForThis; | ||
} | ||
|
||
} | ||
} | ||
|
||
//プレビューデータの書き込み処理 | ||
return new Promise((resolve)=> { | ||
db.run( | ||
` | ||
UPDATE C` + channelId + ` SET | ||
linkData=? | ||
WHERE messageId=? | ||
`, | ||
[JSON.stringify(previewResult), messageId], | ||
(err:Error) => { | ||
if (err) { | ||
console.log("genLinkPreview :: エラー->", err); | ||
resolve(null); | ||
return; | ||
} else { | ||
resolve(previewResult); | ||
return; | ||
} | ||
} | ||
); | ||
}); | ||
|
||
} catch(e) { | ||
|
||
console.log("getLinkPreview :: エラー->", e); | ||
return null; | ||
|
||
} | ||
} | ||
|
||
/** | ||
* URLのパース処理 | ||
* @param url | ||
*/ | ||
async function fetchURL(url:string):Promise<IURLParsed> { | ||
//結果格納用 | ||
let resultFetched:IURLParsed = { | ||
contentType: "text/html", | ||
mediaType: "", | ||
url: "", | ||
siteName: "", | ||
title: "", | ||
description: "", | ||
images: [], | ||
favicon: "" | ||
}; | ||
|
||
//フェッチ、メタデータパース | ||
await ogs({url: url}) | ||
.then((data:any) => { | ||
const { error, html, result, response } = data; | ||
|
||
//パース | ||
resultFetched = { | ||
contentType: "text/html", | ||
mediaType: result.ogType, | ||
url: result.ogUrl, | ||
siteName: result.ogSiteName, | ||
title: result.ogTitle, | ||
description: result.ogDescription, | ||
images: result.ogImage, | ||
favicon: result.favicon | ||
}; | ||
}); | ||
|
||
//取得できたメタデータを返す | ||
return resultFetched; | ||
} | ||
|
||
/** | ||
* twitter用のURLパース処理 | ||
* @param url | ||
*/ | ||
async function fetchURLForTwitter(url:string) { | ||
//結果格納用 | ||
let resultFetched:IURLParsed = { | ||
contentType: "text/html", | ||
mediaType: "", | ||
url: "", | ||
siteName: "", | ||
title: "", | ||
description: "", | ||
images: [], | ||
favicon: "" | ||
}; | ||
|
||
//一度純粋にHTMLをフェッチ | ||
await fetch(url).then(async (res) => { | ||
//取得データをテキスト化 | ||
return await res.text(); | ||
}).then(async (text) => { | ||
//console.log("simple fetched json->", text); | ||
//処理したHTMLのテキストからmetaデータ取得する | ||
await ogs({ html: text }).then((data:any) => { | ||
const { error, html, result, response } = data; | ||
//console.log("genLink Preview :: parsed for Better timing->", result); | ||
//パース | ||
resultFetched = { | ||
contentType: "text/html", | ||
mediaType: result.ogType, | ||
url: result.ogUrl, | ||
siteName: result.ogSiteName, | ||
title: result.ogTitle, | ||
description: result.ogDescription, | ||
images: result.ogImage, | ||
favicon: result.favicon | ||
}; | ||
}); | ||
}); | ||
|
||
//取得できたメタデータを返す | ||
return resultFetched; | ||
} |