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) {