diff --git a/.github/workflows/generator-generic-ossf-slsa3-publish.yml b/.github/workflows/generator-generic-ossf-slsa3-publish.yml
new file mode 100644
index 000000000000..35c829b139b5
--- /dev/null
+++ b/.github/workflows/generator-generic-ossf-slsa3-publish.yml
@@ -0,0 +1,66 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# This workflow lets you generate SLSA provenance file for your project.
+# The generation satisfies level 3 for the provenance requirements - see https://slsa.dev/spec/v0.1/requirements
+# The project is an initiative of the OpenSSF (openssf.org) and is developed at
+# https://github.com/slsa-framework/slsa-github-generator.
+# The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier.
+# For more information about SLSA and how it improves the supply-chain, visit slsa.dev.
+
+name: SLSA generic generator
+on:
+ workflow_dispatch:
+ release:
+ types: [created]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ outputs:
+ digests: ${{ steps.hash.outputs.digests }}
+
+ steps:
+ - uses: actions/checkout@v4
+
+ # ========================================================
+ #
+ # Step 1: Build your artifacts.
+ #
+ # ========================================================
+ - name: Build artifacts
+ run: |
+ # These are some amazing artifacts.
+ echo "artifact1" > artifact1
+ echo "artifact2" > artifact2
+
+ # ========================================================
+ #
+ # Step 2: Add a step to generate the provenance subjects
+ # as shown below. Update the sha256 sum arguments
+ # to include all binaries that you generate
+ # provenance for.
+ #
+ # ========================================================
+ - name: Generate subject for provenance
+ id: hash
+ run: |
+ set -euo pipefail
+
+ # List the artifacts the provenance will refer to.
+ files=$(ls artifact*)
+ # Generate the subjects (base64 encoded).
+ echo "hashes=$(sha256sum $files | base64 -w0)" >> "${GITHUB_OUTPUT}"
+
+ provenance:
+ needs: [build]
+ permissions:
+ actions: read # To read the workflow path.
+ id-token: write # To sign the provenance.
+ contents: write # To add assets to a release.
+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0
+ with:
+ base64-subjects: "${{ needs.build.outputs.digests }}"
+ upload-assets: true # Optional: Upload to a new release
diff --git a/collections/scam-detection-ai/__pycache__/email_analyzer.cpython-312.pyc b/collections/scam-detection-ai/__pycache__/email_analyzer.cpython-312.pyc
new file mode 100644
index 000000000000..17ad068257ce
Binary files /dev/null and b/collections/scam-detection-ai/__pycache__/email_analyzer.cpython-312.pyc differ
diff --git a/collections/scam-detection-ai/__pycache__/message_analyzer.cpython-312.pyc b/collections/scam-detection-ai/__pycache__/message_analyzer.cpython-312.pyc
new file mode 100644
index 000000000000..e568a30d4140
Binary files /dev/null and b/collections/scam-detection-ai/__pycache__/message_analyzer.cpython-312.pyc differ
diff --git a/collections/scam-detection-ai/app.py b/collections/scam-detection-ai/app.py
new file mode 100644
index 000000000000..90845051323d
--- /dev/null
+++ b/collections/scam-detection-ai/app.py
@@ -0,0 +1,64 @@
+from flask import Flask, render_template, request
+from email_analyzer import analyze_email
+from email_fetcher import fetch_emails
+from message_analyzer import analyze_message
+
+app = Flask(__name__)
+
+@app.route('/')
+def index():
+ return render_template('index.html')
+
+@app.route('/analyze', methods=['POST'])
+def analyze():
+ if 'email_text' in request.form:
+ email_text = request.form['email_text']
+ analysis = analyze_email(email_text)
+ total_score = sum(analysis.values())
+ is_scam = total_score >= 3
+ return render_template('result.html', analysis=analysis, is_scam=is_scam, analysis_type='Email')
+
+ elif 'message_text' in request.form:
+ message_text = request.form['message_text']
+ analysis = analyze_message(message_text)
+ total_score = sum(analysis.values())
+ is_scam = total_score >= 2
+ return render_template('result.html', analysis=analysis, is_scam=is_scam, analysis_type='Message')
+
+ elif 'fetch_emails' in request.form:
+ username = request.form['username']
+ password = request.form['password']
+ emails = fetch_emails(username, password)
+
+ analyzed_emails = []
+ if emails:
+ for email_message in emails:
+ body = ""
+ if email_message.is_multipart():
+ for part in email_message.walk():
+ if part.get_content_type() == "text/plain":
+ body = part.get_payload(decode=True).decode()
+ break
+ else:
+ body = email_message.get_payload(decode=True).decode()
+
+ analysis = analyze_email(body)
+ total_score = sum(analysis.values())
+ is_scam = total_score >= 3
+
+ subject, _ = email.header.decode_header(email_message["Subject"])[0]
+ if isinstance(subject, bytes):
+ subject = subject.decode()
+
+ analyzed_emails.append({
+ "subject": subject,
+ "from": email_message['From'],
+ "analysis": analysis,
+ "is_scam": is_scam
+ })
+ return render_template('results_list.html', emails=analyzed_emails)
+
+ return "Invalid request", 400
+
+if __name__ == '__main__':
+ app.run(debug=True)
diff --git a/collections/scam-detection-ai/chrome-extension/background.js b/collections/scam-detection-ai/chrome-extension/background.js
new file mode 100644
index 000000000000..c365c6ca8dca
--- /dev/null
+++ b/collections/scam-detection-ai/chrome-extension/background.js
@@ -0,0 +1,27 @@
+chrome.runtime.onInstalled.addListener(() => {
+ chrome.contextMenus.create({
+ id: "analyzeText",
+ title: "Analyze for Scams",
+ contexts: ["selection"]
+ });
+});
+
+chrome.contextMenus.onClicked.addListener((info, tab) => {
+ if (info.menuItemId === "analyzeText") {
+ fetch('http://localhost:5000/analyze', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: `message_text=${encodeURIComponent(info.selectionText)}`
+ })
+ .then(response => response.text())
+ .then(data => {
+ chrome.storage.local.set({ analysisResult: data });
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ chrome.storage.local.set({ analysisResult: 'Error analyzing text.' });
+ });
+ }
+});
diff --git a/collections/scam-detection-ai/chrome-extension/manifest.json b/collections/scam-detection-ai/chrome-extension/manifest.json
new file mode 100644
index 000000000000..946ddd0b94bb
--- /dev/null
+++ b/collections/scam-detection-ai/chrome-extension/manifest.json
@@ -0,0 +1,16 @@
+{
+ "manifest_version": 3,
+ "name": "Scam Detection AI",
+ "version": "1.0",
+ "description": "Analyzes selected text for scams.",
+ "permissions": [
+ "activeTab",
+ "contextMenus"
+ ],
+ "background": {
+ "service_worker": "background.js"
+ },
+ "action": {
+ "default_popup": "popup.html"
+ }
+}
diff --git a/collections/scam-detection-ai/chrome-extension/popup.html b/collections/scam-detection-ai/chrome-extension/popup.html
new file mode 100644
index 000000000000..49ef9d1b7dd8
--- /dev/null
+++ b/collections/scam-detection-ai/chrome-extension/popup.html
@@ -0,0 +1,17 @@
+
+
+
+ Scam Detection AI
+
+
+
+ Scam Detection AI
+
+
+
+
+
+
diff --git a/collections/scam-detection-ai/chrome-extension/popup.js b/collections/scam-detection-ai/chrome-extension/popup.js
new file mode 100644
index 000000000000..68d231561d8d
--- /dev/null
+++ b/collections/scam-detection-ai/chrome-extension/popup.js
@@ -0,0 +1,27 @@
+document.addEventListener('DOMContentLoaded', () => {
+ chrome.storage.local.get(['analysisResult'], (result) => {
+ if (result.analysisResult) {
+ document.getElementById('result').innerHTML = result.analysisResult;
+ chrome.storage.local.remove(['analysisResult']);
+ }
+ });
+});
+
+document.getElementById('analyzeButton').addEventListener('click', () => {
+ const text = document.getElementById('textToAnalyze').value;
+ fetch('http://localhost:5000/analyze', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: `message_text=${encodeURIComponent(text)}`
+ })
+ .then(response => response.text())
+ .then(data => {
+ document.getElementById('result').innerHTML = data;
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ document.getElementById('result').innerText = 'Error analyzing text.';
+ });
+});
diff --git a/collections/scam-detection-ai/email_analyzer.py b/collections/scam-detection-ai/email_analyzer.py
new file mode 100644
index 000000000000..cfed604df07f
--- /dev/null
+++ b/collections/scam-detection-ai/email_analyzer.py
@@ -0,0 +1,107 @@
+import re
+
+import requests
+
+def get_domain_reputation(domain):
+ """
+ Checks the reputation of a domain using a mock API.
+ In a real application, this would integrate with a service like VirusTotal.
+ """
+ # This is a mock response.
+ if "fake" in domain or "suspicious" in domain:
+ return "Malicious"
+ return "Clean"
+
+def analyze_email(email_text):
+ """
+ Analyzes an email for potential scam indicators.
+
+ Args:
+ email_text: The full text of the email.
+
+ Returns:
+ A dictionary containing the analysis results.
+ """
+ scam_indicators = {
+ "urgency": 0,
+ "generic_greeting": 0,
+ "suspicious_links": 0,
+ "unusual_sender": 0,
+ "payment_requests": 0,
+ "attachments": 0,
+ "domain_analysis": {}
+ }
+
+ # Urgency keywords
+ urgency_keywords = ["urgent", "immediate", "action required", "limited time", "expire"]
+ for keyword in urgency_keywords:
+ if re.search(r'\b' + keyword + r'\b', email_text, re.IGNORECASE):
+ scam_indicators["urgency"] = 1
+ break
+
+ # Generic greeting
+ generic_greetings = ["dear customer", "dear user", "sir/madam"]
+ for greeting in generic_greetings:
+ if greeting in email_text.lower():
+ scam_indicators["generic_greeting"] = 1
+ break
+
+ # Suspicious links (basic check for non-standard URLs)
+ if re.search(r'http[s]?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}/[a-zA-Z0-9_.-]+', email_text):
+ scam_indicators["suspicious_links"] = 1
+
+ # Unusual sender (very basic check)
+ if "From:" in email_text:
+ from_line = email_text.split("From:")[1].split("\n")[0]
+ if re.search(r'<.*@.*>', from_line) and not re.search(r'<.*@.*\..*>', from_line):
+ scam_indicators["unusual_sender"] = 1
+
+ # Payment requests
+ payment_keywords = ["payment", "invoice", "wire transfer", "bank account", "credit card"]
+ for keyword in payment_keywords:
+ if re.search(r'\b' + keyword + r'\b', email_text, re.IGNORECASE):
+ scam_indicators["payment_requests"] = 1
+ break
+
+ # Attachments
+ if "Content-Disposition: attachment" in email_text:
+ scam_indicators["attachments"] = 1
+
+ # Domain analysis
+ urls = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', email_text)
+ domains = [re.search(r'//(.*?)/', url).group(1) for url in urls if re.search(r'//(.*?)/', url)]
+
+ for domain in domains:
+ reputation = get_domain_reputation(domain)
+ scam_indicators["domain_analysis"][domain] = reputation
+
+ return scam_indicators
+
+if __name__ == '__main__':
+ sample_email = """
+ From: Suspicious Sender
+ Subject: Urgent Action Required: Your Account Will Be Deactivated
+
+ Dear user,
+
+ We have detected suspicious activity on your account. For your security, we have temporarily suspended your account.
+ To reactivate your account, you must verify your identity by clicking the link below and updating your payment information.
+
+ http://suspicious-link.com/verify
+
+ Failure to do so within 24 hours will result in permanent account deactivation.
+
+ Thank you for your cooperation.
+
+ Sincerely,
+ The Security Team
+ """
+
+ analysis = analyze_email(sample_email)
+ print(analysis)
+
+ total_score = sum(analysis.values())
+ if total_score >= 3:
+ print("\nThis email is likely a scam!")
+ else:
+ print("\nThis email seems legitimate.")
diff --git a/collections/scam-detection-ai/email_fetcher.py b/collections/scam-detection-ai/email_fetcher.py
new file mode 100644
index 000000000000..4430bef5d003
--- /dev/null
+++ b/collections/scam-detection-ai/email_fetcher.py
@@ -0,0 +1,76 @@
+import imaplib
+import email
+from email.header import decode_header
+
+def fetch_emails(username, password, server="imap.gmail.com"):
+ """
+ Fetches emails from an IMAP server.
+
+ Args:
+ username: The email account username.
+ password: The email account password.
+ server: The IMAP server address.
+
+ Returns:
+ A list of email messages.
+ """
+ try:
+ # connect to the server
+ mail = imaplib.IMAP4_SSL(server)
+ # login
+ mail.login(username, password)
+ # select the inbox
+ mail.select("inbox")
+
+ # search for all emails
+ status, messages = mail.search(None, "ALL")
+ email_ids = messages[0].split()
+
+ emails = []
+ for email_id in email_ids[-5:]: # Fetch last 5 emails for demonstration
+ status, msg_data = mail.fetch(email_id, "(RFC822)")
+ for response_part in msg_data:
+ if isinstance(response_part, tuple):
+ msg = email.message_from_bytes(response_part[1])
+ emails.append(msg)
+
+ mail.logout()
+ return emails
+
+ except imaplib.IMAP4.error as e:
+ print(f"IMAP Error: {e}")
+ return []
+
+if __name__ == '__main__':
+ # This is a placeholder for a secure way to get credentials
+ EMAIL_USERNAME = "your_email@gmail.com"
+ EMAIL_PASSWORD = "your_app_password"
+
+ emails = fetch_emails(EMAIL_USERNAME, EMAIL_PASSWORD)
+ if emails:
+ for email_message in emails:
+ subject, encoding = decode_header(email_message["Subject"])[0]
+ if isinstance(subject, bytes):
+ subject = subject.decode(encoding if encoding else "utf-8")
+
+ print("="*50)
+ print(f"Subject: {subject}")
+ print(f"From: {email_message['From']}")
+ print(f"To: {email_message['To']}")
+
+ if email_message.is_multipart():
+ for part in email_message.walk():
+ content_type = part.get_content_type()
+ content_disposition = str(part.get("Content-Disposition"))
+ try:
+ body = part.get_payload(decode=True).decode()
+ if "attachment" not in content_disposition:
+ print("\n--- Body ---\n", body)
+ except:
+ pass
+ else:
+ body = email_message.get_payload(decode=True).decode()
+ print("\n--- Body ---\n", body)
+ print("="*50 + "\n")
+ else:
+ print("Could not fetch emails. Please check your credentials and IMAP settings.")
diff --git a/collections/scam-detection-ai/index.md b/collections/scam-detection-ai/index.md
new file mode 100644
index 000000000000..06f6f71f6824
--- /dev/null
+++ b/collections/scam-detection-ai/index.md
@@ -0,0 +1,8 @@
+---
+title: "Scam Detection AI"
+layout: collection
+permalink: /collection/scam-detection-ai/
+collection: scam-detection-ai
+---
+
+This collection contains the source code for the Scam Detection AI, a project that aims to detect and prevent scams from various sources like emails, SMS, and fake news.
diff --git a/collections/scam-detection-ai/message_analyzer.py b/collections/scam-detection-ai/message_analyzer.py
new file mode 100644
index 000000000000..5c2c56912dae
--- /dev/null
+++ b/collections/scam-detection-ai/message_analyzer.py
@@ -0,0 +1,63 @@
+import re
+
+def analyze_message(message_text):
+ """
+ Analyzes an SMS or other short message for potential scam indicators.
+
+ Args:
+ message_text: The full text of the message.
+
+ Returns:
+ A dictionary containing the analysis results.
+ """
+ scam_indicators = {
+ "shortened_urls": 0,
+ "unusual_sender": 0,
+ "urgent_requests": 0,
+ "prize_offers": 0
+ }
+
+ # Check for shortened URLs
+ shortened_url_patterns = [r'bit\.ly', r't\.co', r'goo\.gl', r'tinyurl\.com']
+ for pattern in shortened_url_patterns:
+ if re.search(pattern, message_text):
+ scam_indicators["shortened_urls"] = 1
+ break
+
+ # Check for unusual sender (e.g., non-numeric sender ID)
+ # This is a very basic check and would need to be improved.
+ sender_match = re.search(r'From:\s*(\S+)', message_text, re.IGNORECASE)
+ if sender_match:
+ sender = sender_match.group(1)
+ if not sender.isdigit() and len(sender) > 10:
+ scam_indicators["unusual_sender"] = 1
+
+ # Check for urgent requests
+ urgent_keywords = ["urgent", "verify", "confirm", "login", "account"]
+ for keyword in urgent_keywords:
+ if re.search(r'\b' + keyword + r'\b', message_text, re.IGNORECASE):
+ scam_indicators["urgent_requests"] = 1
+ break
+
+ # Check for prize offers
+ prize_keywords = ["congratulations", "winner", "prize", "claim", "won"]
+ for keyword in prize_keywords:
+ if re.search(r'\b' + keyword + r'\b', message_text, re.IGNORECASE):
+ scam_indicators["prize_offers"] = 1
+ break
+
+ return scam_indicators
+
+if __name__ == '__main__':
+ sample_message = """
+ From: 555-123-4567
+ Congratulations! You've won a $1000 gift card. Click here to claim: http://bit.ly/fake-prize
+ """
+ analysis = analyze_message(sample_message)
+ print(analysis)
+
+ total_score = sum(analysis.values())
+ if total_score >= 2:
+ print("\nThis message is likely a scam!")
+ else:
+ print("\nThis message seems legitimate.")
diff --git a/collections/scam-detection-ai/static/app.js b/collections/scam-detection-ai/static/app.js
new file mode 100644
index 000000000000..35d26bd44897
--- /dev/null
+++ b/collections/scam-detection-ai/static/app.js
@@ -0,0 +1,2 @@
+// This is a placeholder for your PWA's javascript.
+console.log("Scam Detection AI PWA is running.");
diff --git a/collections/scam-detection-ai/static/manifest.json b/collections/scam-detection-ai/static/manifest.json
new file mode 100644
index 000000000000..5cc27d451507
--- /dev/null
+++ b/collections/scam-detection-ai/static/manifest.json
@@ -0,0 +1,20 @@
+{
+ "name": "Scam Detection AI",
+ "short_name": "Scam AI",
+ "start_url": "/",
+ "display": "standalone",
+ "background_color": "#ffffff",
+ "theme_color": "#000000",
+ "icons": [
+ {
+ "src": "images/icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ]
+}
diff --git a/collections/scam-detection-ai/static/styles.css b/collections/scam-detection-ai/static/styles.css
new file mode 100644
index 000000000000..317bd3ce55dc
--- /dev/null
+++ b/collections/scam-detection-ai/static/styles.css
@@ -0,0 +1,4 @@
+/* This is a placeholder for your PWA's styles. */
+body {
+ background-color: #f0f0f0;
+}
diff --git a/collections/scam-detection-ai/static/sw.js b/collections/scam-detection-ai/static/sw.js
new file mode 100644
index 000000000000..58d566bcef63
--- /dev/null
+++ b/collections/scam-detection-ai/static/sw.js
@@ -0,0 +1,29 @@
+const CACHE_NAME = 'scam-detection-ai-cache-v1';
+const urlsToCache = [
+ '/',
+ '/static/styles.css', // Assuming you'll have a stylesheet
+ '/static/app.js' // Assuming you'll have some javascript
+];
+
+self.addEventListener('install', event => {
+ event.waitUntil(
+ caches.open(CACHE_NAME)
+ .then(cache => {
+ console.log('Opened cache');
+ return cache.addAll(urlsToCache);
+ })
+ );
+});
+
+self.addEventListener('fetch', event => {
+ event.respondWith(
+ caches.match(event.request)
+ .then(response => {
+ if (response) {
+ return response;
+ }
+ return fetch(event.request);
+ }
+ )
+ );
+});
diff --git a/collections/scam-detection-ai/templates/index.html b/collections/scam-detection-ai/templates/index.html
new file mode 100644
index 000000000000..2ecab4ec6ff4
--- /dev/null
+++ b/collections/scam-detection-ai/templates/index.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+ Scam Detection AI
+
+
+
+
+
+
+
+
+
diff --git a/collections/scam-detection-ai/templates/result.html b/collections/scam-detection-ai/templates/result.html
new file mode 100644
index 000000000000..9e181daccb3c
--- /dev/null
+++ b/collections/scam-detection-ai/templates/result.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+ Analysis Result
+
+
+
+ {{ analysis_type }} Analysis Result
+
+
{{ 'This ' + analysis_type.lower() + ' is likely a scam!' if is_scam else 'This ' + analysis_type.lower() + ' seems legitimate.' }}
+
+ {% for indicator, value in analysis.items() %}
+ {% if indicator != 'domain_analysis' %}
+ - {{ indicator.replace('_', ' ')|title }}: {{ 'Detected' if value else 'Not Detected' }}
+ {% endif %}
+ {% endfor %}
+
+ {% if analysis.domain_analysis %}
+
Domain Analysis
+
+ {% for domain, status in analysis.domain_analysis.items() %}
+ - {{ domain }}: {{ status }}
+ {% endfor %}
+
+ {% endif %}
+
+
+ Analyze another message or email
+
+
diff --git a/collections/scam-detection-ai/templates/results_list.html b/collections/scam-detection-ai/templates/results_list.html
new file mode 100644
index 000000000000..2b6e229da92c
--- /dev/null
+++ b/collections/scam-detection-ai/templates/results_list.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+ Fetched Email Analysis
+
+
+
+ Fetched Email Analysis
+ {% if emails %}
+ {% for email in emails %}
+
+
Subject: {{ email.subject }}
+
From: {{ email.from }}
+
{{ 'This email is likely a scam!' if email.is_scam else 'This email seems legitimate.' }}
+
+ {% for indicator, value in email.analysis.items() %}
+ {% if indicator != 'domain_analysis' %}
+ - {{ indicator.replace('_', ' ')|title }}: {{ 'Detected' if value else 'Not Detected' }}
+ {% endif %}
+ {% endfor %}
+
+ {% if email.analysis.domain_analysis %}
+
Domain Analysis
+
+ {% for domain, status in email.analysis.domain_analysis.items() %}
+ - {{ domain }}: {{ status }}
+ {% endfor %}
+
+ {% endif %}
+
+ {% endfor %}
+ {% else %}
+ Could not fetch or analyze emails. Please check your credentials and try again.
+ {% endif %}
+
+ Back to Home
+
+
diff --git a/collections/scam-detection-ai/test_email_analyzer.py b/collections/scam-detection-ai/test_email_analyzer.py
new file mode 100644
index 000000000000..4301ed83fec8
--- /dev/null
+++ b/collections/scam-detection-ai/test_email_analyzer.py
@@ -0,0 +1,45 @@
+import unittest
+from email_analyzer import analyze_email
+
+class TestEmailAnalyzer(unittest.TestCase):
+
+ def test_scam_email(self):
+ scam_email = """
+ From: Urgent Winner
+ Subject: Action Required: You have won a prize!
+
+ Dear customer,
+
+ You have won a lottery! To claim your prize, please send your bank account details and a payment of $50 for processing fees.
+ Click this link to proceed: http://fake-prize.com/claim
+
+ This is a limited time offer, it will expire in 24 hours.
+ """
+ analysis = analyze_email(scam_email)
+ self.assertEqual(analysis['urgency'], 1)
+ self.assertEqual(analysis['generic_greeting'], 1)
+ self.assertEqual(analysis['suspicious_links'], 1)
+ self.assertEqual(analysis['payment_requests'], 1)
+ self.assertEqual(analysis['domain_analysis']['fake-prize.com'], 'Malicious')
+
+ def test_legitimate_email(self):
+ legitimate_email = """
+ From: John Doe
+ Subject: Project Update
+
+ Hi Team,
+
+ Here is the update on our project. I've attached the weekly report.
+ Let's discuss it in our meeting tomorrow.
+
+ Best,
+ John
+ """
+ analysis = analyze_email(legitimate_email)
+ self.assertEqual(analysis['urgency'], 0)
+ self.assertEqual(analysis['generic_greeting'], 0)
+ self.assertEqual(analysis['suspicious_links'], 0)
+ self.assertEqual(analysis['payment_requests'], 0)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/collections/scam-detection-ai/test_message_analyzer.py b/collections/scam-detection-ai/test_message_analyzer.py
new file mode 100644
index 000000000000..c008dcb09145
--- /dev/null
+++ b/collections/scam-detection-ai/test_message_analyzer.py
@@ -0,0 +1,20 @@
+import unittest
+from message_analyzer import analyze_message
+
+class TestMessageAnalyzer(unittest.TestCase):
+
+ def test_scam_message(self):
+ scam_message = "Congratulations! You've won a prize. Click http://bit.ly/scam to claim."
+ analysis = analyze_message(scam_message)
+ self.assertEqual(analysis['shortened_urls'], 1)
+ self.assertEqual(analysis['prize_offers'], 1)
+
+ def test_legitimate_message(self):
+ legitimate_message = "Your appointment is confirmed for 3 PM tomorrow."
+ analysis = analyze_message(legitimate_message)
+ self.assertEqual(analysis['shortened_urls'], 0)
+ self.assertEqual(analysis['prize_offers'], 0)
+ self.assertEqual(analysis['urgent_requests'], 0)
+
+if __name__ == '__main__':
+ unittest.main()