Telegram Speaker

[SNOLAB] Speak latest telegram message With TTS technology just in your browser. @deprecated Use my new script [SNOLAB] I Heard Telegram Speaking

  1. // ==UserScript==
  2. // @deprecated Use my new script [SNOLAB] I Heard Telegram Speaking
  3. // @name Telegram Speaker
  4. // @namespace https://userscript.snomiao.com/
  5. // @author snomiao@gmail.com
  6. // @version 0.1.3
  7. // @description [SNOLAB] Speak latest telegram message With TTS technology just in your browser. @deprecated Use my new script [SNOLAB] I Heard Telegram Speaking
  8. // @match https://*.telegram.org/z/
  9. // @grant none
  10. // @run-at document-start
  11. // @license GPL-3.0+
  12. // @supportURL https://github.com/snomiao/userscript.js/issues
  13. // @contributionURL https://snomiao.com/donate
  14. // ==/UserScript==
  15.  
  16. /*
  17. # the legacy way needs you to install and run an saying pipe service in your computer, in which situation that you don't have latest browser with TTS technologies.
  18.  
  19. npm i -g piserve snosay
  20. piserve | snosay --voice "Microsoft Huihui Desktop"
  21.  
  22. */
  23.  
  24. async function say(s) {
  25. if (!s) return; // console.error('say empty msg')
  26.  
  27. // new method to say
  28. console.log("saying " + s);
  29. if (globalThis.speechSynthesis) {
  30. // wait for voices
  31. while (speechSynthesis.getVoices().length === 0) {
  32. await new Promise((r) => setTimeout(r, 1e3));
  33. }
  34. const utter = new SpeechSynthesisUtterance(s);
  35. utter.voice = speechSynthesis
  36. .getVoices()
  37. .filter(({ lang }) => navigator.languages.includes(lang))
  38. .reverse()[0];
  39. utter.rate = Math.min(Math.max(1, s.length / 60), 4);
  40. if (speechSynthesis.speaking) speechSynthesis.cancel();
  41. speechSynthesis.speak(utter);
  42. } else await fetch("http://localhost:25971/?text=" + encodeURIComponent(s));
  43. }
  44. const lastMsg = () =>
  45. [...document.querySelectorAll(".Message:not(.own) .text-content")]
  46. .map((e) => e.textContent)
  47. .reverse()[0];
  48. const chagnedFilterMaker = (init) => (e) => e !== init ? (init = e) : undefined;
  49. const changedFilter = chagnedFilterMaker("");
  50. const looper = () => (say(changedFilter(lastMsg())), 1);
  51.  
  52. (async function () {
  53. while (looper()) await new Promise((r) => setTimeout(r, 1000));
  54. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址