Skip to content

Conversation

@EthanThePhoenix38
Copy link
Member

Nouvelle version du site

… digests

Major overhaul of AI-Pulse into a fully configurable, personalized news reader:

- config.json: externalized 12 categories (AI, Cybersecurity, IoT, Windows, Mac,
  Linux, Tech, Entrepreneurship, Finance, Crypto, Open Source, Products) with 112
  RSS sources in FR/EN, bilingual labels, and keyword mappings
- aggregator.js: config-driven, franc-min language detection, article deduplication
  (70% Dice similarity), local Readability reader, RSS feed generation (global +
  per-category), email digests via Resend API
- readme-viewer.html: section navigation sidebar with scroll spy, preferences panel
  (language, categories, keywords, article count slider), DOM-based filtering
- reader.html: back button in article info bar
- tracker.js: preferences manager, read history, bookmarks manager (localStorage)
- All pages: portfolio moved from nav to footer, added "Proposer une source" and
  "S'abonner" links in footer pointing to GitHub Issue templates
- Issue templates: source submission (new-source.yml) and subscription (subscribe.yml)
- Workflows: add-source.yml (auto-add approved sources), manage-subscriber.yml
  (auto-add subscribers), update-ai-pulse.yml (API_RESEND env var)
- Email digest: HTML template with personalized content per subscriber preferences

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a13d20ac0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@EthanThePhoenix38
Copy link
Member Author

@copilot Corrige le check qui n'a pas marché.

Copy link
Contributor

Copilot AI commented Feb 5, 2026

@EthanThePhoenix38 I've opened a new pull request, #58, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces a major upgrade to the AI-Pulse news aggregator, transforming it from a hardcoded system to a fully configurable, multi-language platform with email subscriptions and enhanced user personalization.

Changes:

  • Implemented a configuration-driven architecture using config.json with 12 content categories and multi-language support
  • Added email digest functionality with subscriber management via GitHub issues and Resend API integration
  • Introduced client-side preferences system with language filtering, category selection, keyword search, and read history tracking
  • Added RSS feed generation for global and per-category subscriptions

Reviewed changes

Copilot reviewed 32 out of 33 changed files in this pull request and generated 31 comments.

