-
Notifications
You must be signed in to change notification settings - Fork 0
redeem fix #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
redeem fix #41
Changes from 86 commits
56e44f8
82db2b0
579683d
fad6d1a
a12de82
5d79afe
0f3af89
d5d90f6
cbf5fcd
5a5d1d5
207ba9b
76b9912
366b640
ebc7bb7
be9a086
3fc9146
914b789
938886f
7737a2f
3ea0d45
ee4de2a
3ae0527
25dc303
730dc88
bb266bd
7d70a13
d1f450d
5436727
d8c850e
1405787
1ad53b1
3956aed
a0b1f82
a2d0cea
6adf5b1
57df8ef
6bbabff
7672520
d56e12e
5aca8cf
f0cb455
dd0ffab
4f534c8
9095db5
979acca
008f0e0
c09bdcc
1cb53f6
ee60426
56967e2
cfcf2dd
1aa6813
5844084
4a6a8e5
693bfbc
326928e
a80e583
69800d3
365ef8e
61d9dcf
046c52f
7b33d13
638fb4e
59a7722
4a09f0b
99b9642
15efb3c
6ca3832
08355e7
0d7bb86
484caaf
a45dcfc
478e8ea
6ad992d
2fcaa47
4e39aa1
01b85b8
7a1ee84
8589ceb
0f9441b
ca487ed
a7b0ddf
9a96471
dc502bd
3646a03
f8f4f78
3766fed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to Chat Yapper are documented here. | ||
|
|
||
| ## v1.3.3 (Latest) | ||
| - twitch redeem fix | ||
| - two new voice effects | ||
| - new filter for @user messages | ||
|
|
||
| ## v1.3.2 | ||
| - Fix to edge-tts | ||
|
|
||
| ## v1.3.1 | ||
| - **New Features:** | ||
| - Twitch fix | ||
| - Allow random avatar assignment | ||
| - More fonts to select from | ||
|
|
||
| ## v1.3.0 | ||
| - Better control of avatar placement in Avatar Layout Editor | ||
| - Select and Adjust speaking animations for crowd mode | ||
| - Added idle animations for crowd mode | ||
|
|
||
| ## v1.2.2 | ||
| - Quick status view | ||
| - Limit concurrent TTS messages | ||
| - Some more twitch fixes and improved notifications | ||
|
|
||
| ## v1.2.1 | ||
| - Usernames for chat bubbles | ||
| - Text size adjustment | ||
| - Toggle for only allowing redeem messages for Twitch | ||
| - Twitch token refresh (should fix auth issues) | ||
|
|
||
| ## v1.2.0 | ||
| - Chat bubbles above avatars | ||
| - Pop-up mode for avatars | ||
| - Linux standalone build (x64) | ||
| - Improved audio quality (reduced crackling) | ||
| - Docker multi-architecture support (amd64, arm64) | ||
| - Better audio preloading and buffering | ||
| - High-quality ffmpeg audio processing | ||
| - GitHub Container Registry (GHCR) for Docker images | ||
| - Automated cross-platform builds via GitHub Actions | ||
|
|
||
| ## v1.1.2 | ||
| - Stability fixes | ||
| - MSI installation for Windows | ||
| - Light mode theme | ||
| - Cleaned up settings UI | ||
|
|
||
| ## v1.0.0 | ||
| - GIF and WebP support for animated avatars | ||
| - Customizable speaking glow effects (color, opacity, size, enable/disable) | ||
| - Message history and replay system (stores 100 recent messages) | ||
| - Export/Import configuration system (backup/restore settings, voices, and avatars) | ||
| - Persistent voice caching for all TTS providers (MonsterTTS, Google Cloud, Amazon Polly, Edge TTS) | ||
| - Audio filters | ||
| - Docker Support | ||
|
|
||
| ## v0.1.0 | ||
| - Initial release | ||
| - Avatars page | ||
| - Settings page | ||
| - TTS selection | ||
| - Avatar positioning | ||
| - Basic Twitch integration |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -138,33 +138,31 @@ def should_process_message( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (should_process, filtered_text) - tuple indicating if message should be processed and the filtered text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| filtering = settings.get("messageFiltering", {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not filtering.get("enabled", True): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return True, text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check Twitch channel point redeem filter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check Twitch channel point redeem filter first — this applies regardless of | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # whether general message filtering is enabled or disabled. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| twitch_settings = settings.get("twitch", {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| redeem_filter = twitch_settings.get("redeemFilter", {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if redeem_filter.get("enabled", False): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allowed_redeem_names = redeem_filter.get("allowedRedeemNames", []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if allowed_redeem_names: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if message has a msg-param-reward-name tag (the redeem name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Also check custom-reward-id to confirm it's a redeem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| custom_reward_id = tags.get("custom-reward-id", "") if tags else "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reward_name = tags.get("msg-param-reward-name", "") if tags else "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not custom_reward_id: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # No redeem ID means this is a regular message, not a channel point redeem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info(f"Skipping message from {username} - not from a channel point redeem") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return False, text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if the redeem name is in the allowed list (case-insensitive) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not any(reward_name.lower() == allowed_name.lower() for allowed_name in allowed_redeem_names): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info(f"Skipping message from {username} - redeem name '{reward_name}' not in allowed list") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return False, text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info(f"Processing message from {username} - redeem name '{reward_name}' is allowed") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Twitch IRC PRIVMSG tags include custom-reward-id (UUID) for channel point redeems, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # but do NOT include the reward title/name. Name-based filtering is not possible | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # from IRC events alone, so we filter only on the presence of custom-reward-id. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Exception: the built-in "Highlight My Message" reward uses msg-id=highlighted-message | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # instead of custom-reward-id, so we treat that as a valid redeem too. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| custom_reward_id = tags.get("custom-reward-id", "") if tags else "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| msg_id = (tags.get("msg-id", "") or "") if tags else "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_highlight = msg_id.lower() == "highlighted-message" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not custom_reward_id and not is_highlight: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # No redeem ID means this is a regular chat message, not a channel point redeem | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info(f"Skipping message from {username} - not from a channel point redeem") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return False, text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info(f"Processing channel point redeem from {username} (reward-id: {custom_reward_id or 'highlighted-message'})") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # but do NOT include the reward title/name. Name-based filtering is not possible | |
| # from IRC events alone, so we filter only on the presence of custom-reward-id. | |
| # Exception: the built-in "Highlight My Message" reward uses msg-id=highlighted-message | |
| # instead of custom-reward-id, so we treat that as a valid redeem too. | |
| custom_reward_id = tags.get("custom-reward-id", "") if tags else "" | |
| msg_id = (tags.get("msg-id", "") or "") if tags else "" | |
| is_highlight = msg_id.lower() == "highlighted-message" | |
| if not custom_reward_id and not is_highlight: | |
| # No redeem ID means this is a regular chat message, not a channel point redeem | |
| logger.info(f"Skipping message from {username} - not from a channel point redeem") | |
| return False, text | |
| logger.info(f"Processing channel point redeem from {username} (reward-id: {custom_reward_id or 'highlighted-message'})") | |
| # but do NOT include the reward title/name. To preserve backend filtering support | |
| # with the existing settings shape, we enforce the allowlist using redeem | |
| # identifiers available in IRC tags rather than reward titles. | |
| # Exception: the built-in "Highlight My Message" reward uses | |
| # msg-id=highlighted-message instead of custom-reward-id, so we treat that as | |
| # a valid redeem with the identifier "highlighted-message". | |
| custom_reward_id = (tags.get("custom-reward-id", "") or "") if tags else "" | |
| msg_id = (tags.get("msg-id", "") or "") if tags else "" | |
| is_highlight = msg_id.lower() == "highlighted-message" | |
| redeem_identifier = custom_reward_id or ("highlighted-message" if is_highlight else "") | |
| if not redeem_identifier: | |
| # No redeem ID means this is a regular chat message, not a channel point redeem | |
| logger.info(f"Skipping message from {username} - not from a channel point redeem") | |
| return False, text | |
| allowed_redeem_names = redeem_filter.get("allowedRedeemNames", []) or [] | |
| normalized_allowed_redeems = { | |
| str(allowed_redeem).strip().lower() | |
| for allowed_redeem in allowed_redeem_names | |
| if str(allowed_redeem).strip() | |
| } | |
| if normalized_allowed_redeems and redeem_identifier.lower() not in normalized_allowed_redeems: | |
| logger.info( | |
| f"Skipping channel point redeem from {username} - reward-id not allowed: {redeem_identifier}" | |
| ) | |
| return False, text | |
| logger.info( | |
| f"Processing channel point redeem from {username} (reward-id: {redeem_identifier})" | |
| ) |
Copilot
AI
Apr 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New skipMentions filtering and the updated Twitch redeem handling are not covered by unit tests. There are existing pytest tests for this module, but none exercise should_process_message(). Adding tests for (a) redeemFilter enabled/disabled with/without custom-reward-id/highlighted-message, and (b) skipMentions on/off would help prevent regressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
underwaterandvibratofilters were added to_has_enabled_filters(),_build_filters(), and_build_random_filters(), but the existingbackend/tests/test_audio_filters.pysuite doesn’t cover these new filter types (it currently asserts only reverb/pitch/speed behavior). Adding tests that assert the expected ffmpeg filter strings are produced for both deterministic and random modes would help prevent regressions.