Skip to content

Feat(#6): 대화 텍스트 내 URL 정규식 추출 기능 구현 - #8

Merged
pearseona merged 3 commits into
developfrom
feat/6-extract-url-regex
Jul 14, 2026
Merged

Feat(#6): 대화 텍스트 내 URL 정규식 추출 기능 구현#8
pearseona merged 3 commits into
developfrom
feat/6-extract-url-regex

Conversation

@pearseona

@pearseona pearseona commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

📝 개요

사용자가 입력한 텍스트 내에서 악성 피싱 URL을 판별하기 위한 전처리 파이프라인의 1단계인 **'URL 정규식 추출 기능'**을 구현했습니다.

메인 백엔드(Spring) 서버와의 원할한 인터페이스 연동 및 통합 테스트를 위해 음성 분석용 더미 엔드포인트를 미리 확보했습니다.

🔗 관련 이슈

🎯 주요 변경 사항

정규식 기반의 URL 추출기 구현

  • 문장 내부에서 http:// 또는 https://로 시작하는 웹 주소를 매칭하는 정규표현식 파이프라인 구현
  • 문장 맨 끝에 붙는 온점(.), 쉼표(,), 괄호(]) 등의 문장부호가 URL 문자열에 포함되어 도메인이 깨지는 억까 케이스 방어 로직 적용
  • 동일한 악성 URL이 반복 유입될 때 외부 API 중복 호출을 막기 위해, 순서를 보존하며 유니크 값만 남기는 중복 제거 로직 구현

5개 시나리오 기반 단위 테스트 검증 완

  • URL이 없는 순수 대화, 다중 URL 혼재, 문장 부호 접착 케이스, 중복 URL 입력 등 다양한 피싱 문자 패턴을 가정한 테스트 코드를 작성하여 테스트

보이스피싱 탐지용 음성 분석 라우터 초안 확보

📸 사진

image

✅ PR 체크리스트

  • 관련 이슈를 연결했습니다.
  • 구현 범위와 변경 이유를 설명했습니다.
  • 로컬 테스트(uvicorn 구동 또는 테스트 코드)를 통과했습니다.
  • API 변경 사항이 있다면 Swagger / API 명세에 반영했습니다.
  • 민감 정보(API Key, 시크릿 키 등)가 코드·로그·테스트 데이터에 포함되지 않았습니다.
  • 프론트엔드 또는 메인 백엔드(Spring)에 영향을 주는 응답 스키마 또는 Enum 변경이 있다면 팀에 공유했습니다.
  • 병합(Merge) 전 작업 브랜치를 삭제하지 않았습니다.

Summary by CodeRabbit

  • New Features

    • Added voice-call analysis support with risk scoring, phishing detection, keyword results, and an analysis summary.
    • Added automatic extraction of HTTP and HTTPS links from text, including duplicate removal and trailing punctuation cleanup.
  • Improvements

    • Updated analysis results to clearly indicate that both message and URL analysis are complete.
    • Added clearer field descriptions to URL analysis results.
  • Tests

    • Added coverage for URL extraction, including multiple links, duplicate links, punctuation, and text without links.

@pearseona pearseona added the feat New feature or functional additions to the application label Jul 12, 2026
@pearseona pearseona self-assigned this Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a voice-phishing analysis endpoint, updates the SMS analysis response message and annotations, and introduces a tested utility for extracting, cleaning, ordering, and deduplicating URLs from text.

Changes

Analysis features

Layer / File(s) Summary
URL extraction utility and validation
app/service/url/url_extractor.py, tests/test_url_extractor.py
Adds HTTP/HTTPS URL matching with punctuation trimming, order preservation, deduplication, and unit tests for the supported cases.
Voice analysis endpoint
app/router/analyze_voice.py
Adds a /analyze-voice POST endpoint returning a fixed voice-phishing analysis payload through ApiResponse.
SMS analysis response update
app/router/analyze.py
Updates URL analysis field annotations and changes the completion message to indicate SMS and URL analysis.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • SafeFam/SafeFam_AI issue 6 — covers the URL extraction utility and its tests added in this PR.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: regex-based URL extraction from conversation text.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/6-extract-url-regex

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/test_url_extractor.py (1)

23-27: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Expand punctuation tests to cover the documented behavior.

This test only verifies a trailing period, so regressions involving commas, closing brackets, or valid URLs ending in balanced parentheses would pass unnoticed.

🧪 Proposed test expansion
     def test_url_with_trailing_punctuation(self):
         """시나리오 4: 문장 맨 끝에 온점이나 기호와 함께 URL이 위치한 경우 -> 기호 제외하고 깔끔하게 추출 (억까 방지)"""
-        text = "아래 단축 링크를 꼭 클릭해주세요: https://bit.ly/3xyz."
-        expected = ["https://bit.ly/3xyz"]
-        self.assertEqual(extract_urls_from_text(text), expected)
+        cases = [
+            ("링크: https://example.com/path,", ["https://example.com/path"]),
+            ("링크: (https://example.com/path).", ["https://example.com/path"]),
+            (
+                "링크: https://en.wikipedia.org/wiki/Foo_(bar)",
+                ["https://en.wikipedia.org/wiki/Foo_(bar)"],
+            ),
+        ]
+        for text, expected in cases:
+            with self.subTest(text=text):
+                self.assertEqual(extract_urls_from_text(text), expected)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_url_extractor.py` around lines 23 - 27, Expand
test_url_with_trailing_punctuation to cover trailing commas and closing
brackets, plus a valid URL whose path ends with balanced parentheses. Assert
punctuation is excluded while balanced parentheses remain part of the extracted
URL, preserving the documented extraction behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/service/url/url_extractor.py`:
- Around line 20-22: Update the URL-cleaning loop in the URL extraction function
to trim sentence punctuation only when it is clearly attached, preserving valid
trailing URL characters. Remove closing brackets such as “)” or “]” only when
they are unmatched by corresponding opening brackets in the URL, so balanced URL
paths like “Foo_(bar)” remain intact.