Show a summary per file
File Description
config.json New centralized configuration defining categories, feeds, language labels, and settings
src/aggregator.js Major refactor: added language detection (franc-min), deduplication, RSS/email generation, and config-driven feed processing
templates/email-digest.html New HTML email template for subscriber digests
readme-viewer.html Enhanced with preferences panel, category filtering, language selection, and read history tracking
reader.html Added back button for improved navigation
js/tracker.js Extended with PrefsManager, ReadHistory, and Bookmarks managers for cross-page persistence
package.json Added franc-min dependency for language detection
.github/workflows/manage-subscriber.yml New workflow to automatically process subscription requests via GitHub issues
.github/workflows/add-source.yml New workflow to automatically add approved RSS sources to config.json
.github/workflows/update-ai-pulse.yml Updated to include API_RESEND secret for email functionality
.github/ISSUE_TEMPLATE/*.yml New issue templates for subscriptions and source suggestions
stats.html, privacy.html, index.html, app.html, about.html Footer updates: moved Portfolio to footer, added subscription/source suggestion links
feed*.xml Generated RSS feed files for global and per-category subscriptions
data/subscribers.json New empty subscribers list file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 401 to 458
for (const subscriber of subscribers) {
try {
// Filter articles based on subscriber preferences
let filteredSections = [];
const subCategories = subscriber.categories || Object.keys(CATEGORIES);
const subLang = subscriber.lang || 'all';

for (const cat of subCategories) {
const articles = categorizedArticles[cat];
if (!articles || articles.length === 0) continue;

let filtered = articles;
if (subLang !== 'all') {
filtered = articles.filter(a => a.lang === subLang);
}
filtered = filtered.slice(0, 5);
if (filtered.length === 0) continue;

const catConfig = CATEGORIES[cat];
const label = subLang === 'fr' ? catConfig.labels.fr : catConfig.labels.en;

const articlesHtml = filtered.map(a =>
`<tr><td style="padding:10px 0;border-bottom:1px solid #1a1e47;">
<a href="https://thephoenixagency.github.io/AI-Pulse/app.html?url=${encodeURIComponent(a.link)}&title=${encodeURIComponent(a.title)}&source=${encodeURIComponent(a.source)}" style="color:#00d9ff;text-decoration:none;font-weight:600;">${a.title}</a>
<br><span style="color:#94a3b8;font-size:13px;">${a.source} | ${a.lang.toUpperCase()}</span>
</td></tr>`
).join('');

filteredSections.push(`<tr><td style="padding:20px 0 10px;"><h2 style="color:#00d9ff;margin:0;font-size:18px;">${label}</h2></td></tr>${articlesHtml}`);
}

if (filteredSections.length === 0) continue;

const emailHtml = template
.replace('{{DATE}}', today)
.replace('{{SECTIONS}}', filteredSections.join(''))
.replace('{{EMAIL}}', subscriber.email)
.replace(/{{UNSUB_URL}}/g, `https://github.com/ThePhoenixAgency/AI-Pulse/issues/new?template=unsubscribe.yml&title=Unsubscribe:+${encodeURIComponent(subscriber.email)}`);

// Send via Resend
const response = await axios.post('https://api.resend.com/emails', {
from: 'AI-Pulse <noreply@resend.dev>',
to: [subscriber.email],
subject: `AI-Pulse Digest - ${today}`,
html: emailHtml
}, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});

console.error(` Email sent to ${subscriber.email}: ${response.data.id}`);
} catch (error) {
console.error(` Failed to send email to ${subscriber.email}: ${error.message}`);
}
}
}
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The email sending loop doesn't implement rate limiting or batch processing. If there are many subscribers, this could hit API rate limits or cause performance issues. Consider implementing batch processing with delays between batches to respect API limits and avoid overwhelming the email service.

Copilot uses AI. Check for mistakes.
return langMap[code] || code;
};
} catch (e) {
console.error('franc-min not available, using feed-declared language only');
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The franc-min package is used for language detection, but there's no verification that this package is being properly installed. The error handling only logs to stderr but doesn't inform the user how to fix the issue. Consider adding a more informative message suggesting to run "npm install" if the package is missing.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

- type: dropdown
id: language
attributes:
label: Langue preferee / Preferred language
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The French word "preferee" is missing accents. It should be "préférée".

Suggested change
label: Langue preferee / Preferred language
label: Langue préférée / Preferred language

Copilot uses AI. Check for mistakes.
<h4>Langue / Language</h4>
<select id="prefLang">
<option value="all">Toutes / All</option>
<option value="fr">Francais</option>
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The word "Francais" is missing the cedilla. It should be "Français" to be spelled correctly in French.

Suggested change
<option value="fr">Francais</option>
<option value="fr">Français</option>

Copilot uses AI. Check for mistakes.
Comment on lines 139 to 156
const lang = detectedLang || feedLang || 'en';

// Try to fetch and extract content if it doesn't exist
if (!fs.existsSync(localPath)) {
try {
const response = await axios.get(articleUrl, { timeout: 8000, headers: { 'User-Agent': 'AI-Pulse/2.0' } });
const response = await axios.get(articleUrl, { timeout: 8000, headers: { 'User-Agent': 'AI-Pulse/3.0' } });
const dom = new JSDOM(response.data, { url: articleUrl });
const reader = new Readability(dom.window.document);
const articleContent = reader.parse();

if (articleContent && articleContent.textContent) {
const cleanHtml = `
<!DOCTYPE html>
<html lang="en">
// Detect language from full content if not yet determined
if (!detectedLang) {
detectedLang = detectLang(articleContent.textContent.slice(0, 500));
}

const cleanHtml = `<!DOCTYPE html>
<html lang="${lang}">
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The HTML lang attribute uses a variable that might contain a franc-min language code (ISO 639-3) that hasn't been mapped. The langMap only covers 12 common languages, but franc-min can return many other 3-letter codes. If an unmapped code is returned, it will be set as the lang attribute (e.g., 'pol' for Polish), which is not a valid HTML lang attribute value. HTML requires ISO 639-1 (2-letter) codes. Consider defaulting to 'en' for unmapped codes: const lang = detectedLang || feedLang || 'en'; should check if detectedLang is in a whitelist of valid 2-letter codes first.

Copilot uses AI. Check for mistakes.
- type: dropdown
id: category
attributes:
label: Categorie / Category
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The French word "Categorie" is missing an accent. It should be "Catégorie".

Suggested change
label: Categorie / Category
label: Catégorie / Category

Copilot uses AI. Check for mistakes.
Comment on lines +114 to +122
- name: Commit changes
run: |
git config --global user.name 'PhoenixProject-AutoSync'
git config --global user.email '${{ secrets.GIT_AUTHOR_EMAIL }}'
git add config.json
if ! git diff --cached --exit-code; then
git commit -m "Add new source from issue #${{ github.event.issue.number }}"
git push
fi
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The workflow has write permissions to contents and issues, and automatically commits changes based on user input from issue forms. A malicious user could potentially craft an issue that, when labeled, causes the workflow to commit malicious content to config.json. While there is a label requirement ('source-approved'), repository maintainers should be extremely careful about which issues they label, as this triggers automatic code commits. Consider adding additional validation steps or requiring manual review before auto-committing, or implement a pull request workflow instead of direct commits.

Suggested change
- name: Commit changes
run: |
git config --global user.name 'PhoenixProject-AutoSync'
git config --global user.email '${{ secrets.GIT_AUTHOR_EMAIL }}'
git add config.json
if ! git diff --cached --exit-code; then
git commit -m "Add new source from issue #${{ github.event.issue.number }}"
git push
fi
- name: Create pull request for config update
uses: peter-evans/create-pull-request@v6
with:
commit-message: "Add new source from issue #${{ github.event.issue.number }}"
title: "Add new source from issue #${{ github.event.issue.number }}"
body: |
This pull request was automatically generated from issue #${{ github.event.issue.number }} after it was labeled 'source-approved'.
Please review the changes to config.json before merging.
branch: "auto/add-source-${{ github.event.issue.number }}"
add-paths: |
config.json

Copilot uses AI. Check for mistakes.
<!-- Header -->
<tr><td style="padding:30px 20px;text-align:center;border-bottom:1px solid rgba(0,217,255,0.2);">
<h1 style="margin:0;color:#00d9ff;font-size:24px;font-weight:700;">AI-Pulse</h1>
<p style="margin:8px 0 0;color:#94a3b8;font-size:14px;">Votre digest personnalise - {{DATE}}</p>
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The email template contains French text "Votre digest personnalise" but "personnalise" is missing the accent on the 'e'. It should be "personnalisé" to be grammatically correct in French.

Copilot uses AI. Check for mistakes.
Vous recevez ce mail car vous etes abonne a AI-Pulse ({{EMAIL}}).
</p>
<p style="margin:0;">
<a href="{{UNSUB_URL}}" style="color:#ef4444;font-size:12px;text-decoration:none;">Se desabonner</a>
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The French text "Se desabonner" is missing an accent. It should be "Se désabonner" for proper French spelling.

Copilot uses AI. Check for mistakes.
@EthanThePhoenix38
Copy link
Member Author

@codex corrige ce qu'il manque

@chatgpt-codex-connector
Copy link

To use Codex here, create an environment for this repo.

Copy link
Contributor

Copilot AI commented Feb 5, 2026

@EthanThePhoenix38 I've opened a new pull request, #59, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Feb 5, 2026

@EthanThePhoenix38 I've opened a new pull request, #60, to work on those changes. Once the pull request is ready, I'll request review from you.

EthanThePhoenix38 and others added 3 commits February 5, 2026 20:09
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@EthanThePhoenix38
Copy link
Member Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Contributor

Copilot AI commented Feb 5, 2026

@EthanThePhoenix38 I've opened a new pull request, #61, to work on those changes. Once the pull request is ready, I'll request review from you.

@EthanThePhoenix38 EthanThePhoenix38 marked this pull request as draft February 5, 2026 19:15
- Add sticky quick-nav bar for fast section jumping
- Improve section visual separation with cards and left border
- Add scroll-margin-top for proper anchor positioning

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- Remove quick-nav styles (not needed)
- Keep improved section separators with cards and left border

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- Remove left sidebar navigation
- Add fixed top bar with dropdown menu for section navigation
- Dropdown shows only filtered categories (or all if no filter)
- Center content area without left margin
- Keep elevator buttons for scroll up/down
- Update responsive styles

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
Deduplication improvements:
- Compare content (summary) in addition to title
- Add contentThreshold config option (default 0.5)
- Mark duplicates if title OR content similar, or both moderately similar

Read articles improvements:
- Normalize URLs for comparison (ignore query params)
- Compare by title in addition to URL
- Add "Déjà lus / Already read" collapsible group
- Add "Hide read articles" preference option
- Style read articles group with purple theme

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- Add flex-wrap to prevent horizontal overflow
- Add max-width and padding for better containment

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
Instead of redirecting to homepage, now goes back to
previous page if available, otherwise to the reader

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
The iframe loading ThePhoenixAgency.github.io was blocked
due to X-Frame-Options. Replaced with a button link that
opens in a new tab.

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- Remove "Auto-updated every 3 hours" mention
- Remove "100% Free & Open Source" from footer
- Keep "Last Update" timestamp as needed

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
@github-actions github-actions bot added the documentation Improvements or additions to documentation label Feb 10, 2026
- Remove "Proposer une source" link (security vulnerability)
- Move ThePhoenixAgency to copyright line
- Add mobile CSS grid (3 columns) for footer links
- Remove dead link @EthanThePhoenix38 from portfolio

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- Nouveau guide de configuration (docs/CONFIG_GUIDE.md)
- README.md réécrit avec structure complète du projet
- index.html documenté avec commentaires détaillés
- app.html documenté avec explications du fonctionnement
- aggregator.js entièrement commenté (chaque fonction expliquée)

Documentation en français, accessible aux débutants, sans jargon technique.

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- css/style.css : Explication des variables, classes, animations
- update-ai-pulse.yml : Guide complet du workflow automatique
  - Explique cron, déclencheurs, étapes, secrets
  - Documentation accessible aux débutants

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
- js/ui.js : Gestion de l'interface (navigation active, curseur)
- js/tracker.js : Statistiques locales, préférences, historique, favoris
  - Explique localStorage et la confidentialité des données
  - Documente chaque méthode de Tracker, PrefsManager, ReadHistory, Bookmarks

Documentation en français accessible aux débutants.

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
Conflits résolus:
- README.md: Pris la version de main (articles récents)
- HTML files: Gardé notre version (documentation + footer corrigé)
- aggregator.js: Gardé notre version documentée
- workflow: Gardé notre version documentée

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
Ajout de commentaires détaillés en français pour :
- about.html : Page à propos avec mission et stack technique
- privacy.html : Politique de confidentialité (RGPD)
- stats.html : Tableau de bord des statistiques locales
- 404.html : Page d'erreur avec redirection automatique
- reader.html : Lecteur d'articles avec iframe sécurisée

Chaque fichier inclut :
- Capsule documentaire complète en en-tête
- Commentaires CSS et JavaScript expliqués
- Descriptions des fonctions et paramètres
- Explications accessibles aux débutants

https://claude.ai/code/session_0138bAjho1fWwiRZju3nJFJ3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants