🎯 Overview
Version 4.0.0 represents a major overhaul of the IFTTT filter script, focusing on:
- Performance optimization (~100x faster entity processing)
- Code cleanup (removal of legacy compatibility layers)
- Enhanced RSS support (proper retweet formatting from rss.app feeds)
- Size reduction (~7KB smaller, more room for future features)
⚠️ BREAKING CHANGES
1. FilterRule API Changes
Removed legacy properties:
- ❌
keywords?: string[](usecontentinstead) - ❌
rule?: FilterRule(use nested filter structures)
Migration:
// BEFORE (v3.x):
{
type: "and",
keywords: ["tech", "AI"]
}
// AFTER (v4.0.0):
{
type: "and",
content: ["tech", "AI"]
}2. URL_REPLACE_FROM - Array Only
Single string format removed:
// BEFORE (v3.x):
URL_REPLACE_FROM: "https://twitter.com/" // ❌ No longer supported
// AFTER (v4.0.0):
URL_REPLACE_FROM: ["https://twitter.com/"] // ✅ Array required3. Cache System Removed
Internal cache system (getCached(), getCachedRegex()) has been removed. Regex compilation is now handled directly with optimized patterns.
Impact: None for users - internal change only.
4. Polyfills Removed
ES5 polyfills for String.prototype.startsWith, String.prototype.endsWith, and Array.from fallbacks have been removed. IFTTT runtime now natively supports these features.
Impact: None - IFTTT environment supports ES6+ features.
✨ New Features
RSS Retweet Formatting Support
Added comprehensive support for retweets from RSS feeds (via rss.app):
Features:
- ✅ Recognizes "RT by @username:" format (rss.app variant)
- ✅ Normalizes duplicate RT prefixes
- ✅ Proper formatting:
RetweetingUser 𝕏📤 https://x.com/OriginalAuthor:
Example:
Input (from rss.app):
EntryTitle: "RT by @UdalostiBrno: RT by @UdalostiBrno: Content..."
EntryAuthor: "@Minarik_CT"
Output:
UdalostiBrno 𝕏📤 https://x.com/Minarik_CT:
Content...
https://x.com/Minarik_CT/status/123
Changes:
- Updated
REPOST_PREFIXregex:/^(RT (?:by )?@([^:]+): )/i - Updated
REPOST_USERregex:/RT (?:by )?(@[a-z0-9_]+)/gi - Updated
RT_PREFIXregex:/^RT\s+(?:by\s+)?@[\w]+/i - Enhanced
formatRepost()with RSS-specific logic - Added duplicate RT prefix normalization in
composeContent()
🚀 Performance Optimizations
1. CHAR_MAP Processing - 100x Faster
Before (v3.x):
- 70 iterations through string per entity
- Complexity: O(n×m) where n=string length, m=entities
- For 500-char post: ~105,000 character comparisons
After (v4.0.0):
- Single-pass regex replacement
- Pre-compiled pattern:
/( |…|&|...)/g - Complexity: O(n) - linear
- For 500-char post: ~500 character comparisons
Performance gain: ~210x faster ⚡
2. HTML Entity Decoding - Single Pass
Created codePointToChar() helper function to eliminate duplicate surrogate pair logic:
Before:
// Decimal entities: full surrogate logic
str = str.replace(/&#(\d+);/g, function(m, dec) {
// ... surrogate pair handling ...
});
// Hex entities: DUPLICATE surrogate logic
str = str.replace(/&#x([0-9a-fA-F]+);/gi, function(m, hex) {
// ... same surrogate pair handling ...
});After:
// Helper function (DRY):
function codePointToChar(cp) {
if (cp > 0xFFFF) { /* surrogate pairs */ }
return String.fromCharCode(cp);
}
// Single unified regex:
str.replace(/&#(?:x([0-9a-fA-F]+)|(\d+));/gi, function(m, hex, dec) {
return codePointToChar(parseInt(hex || dec, hex ? 16 : 10));
});Savings: ~430 characters, cleaner code
3. Unified Filter Matching - Loop-Based
Refactored matchesUnifiedFilter() from 6 duplicate blocks to loop-based approach:
Before (v3.x):
// Block 1: content literal matching
if (rule.content && rule.content.length > 0) {
// ... 8 lines of code ...
}
// Block 2: contentRegex matching
if (rule.contentRegex && rule.contentRegex.length > 0) {
// ... 8 lines of code ...
}
// Blocks 3-6: Same pattern for username, usernameRegex, domain, domainRegexAfter (v4.0.0):
// Single parameterized function called 6 times:
processFilterArrays(lowerStr, rule.content, rule.contentRegex, results);
processFilterArrays(lowerUsername, rule.username, rule.usernameRegex, results);
processFilterArrays(domainStr, rule.domain, rule.domainRegex, results);Savings: ~1217 characters
4. Other Optimizations
- ✅
findLastSentenceEnd()- removed slice/regex operations - ✅
platformConfigs- centralized platform configuration withuseFeedTitleAuthor - ✅
processStatus()- removed redundant ternary operator - ✅ Plus sign Unicode fix:
\uFE63→\uFE62(SMALL PLUS SIGN)
📊 Code Metrics
| Metric | v3.2.1 | v4.0.0 | Change |
|---|---|---|---|
| File Size | ~63 KB | ~56 KB | -7 KB (-11%) |
| Lines of Code | 1,423 | 1,138 | -285 lines (-20%) |
| Functions | 42+ | 30 | -12 functions (-29%) |
| IFTTT Limit | 65 KB | 65 KB | - |
| Available Space | ~2 KB | ~9 KB | +7 KB buffer |
🐛 Bug Fixes
1. Plus Sign Replacement
Issue: Plus signs were incorrectly converted to SMALL HYPHEN-MINUS (﹣) instead of SMALL PLUS SIGN (﹢).
Fixed:
// Before:
str = str.replace(/\+/g, "\uFE63"); // ❌ U+FE63 (looks like minus)
// After:
str = str.replace(/\+/g, "\uFE62"); // ✅ U+FE62 (looks like plus)Impact: C++ now displays as C﹢﹢ (plus) instead of C﹣﹣ (minus)
2. RSS Feed Author Handling
Fixed processContent() to properly use feedUsername fallback when author is empty for RSS feeds.
3. Duplicate RT Prefix Normalization
RSS feeds from rss.app sometimes generate duplicate RT prefixes:
RT by @user: RT by @user: Content
Now automatically normalized to:
RT by @user: Content
🔧 Technical Improvements
1. Platform Configuration System
Introduced centralized platformConfigs object:
const platformConfigs: { [key: string]: PlatformConfig } = {
BS: { handleQuotes: true, useFeedTitleAuthor: true, useGetContent: true },
RSS: { handleRetweets: true, useGetContent: true },
TW: {
handleQuotes: true,
handleReplies: true,
handleRetweets: true,
useFeedTitleAuthor: true,
useParsedText: true
},
YT: { useGetContent: true }
};Benefits:
- Cleaner separation of platform-specific behavior
- Easier to maintain and extend
- Reduced conditional logic throughout codebase
2. Enhanced TypeScript Interfaces
interface PlatformConfig {
handleQuotes?: boolean;
handleReplies?: boolean;
handleRetweets?: boolean;
useFeedTitleAuthor?: boolean;
useGetContent?: boolean;
useParsedText?: boolean;
}3. Improved Helper Functions
New optimized helper functions:
codePointToChar(cp: number): string- Unicode code point conversionprocessFilterArrays()- Unified filter array processing- Optimized
findLastSentenceEnd()- Sentence boundary detection
📝 Migration Guide
Step 1: Update FilterRule Definitions
Search your configuration for keywords property:
// Find and replace:
PHRASES_REQUIRED: [
{ type: "and", keywords: ["tech", "AI"] } // OLD
]
// With:
PHRASES_REQUIRED: [
{ type: "and", content: ["tech", "AI"] } // NEW
]Step 2: Update URL_REPLACE_FROM
If using single string format:
// Change:
URL_REPLACE_FROM: "https://twitter.com/"
// To:
URL_REPLACE_FROM: ["https://twitter.com/"]Step 3: Test Your Configuration
- Deploy to @BetaBot test account
- Monitor 50-100 posts
- Verify:
- Content filtering works correctly
- URL replacement functions as expected
- Retweets format properly (if using RSS feeds)
Step 4: Deploy to Production
Once testing confirms everything works:
- Update all bot configurations
- Deploy script to production accounts
- Monitor for any issues
🧪 Testing
Test Coverage:
- ✅ 204 total tests (all versions 3.0.0 to 3.1.4)
- ✅ 45/45
matchesUnifiedFiltertests passed - ✅ 41/41
findLastSentenceEndtests passed - ✅ RSS retweet formatting validated with real-world data
Validation:
- ✅ Real production data from @Minarik_CT, @Dostal_CT, @Vitaskova_CT feeds
- ✅ All edge cases covered (duplicates, self-reposts, etc.)
📚 Documentation
Updated documentation:
- ✅
Settings_for_IFTTT_filter_script_-_v4_0_0.md - ✅
Unified_Filter_Guide__-_v4_0_0.md - ✅ Migration guide (this document)
🎉 Credits
Development: Daniel Šnor (@zpravobot)
Testing: Production validation on Zprávobot.news network
Special Thanks: Claude AI for optimization suggestions and code review
📦 Files in Release
ifttt-filter-4.0.0.ts- Production script (56 KB)RELEASE_NOTES_v4.0.0.md- This fileMIGRATION_GUIDE_v4.0.0.md- Detailed migration instructions- Test suites (historical compatibility)
🔗 Links
- GitHub Repository: https://github.com/danielsnor/zpravobot.news
- Production Instance: https://zpravobot.news
- Issue Tracker: https://github.com/danielsnor/zpravobot.news/issues
- Previous Release: v3.2.1
📅 Release Timeline
| Date | Event |
|---|---|
| Dec 28, 2025 | Refactoring started (breaking changes planning) |
| Dec 29, 2025 | Optimization phase completed |
| Dec 30, 2025 | RSS retweet formatting implemented |
| Dec 31, 2025 | Tests |
| Jan 1, 2026 | v4.0.0 Released 🚀 |
🔮 What's Next?
Planned for v4.1.0:
- Further documentation updates
- Additional RSS platform enhancements
- Performance monitoring and analytics
Planned for v4.2.0:
- Potential BlueSky API improvements
- Enhanced content filtering options
⚠️ Known Issues
None at release time.
If you encounter any issues, please report them on GitHub Issues.
💬 Feedback
We'd love to hear your feedback! If you're using this script:
- ⭐ Star the repository on GitHub
- 🐛 Report bugs via GitHub Issues
- 💡 Suggest features via GitHub Discussions
- ☕ Support via Ko-fi: ko-fi.com/zpravobot
Thank you for using Zprávobot.news IFTTT Filter Script! 🎉