Skip to content

Commit bcf0eb5

Browse files
steveseguinactions-user
authored andcommitted
feat(twitch): Add support for multiple subscriber languages
Recognize Twitch subscriber badges based on localized text in the badge `alt` attribute. This improves the reliability of identifying subscribers for features like TTS regardless of the user's language settings on Twitch. * Adds checks for common subscriber terms in Spanish, French, German, Italian, Portuguese, Dutch, Swedish, Russian, Chinese, and Korean within `sources/twitch.js`. * Updates manifest version and configuration files. * Includes minor error handling adjustment in `popup.js` (TTSManager). [auto-enhanced]
1 parent a6e98a4 commit bcf0eb5

6 files changed

Lines changed: 65 additions & 25 deletions

File tree

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "Social Stream Ninja",
33
"description": "Powerful tooling to engage live chat on Youtube, Twitch, Zoom, and more.",
44
"manifest_version": 3,
5-
"version": "3.25.13",
5+
"version": "3.25.14",
66
"homepage_url": "http://socialstream.ninja/",
77
"icons": {
88
"128": "icons/icon-128.png"

popup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3797,7 +3797,7 @@ const TTSManager = { // this is for testing the audio I think; not for managing
37973797
if (contentType && contentType.includes("application/json")) {
37983798
const errorData = await response.json();
37993799
//console.log(errorData);
3800-
throw new Error(errorData?.message || errorData?.detail?.message || errorData?.error || `HTTP error! status: ${response.status}`);
3800+
throw new Error(errorData?.message || errorData?.detail?.message || errorData?.error?.message || errorData?.error || `HTTP error! status: ${response.status}`);
38013801
}
38023802
throw new Error(`HTTP error! status: ${response.status}`);
38033803
}

settings/config_0.json

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@
2424
"mobile": false,
2525
"platform": "Windows",
2626
"fullVersionList": [
27-
{ "brand": "Google Chrome", "version": "137.0.7151.69" },
28-
{ "brand": "Chromium", "version": "137.0.7151.69" },
27+
{ "brand": "Google Chrome", "version": "137.0.7151.122" },
28+
{ "brand": "Chromium", "version": "137.0.7151.122" },
2929
{ "brand": "Not/A)Brand", "version": "24.0.0.0" }
3030
],
3131
"architecture": "x86",
3232
"bitness": "64",
3333
"model": "",
3434
"platformVersion": "10.0.0",
35-
"uaFullVersion": "137.0.7151.69",
35+
"uaFullVersion": "137.0.7151.122",
3636
"wow64": false,
3737
"enhancedHeaders": true
3838
},
@@ -66,15 +66,15 @@
6666
"mobile": false,
6767
"platform": "Windows",
6868
"fullVersionList": [
69-
{ "brand": "Google Chrome", "version": "137.0.7151.69" },
70-
{ "brand": "Chromium", "version": "137.0.7151.69" },
69+
{ "brand": "Google Chrome", "version": "137.0.7151.122" },
70+
{ "brand": "Chromium", "version": "137.0.7151.122" },
7171
{ "brand": "Not/A)Brand", "version": "24.0.0.0" }
7272
],
7373
"architecture": "x86",
7474
"bitness": "64",
7575
"model": "",
7676
"platformVersion": "10.0.0",
77-
"uaFullVersion": "137.0.7151.69",
77+
"uaFullVersion": "137.0.7151.122",
7878
"wow64": false,
7979
"enhancedHeaders": true
8080
},
@@ -114,15 +114,15 @@
114114
"mobile": false,
115115
"platform": "Windows",
116116
"fullVersionList": [
117-
{ "brand": "Google Chrome", "version": "137.0.7151.69" },
118-
{ "brand": "Chromium", "version": "137.0.7151.69" },
117+
{ "brand": "Google Chrome", "version": "137.0.7151.122" },
118+
{ "brand": "Chromium", "version": "137.0.7151.122" },
119119
{ "brand": "Not/A)Brand", "version": "24.0.0.0" }
120120
],
121121
"architecture": "x86",
122122
"bitness": "64",
123123
"model": "",
124124
"platformVersion": "10.0.0",
125-
"uaFullVersion": "137.0.7151.69",
125+
"uaFullVersion": "137.0.7151.122",
126126
"wow64": false,
127127
"enhancedHeaders": true
128128
},
@@ -146,15 +146,15 @@
146146
"mobile": false,
147147
"platform": "Windows",
148148
"fullVersionList": [
149-
{ "brand": "Google Chrome", "version": "137.0.7151.69" },
150-
{ "brand": "Chromium", "version": "137.0.7151.69" },
149+
{ "brand": "Google Chrome", "version": "137.0.7151.122" },
150+
{ "brand": "Chromium", "version": "137.0.7151.122" },
151151
{ "brand": "Not/A)Brand", "version": "24.0.0.0" }
152152
],
153153
"architecture": "x86",
154154
"bitness": "64",
155155
"model": "",
156156
"platformVersion": "10.0.0",
157-
"uaFullVersion": "137.0.7151.69",
157+
"uaFullVersion": "137.0.7151.122",
158158
"wow64": false,
159159
"enhancedHeaders": true
160160
},
@@ -178,15 +178,15 @@
178178
"mobile": false,
179179
"platform": "Windows",
180180
"fullVersionList": [
181-
{ "brand": "Google Chrome", "version": "137.0.7151.69" },
182-
{ "brand": "Chromium", "version": "137.0.7151.69" },
181+
{ "brand": "Google Chrome", "version": "137.0.7151.122" },
182+
{ "brand": "Chromium", "version": "137.0.7151.122" },
183183
{ "brand": "Not/A)Brand", "version": "24.0.0.0" }
184184
],
185185
"architecture": "x86",
186186
"bitness": "64",
187187
"model": "",
188188
"platformVersion": "10.0.0",
189-
"uaFullVersion": "137.0.7151.69",
189+
"uaFullVersion": "137.0.7151.122",
190190
"wow64": false,
191191
"enhancedHeaders": true
192192
},
@@ -304,15 +304,15 @@
304304
"mobile": false,
305305
"platform": "Windows",
306306
"fullVersionList": [
307-
{ "brand": "Google Chrome", "version": "137.0.7151.69" },
308-
{ "brand": "Chromium", "version": "137.0.7151.69" },
307+
{ "brand": "Google Chrome", "version": "137.0.7151.122" },
308+
{ "brand": "Chromium", "version": "137.0.7151.122" },
309309
{ "brand": "Not/A)Brand", "version": "24.0.0.0" }
310310
],
311311
"architecture": "x86",
312312
"bitness": "64",
313313
"model": "",
314314
"platformVersion": "10.0.0",
315-
"uaFullVersion": "137.0.7151.69",
315+
"uaFullVersion": "137.0.7151.122",
316316
"wow64": false,
317317
"enhancedHeaders": true
318318
},
@@ -322,7 +322,11 @@
322322
"size": {
323323
"width": 1280,
324324
"height": 720
325-
}
325+
},
326+
"preload": "kasada",
327+
"preserveAntiBot": false,
328+
"monitorAntiBot": false,
329+
"useSystemBrowser": false
326330
},
327331
"wss": {
328332
"size": {

sources/twitch.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,30 @@
363363
if (subtitle && subtitle.endsWith("-Month") && (subtitle!=="1-Month")){
364364
subtitle+="s";
365365
}
366+
} else if (badge.alt && badge.alt.includes("Suscriptor")){
367+
subscriber = "Suscriptor";
368+
} else if (badge.alt && badge.alt.includes("Abonné")){
369+
subscriber = "Abonné";
370+
} else if (badge.alt && badge.alt.includes("Abonnent")){
371+
subscriber = "Abonnent";
372+
} else if (badge.alt && badge.alt.includes("Abbonato")){
373+
subscriber = "Abbonato";
374+
} else if (badge.alt && badge.alt.includes("Assinante")){
375+
subscriber = "Assinante";
376+
} else if (badge.alt && badge.alt.includes("Abonnee")){
377+
subscriber = "Abonnee";
378+
} else if (badge.alt && badge.alt.includes("Prenumerant")){
379+
subscriber = "Prenumerant";
380+
} else if (badge.alt && badge.alt.includes("Подписчик")){
381+
subscriber = "Подписчик";
382+
} else if (badge.alt && badge.alt.includes("订阅者")){
383+
subscriber = "订阅者";
384+
} else if (badge.alt && badge.alt.includes("購読者")){
385+
subscriber = "購読者";
386+
} else if (badge.alt && badge.alt.includes("구독자")){
387+
subscriber = "구독자";
366388
}
389+
367390
if (badge.srcset) {
368391
let bb = badge.srcset.split("https://").pop();
369392
if (bb) {

sources/websocket/bilibili.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,7 @@ <h3>System Logs</h3>
506506
window.messageBridge.broadcast({
507507
type: "bilibili",
508508
event: "viewer_update",
509-
meta: popularity,
510-
textonly: true
509+
meta: popularity
511510
});
512511
}
513512
break;

tts.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,13 +1475,27 @@ TTS.googleTTS = function(tts) {
14751475

14761476
try {
14771477
const url = "https://texttospeech.googleapis.com/v1beta1/text:synthesize?key=" + TTS.GoogleAPIKey;
1478+
1479+
// Smart language code extraction from voice name
1480+
let languageCode = TTS.googleSettings.lang || TTS.speechLang;
1481+
const voiceName = TTS.googleSettings.voiceName || "en-GB-Standard-A";
1482+
1483+
// If no explicit language is set but we have a voice name, extract language from it
1484+
if (!TTS.googleSettings.lang && TTS.googleSettings.voiceName) {
1485+
// Voice names follow pattern: languageCode-variantName (e.g., en-GB-Chirp3-HD-Laomedeia)
1486+
const voiceMatch = voiceName.match(/^([a-z]{2}-[A-Z]{2})/);
1487+
if (voiceMatch) {
1488+
languageCode = voiceMatch[1];
1489+
}
1490+
}
1491+
14781492
var data = {
14791493
input: {
14801494
text: tts
14811495
},
14821496
voice: {
1483-
languageCode: TTS.googleSettings.lang || TTS.speechLang,
1484-
name: TTS.googleSettings.voiceName || "en-GB-Standard-A",
1497+
languageCode: languageCode,
1498+
name: voiceName,
14851499
ssmlGender: TTS.voiceGender ? TTS.voiceGender.toUpperCase() : "FEMALE"
14861500
},
14871501
audioConfig: {

0 commit comments

Comments
 (0)