---

Nitpick comments:
In `@tests/test_url_extractor.py`:
- Around line 23-27: Expand test_url_with_trailing_punctuation to cover trailing
commas and closing brackets, plus a valid URL whose path ends with balanced
parentheses. Assert punctuation is excluded while balanced parentheses remain
part of the extracted URL, preserving the documented extraction behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 676982c2-b3b5-46b4-9dca-de2d6f4c05cc

📥 Commits

Reviewing files that changed from the base of the PR and between 0326d68 and c037ac7.

📒 Files selected for processing (4)
  • app/router/analyze.py
  • app/router/analyze_voice.py
  • app/service/url/url_extractor.py
  • tests/test_url_extractor.py

Comment on lines +20 to +22
for url in raw_urls:
cleaned_url = url.rstrip('.,?!:;)[]')
cleaned_urls.append(cleaned_url)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve valid URL punctuation when trimming sentence punctuation.

rstrip('.,?!:;)[]') blindly removes valid trailing URL characters. For example, https://en.wikipedia.org/wiki/Foo_(bar) becomes https://en.wikipedia.org/wiki/Foo_(bar, which can make downstream URL analysis miss the original URL. Trim sentence punctuation only when it is clearly attached, and remove closing brackets only when they are unmatched.

🐛 Proposed fix
     for url in raw_urls:
-        cleaned_url = url.rstrip('.,?!:;)[]')
+        cleaned_url = url.rstrip(".,?!:;")
+        if cleaned_url.endswith(")") and cleaned_url.count(")") > cleaned_url.count("("):
+            cleaned_url = cleaned_url[:-1]
+        if cleaned_url.endswith("]") and cleaned_url.count("]") > cleaned_url.count("["):
+            cleaned_url = cleaned_url[:-1]
         cleaned_urls.append(cleaned_url)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for url in raw_urls:
cleaned_url = url.rstrip('.,?!:;)[]')
cleaned_urls.append(cleaned_url)
for url in raw_urls:
cleaned_url = url.rstrip(".,?!:;")
if cleaned_url.endswith(")") and cleaned_url.count(")") > cleaned_url.count("("):
cleaned_url = cleaned_url[:-1]
if cleaned_url.endswith("]") and cleaned_url.count("]") > cleaned_url.count("["):
cleaned_url = cleaned_url[:-1]
cleaned_urls.append(cleaned_url)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/service/url/url_extractor.py` around lines 20 - 22, Update the
URL-cleaning loop in the URL extraction function to trim sentence punctuation
only when it is clearly attached, preserving valid trailing URL characters.
Remove closing brackets such as “)” or “]” only when they are unmatched by
corresponding opening brackets in the URL, so balanced URL paths like
“Foo_(bar)” remain intact.

@pearseona
pearseona merged commit 76ad8cc into develop Jul 14, 2026
1 check passed
@pearseona pearseona changed the title Feat: 대화 텍스트 내 URL 정규식 추출 기능 구현 Feat(#6): 대화 텍스트 내 URL 정규식 추출 기능 구현 Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature or functional additions to the application

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant