From 100435f5eb0ceb61681ccc6d033bb81a76bc9351 Mon Sep 17 00:00:00 2001 From: shun91 Date: Tue, 2 Apr 2024 08:16:22 +0900 Subject: [PATCH] =?UTF-8?q?=E7=9F=AD=E7=B8=AE=E3=81=95=E3=82=8C=E3=81=9FUR?= =?UTF-8?q?L=E3=82=92=E5=85=83=E3=81=AEURL=E3=81=AB=E5=A4=89=E6=8F=9B?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/createNotionPageByTweet.ts | 2 +- src/parseTextAndUrl.test.ts | 12 ++++++------ src/parseTextAndUrl.ts | 26 ++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/createNotionPageByTweet.ts b/src/createNotionPageByTweet.ts index 6525aab..c8008f6 100644 --- a/src/createNotionPageByTweet.ts +++ b/src/createNotionPageByTweet.ts @@ -42,7 +42,7 @@ export async function createNotionPageByTweet({ }, text: { type: "rich_text", - rich_text: parseTextAndUrl(text), + rich_text: await parseTextAndUrl(text), }, url: { url: url, diff --git a/src/parseTextAndUrl.test.ts b/src/parseTextAndUrl.test.ts index 8985170..ca2503a 100644 --- a/src/parseTextAndUrl.test.ts +++ b/src/parseTextAndUrl.test.ts @@ -1,7 +1,7 @@ import { parseTextAndUrl } from "./parseTextAndUrl"; // 適切なパスに置き換えてください import { test, expect } from "vitest"; -test("URLを含むテキストをパースする", () => { +test("URLを含むテキストをパースする", async () => { const testInput = "こんにちは、このリンクを見てください:https://example.com またこちらも:https://openai.com"; const expectedOutput = [ @@ -37,12 +37,12 @@ test("URLを含むテキストをパースする", () => { }, ]; - const result = parseTextAndUrl(testInput); + const result = await parseTextAndUrl(testInput); expect(result).toEqual(expectedOutput); }); -test("URLを含まないテキストをパースする", () => { +test("URLを含まないテキストをパースする", async () => { const testInput = "こんにちは、このテキストにはURLが含まれていません"; const expectedOutput = [ { @@ -53,12 +53,12 @@ test("URLを含まないテキストをパースする", () => { }, ]; - const result = parseTextAndUrl(testInput); + const result = await parseTextAndUrl(testInput); expect(result).toEqual(expectedOutput); }); -test("テキストがURLのみである場合のパース", () => { +test("テキストがURLのみである場合のパース", async () => { const testInput = "https://onlyurl.com"; const expectedOutput = [ { @@ -72,7 +72,7 @@ test("テキストがURLのみである場合のパース", () => { }, ]; - const result = parseTextAndUrl(testInput); + const result = await parseTextAndUrl(testInput); expect(result).toEqual(expectedOutput); }); diff --git a/src/parseTextAndUrl.ts b/src/parseTextAndUrl.ts index 0a23696..c04ec44 100644 --- a/src/parseTextAndUrl.ts +++ b/src/parseTextAndUrl.ts @@ -1,4 +1,26 @@ -export function parseTextAndUrl(input: string) { +/** + * 短縮されたURLを元のURLに変換する + */ +async function replaceShortUrl(shortUrl: string) { + try { + // fetchリクエストを送信し、リダイレクトを手動で処理する + const response = await fetch(shortUrl, { redirect: "manual" }); + + if (response.status >= 300 && response.status < 400) { + // リダイレクトレスポンスの場合、LocationヘッダーからURLを取得 + return response.headers.get("Location") ?? shortUrl; + } + + // リダイレクトがない場合は、元のURLをそのまま返す + return shortUrl; + } catch (error) { + // エラーで元のURLを取得できなかった場合は、短縮URLをそのまま返す + console.warn(error); + return shortUrl; + } +} + +export async function parseTextAndUrl(input: string) { // Define regex to detect URLs in the input string const urlRegex = /(https?:\/\/[^\s]+)/g; @@ -8,7 +30,7 @@ export function parseTextAndUrl(input: string) { // Loop over the input string to find URLs and split the text around them while ((match = urlRegex.exec(input)) !== null) { - const matchedUrl = match[0]; + const matchedUrl = await replaceShortUrl(match[0]); // Extract the text before the URL if (match.index > lastIndex) {