diff --git a/backend/server.js b/backend/server.js
index 3d3edb8..c63b5fb 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -687,6 +687,77 @@ function sanitizeProfileNumber(value) {
return parsed;
}
+function applyProfileVariantTemplates(text, profileNumber) {
+ if (typeof text !== 'string' || !text) {
+ return text || '';
+ }
+
+ const normalizedProfileNumber = sanitizeProfileNumber(profileNumber);
+ let result = text.replace(/\{Profil(?:e)?-(\d+)(?:-(\d+))?\?\s*"([\s\S]*?)"(?:\s*:\s*"([\s\S]*?)")?\}/gi, (match, startStr, endStr, ifText, elseText) => {
+ if (!normalizedProfileNumber) {
+ return '';
+ }
+
+ const start = parseInt(startStr, 10);
+ const end = endStr ? parseInt(endStr, 10) : start;
+ if (Number.isNaN(start) || Number.isNaN(end)) {
+ return '';
+ }
+
+ const lower = Math.min(start, end);
+ const upper = Math.max(start, end);
+ if (normalizedProfileNumber < lower || normalizedProfileNumber > upper) {
+ return elseText || '';
+ }
+ return ifText || '';
+ });
+
+ result = result.replace(/\{Profil(?:e)?-(\d+)(?:-(\d+))?:([\s\S]*?)\}/gi, (match, startStr, endStr, content) => {
+ if (!normalizedProfileNumber) {
+ return '';
+ }
+
+ const start = parseInt(startStr, 10);
+ const end = endStr ? parseInt(endStr, 10) : start;
+ if (Number.isNaN(start) || Number.isNaN(end)) {
+ return '';
+ }
+
+ const lower = Math.min(start, end);
+ const upper = Math.max(start, end);
+ if (normalizedProfileNumber < lower || normalizedProfileNumber > upper) {
+ return '';
+ }
+ return content;
+ });
+
+ return result;
+}
+
+function applyRandomNumberTemplates(text) {
+ if (typeof text !== 'string' || !text) {
+ return text || '';
+ }
+
+ return text.replace(/\{ZUFALL-(-?\d+)-(-?\d+)\}/gi, (match, startStr, endStr) => {
+ const start = parseInt(startStr, 10);
+ const end = parseInt(endStr, 10);
+ if (Number.isNaN(start) || Number.isNaN(end)) {
+ return match;
+ }
+
+ const lower = Math.min(start, end);
+ const upper = Math.max(start, end);
+ const span = upper - lower + 1;
+ if (span <= 0) {
+ return String(lower);
+ }
+
+ const value = Math.floor(Math.random() * span) + lower;
+ return String(value);
+ });
+}
+
function normalizeDeadline(value) {
if (!value && value !== 0) {
return null;
@@ -5059,13 +5130,8 @@ app.delete('/api/search-posts', (req, res) => {
app.get('/api/profile-state', (req, res) => {
try {
const scopeId = req.profileScope;
- let profileNumber = getScopedProfileNumber(scopeId);
- if (!profileNumber) {
- profileNumber = 1;
- setScopedProfileNumber(scopeId, profileNumber);
- }
-
- res.json({ profile_number: profileNumber });
+ const profileNumber = getScopedProfileNumber(scopeId);
+ res.json({ profile_number: profileNumber || null });
} catch (error) {
res.status(500).json({ error: error.message });
}
@@ -5469,10 +5535,9 @@ app.post('/api/posts/:postId/check', (req, res) => {
didChange = true;
}
- let profileValue = sanitizeProfileNumber(profile_number);
+ let profileValue = sanitizeProfileNumber(profile_number) || getScopedProfileNumber(req.profileScope);
if (!profileValue) {
- const storedProfile = getScopedProfileNumber(req.profileScope);
- profileValue = storedProfile || requiredProfiles[0];
+ return res.status(400).json({ error: 'Profil muss zuerst ausgewählt werden.' });
}
const completedRows = db.prepare('SELECT profile_number FROM checks WHERE post_id = ?').all(postId);
@@ -5620,10 +5685,9 @@ app.post('/api/check-by-url', (req, res) => {
didChange = true;
}
- let profileValue = sanitizeProfileNumber(profile_number);
+ let profileValue = sanitizeProfileNumber(profile_number) || getScopedProfileNumber(req.profileScope);
if (!profileValue) {
- const storedProfile = getScopedProfileNumber(req.profileScope);
- profileValue = storedProfile || requiredProfiles[0];
+ return res.status(400).json({ error: 'Profil muss zuerst ausgewählt werden.' });
}
const completedRows = db.prepare('SELECT profile_number FROM checks WHERE post_id = ?').all(post.id);
@@ -6673,10 +6737,11 @@ app.post('/api/ai/generate-comment', async (req, res) => {
}
let promptPrefix = settings.prompt_prefix || '';
+ const normalizedProfileNumber = sanitizeProfileNumber(profileNumber);
// Get friend names for the profile if available
- if (profileNumber) {
- const friends = db.prepare('SELECT friend_names FROM profile_friends WHERE profile_number = ?').get(profileNumber);
+ if (normalizedProfileNumber) {
+ const friends = db.prepare('SELECT friend_names FROM profile_friends WHERE profile_number = ?').get(normalizedProfileNumber);
if (friends && friends.friend_names) {
promptPrefix = promptPrefix.replace('{FREUNDE}', friends.friend_names);
} else {
@@ -6686,6 +6751,12 @@ app.post('/api/ai/generate-comment', async (req, res) => {
promptPrefix = promptPrefix.replace('{FREUNDE}', '');
}
+ const today = new Date();
+ const todayDisplay = today.toLocaleDateString('de-DE');
+ promptPrefix = promptPrefix.replaceAll('{DATUM}', todayDisplay);
+ promptPrefix = applyRandomNumberTemplates(promptPrefix);
+ promptPrefix = applyProfileVariantTemplates(promptPrefix, normalizedProfileNumber);
+
// Try each active credential until one succeeds
let lastError = null;
const attemptDetails = [];
diff --git a/extension/content.js b/extension/content.js
index 858ad15..60c33c4 100644
--- a/extension/content.js
+++ b/extension/content.js
@@ -17,6 +17,7 @@ const SEARCH_RESULTS_PATH_PREFIX = '/search';
const FEED_HOME_PATHS = ['/', '/home.php'];
const sessionSearchRecordedUrls = new Set();
const sessionSearchInfoCache = new Map();
+let profileSelectionNoticeShown = false;
function isOnSearchResultsPage() {
try {
@@ -49,6 +50,19 @@ function maybeRedirectPageReelsToMain() {
if (typeof pathname !== 'string') {
return false;
}
+ if (pathname.toLowerCase() === '/profile.php') {
+ const params = new URLSearchParams(location.search || '');
+ const profileId = params.get('id');
+ const sk = params.get('sk');
+ if (profileId && sk && sk.toLowerCase().startsWith('reel')) {
+ const targetUrl = `${location.origin}/profile.php?id=${encodeURIComponent(profileId)}`;
+ if (location.href !== targetUrl) {
+ location.replace(targetUrl);
+ return true;
+ }
+ return false;
+ }
+ }
const match = pathname.match(/^\/([^/]+)\/reels\/?$/i);
if (!match) {
return false;
@@ -513,6 +527,10 @@ async function getProfileNumber() {
console.warn('[FB Tracker] Failed to resolve profile number from backend:', error);
}
+ if (!profileSelectionNoticeShown) {
+ profileSelectionNoticeShown = true;
+ showToast('Bitte zuerst ein Profil im Tracker auswählen.', 'error');
+ }
return null;
}
diff --git a/extension/popup.html b/extension/popup.html
index 147efca..687ea6c 100644
--- a/extension/popup.html
+++ b/extension/popup.html
@@ -112,6 +112,7 @@