From 4cfa4ffc00eb810859c233d57115fdc07fcad105 Mon Sep 17 00:00:00 2001 From: caadiq Date: Sun, 31 May 2026 18:02:22 +0900 Subject: [PATCH] =?UTF-8?q?fix(x-bot):=20=EB=A6=AC=ED=8A=B8=EC=9C=97=20?= =?UTF-8?q?=EC=9D=B4=EC=A4=91=20=EC=A0=80=EC=9E=A5=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 같은 리트윗이 타임라인에서 래퍼 id / 원본 id 두 형태로 번갈아 나타나 post_id 중복 체크를 통과해 두 번 저장되던 문제 수정. 리트윗 저장 시 동일 내용 + (원작자 또는 봇계정) username이 이미 있으면 중복으로 간주해 건너뜀. hydration으로 양쪽 모두 전체 내용을 갖추므로 내용 기반 매칭이 안정적으로 동작. Co-Authored-By: Claude Opus 4.7 --- backend/src/services/x/index.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/backend/src/services/x/index.js b/backend/src/services/x/index.js index 2c2d254..43d1f0f 100644 --- a/backend/src/services/x/index.js +++ b/backend/src/services/x/index.js @@ -61,6 +61,20 @@ async function xBotPlugin(fastify, opts) { return null; } + // 리트윗 이중 저장 방지: 같은 리트윗이 타임라인에서 래퍼 id / 원본 id 두 형태로 + // 번갈아 나타나 post_id가 달라도 같은 트윗인 경우가 있음. + // hydration으로 양쪽 모두 전체 내용을 갖추므로 동일 내용이면 중복 처리. + // username은 형태에 따라 원작자/봇계정으로 불일치할 수 있어 둘 다 매칭. + if (tweet.isRetweet && tweet.text) { + const [dup] = await fastify.db.query( + 'SELECT id FROM schedule_x WHERE content = ? AND username IN (?, ?) LIMIT 1', + [tweet.text, tweet.originalUsername || username, username] + ); + if (dup.length > 0) { + return null; + } + } + const date = formatDate(tweet.time); const time = formatTime(tweet.time); const title = extractTitle(tweet.text);