בקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר
- 
@צדיק-תמים מישהו יודע מה הסיפור של השגיאה הזו?
else if (toDo == 9) { let ans = await call.read([{type: 'text', data: "אנא הקלט משהו"}], "record"); console.log(ans); execFile("python3", ["/public_html/recognize.py",ans], (error, stdout, stderr) => { console.log(stdout); console.log(error); if (error) { console.error(error); call.id_list_message([{type:'text', data: "Error processing audio" }]); return; } console.log("הבעיה כאן! בפלט"); call.id_list_message([{type:'text', data: stdout}]); console.log("הבעיה כאן! בפלט"); }); }זה הקובץ פייתון (מתמלל מצוין, אגב)
from pydub import AudioSegment import speech_recognition as sr from rapidfuzz import process, fuzz import sys, json, tempfile, requests token = "" BASE_URL = f"https://www.call2all.co.il/ym/api/DownloadFile?token={token}&path=ivr2:/" def add_silence(audio_segment): silence = AudioSegment.silent(duration=1000) return silence + audio_segment + silence def recognize_speech(audio_segment): recognizer = sr.Recognizer() with tempfile.NamedTemporaryFile(suffix=".wav", delete=True) as temp_wav: audio_segment.export(temp_wav.name, format="wav") with sr.AudioFile(temp_wav.name) as source: data = recognizer.record(source) try: return recognizer.recognize_google(data, language="he-IL") except sr.UnknownValueError: return "" # לא זוהה דיבור except sr.RequestError as e: return f"Error: {e}" # בעיה עם ה‑API if __name__ == "__main__": # argv[1] = שם הקובץ בתוך ivr2:/ (למשל "1/003.wav") file_name = sys.argv[1] file_url = f"{BASE_URL}{file_name}" # 1️⃣ הורדת הקובץ מהאינטרנט response = requests.get(file_url) if response.status_code != 200: print("Error downloading audio file") sys.exit(1) # 2️⃣ שמירתו זמנית וטעינה עם pydub with tempfile.NamedTemporaryFile(suffix=".wav", delete=True) as temp_audio: temp_audio.write(response.content) temp_audio.flush() audio = AudioSegment.from_file(temp_audio.name, format="wav") # 3️⃣ הוספת שנייה שקט audio = add_silence(audio) # 4️⃣ זיהוי דיבור recognized_text = recognize_speech(audio) # ✅ הדפסת התוצאה print(recognized_text)השגיאה שאני מקבל:
[716b56ab1a7cfd79b974fa0d55f5cbbd65915674]: Cannot send id_list_message after sending response (probably done from uncaughtErrorHandler due to error in asynchronous code after returning response)
אני לא מוצא על איזה id_list_message הוא מתכוון... הוא לא משמיע כלום. גם לא את הid_list_message של השגיאה, בוודאות!
הקטע שהוא רושם ללוג את 2 הטקסטים גם שלפני הid_list_message וגם שאחרי, ז"א שהריצה לא מסתיימת.
 - 
מצרף את הקוד המלא אם זה יעזור למישהו לעזור לי...
import { YemotRouter } from 'yemot-router2'; import {sendRequest, mainextPath} from '../utils/utils_func.js'; import '../utils/type.js'; import {execFile} from 'child_process'; /** @param {import('yemot-router2').Call} call */ export async function callHandler (call) { console.log("מכין בקשה"); // מקבל את כל ההעדפות של המאזין const params = new URLSearchParams({ phone: call.ApiPhone.replace("+972","0") }); const url = `https://stamandsefer.co.il/appart/new/getTzintukSubcrib.php?${params}`; /** @type {AdResponse} */ let responseSubscribe = await sendRequest(call ,url, "אירעה שגיאה בעת מציאת רישום להתראה"); console.log("responseSubscribe: ", responseSubscribe); // יוצר פרמטרים לשליחה לקבלת כל המודעות שלא נקראו על פי ההעדפות הנ"ל let sumAds = 0; for (let element of makeAdsParams(responseSubscribe, call)) { //console.log("נכנס ללולאה"); if(element.betShemesh == null) {element.betShemesh = ""}; // מכל שורת פרמטרים מקבל את המודעות /** @type {AdResponse} */ let responseAds = await sendRequest(call ,`https://stamandsefer.co.il/appart/new/getBuyerAds.php?${new URLSearchParams(element)}`, "אירעה שגיאה בעת מציאת מודעות"); //console.log("responseAds: ", responseAds); sumAds = sumAds + responseAds.count; }; // אם אין מודעות בכלל עובר לשלוחה ראשית if (sumAds==0) { call.go_to_folder("/1/1"); } for (let index = 0; index < 3; index++) { let toDo = await call.read([{type:"text", data:`יש ${sumAds} התראות חדשות למעבר לשמיעת ההתראות הקש 1 למעבר לשאר השלוחות 2`}], 'tap', {min_digits: 1, digits_allowed: [1,2, 9, "*0"], typing_playback_mode: 'No'}); if (toDo == 1) { call.go_to_folder("/1/1/3"); } else if (toDo == 2 || toDo == "*0") { call.go_to_folder(mainextPath); } else if (toDo == 9) { let ans = await call.read([{type: 'text', data: "אנא הקלט משהו"}], "record"); console.log(ans); execFile("python3", ["/home/node.stamandsefer.co.il/public_html/recognize.py",ans], (error, stdout, stderr) => { console.log(stdout); if (error) { console.error(error); call.id_list_message([{type:'text', data: "Error processing audio" }]); return; } console.log("הבעיה כאן! בפלט"); call.id_list_message([{type:'text', data: ` התוצאה היא ${stdout}`}]); console.log("הבעיה כאן! בפלט"); }); } } call.go_to_folder("/1/1"); } /***************************************** */ /** @param {AdResponse} res @param {import('yemot-router2').Call} call */ function makeAdsParams(res, call) { if (!res || !Array.isArray(res.data)) return []; let ads = []; /** @type {AdData[]} */ for (const adBase of res.data) { // עיבוד מודעה let paramsOfAd = {}; // מוסיף לכל שדה קיים את הערך לאובייקט const allowedFields = ['buyorrent', 'city', 'betShemesh', 'region', 'room']; for (const key of allowedFields) { if (adBase[key] !== undefined && adBase[key] !== null) { paramsOfAd[key] = adBase[key]; } } paramsOfAd.phone = call.ApiPhone.replace("+972", "0"); if (paramsOfAd.room) { paramsOfAd.room = paramsOfAd.room.toString().replace(".0",""); } ads.push(paramsOfAd); } return ads; } /***************************************** */ /** @param {AdResponse} res*/ function makeAds(res) { const adsData = res?.data ?? res?.results; if (!Array.isArray(adsData)) return []; let ad = [], tempAd; for (const adBase of adsData) { tempAd = `המודעה היא דירה ל${adBase.buyorrent} ב${adBase.city} `; if (adBase.city === "בית שמש") tempAd += `ה${adBase.betShemesh} `; tempAd += `${adBase.room} חדרים בשכונה ${adBase.region} ברחוב ${adBase.street} מספר ${adBase.number} קומה ${adBase.floor} במחיר ${adBase.price} טלפון ליצירת קשר ${adBase.phone} `; if (adBase.phone2) tempAd += ` טלפון נוסף ${adBase.phone2}`; tempAd = tempAd.replace(".0","").replace(".5"," וחצי").replace("-","מינוס "); console.log(tempAd); ad.push({ad: tempAd, adId: adBase.id}); } return ad; } - 
@צדיק-תמים מישהו יודע מה הסיפור של השגיאה הזו?
else if (toDo == 9) { let ans = await call.read([{type: 'text', data: "אנא הקלט משהו"}], "record"); console.log(ans); execFile("python3", ["/public_html/recognize.py",ans], (error, stdout, stderr) => { console.log(stdout); console.log(error); if (error) { console.error(error); call.id_list_message([{type:'text', data: "Error processing audio" }]); return; } console.log("הבעיה כאן! בפלט"); call.id_list_message([{type:'text', data: stdout}]); console.log("הבעיה כאן! בפלט"); }); }זה הקובץ פייתון (מתמלל מצוין, אגב)
from pydub import AudioSegment import speech_recognition as sr from rapidfuzz import process, fuzz import sys, json, tempfile, requests token = "" BASE_URL = f"https://www.call2all.co.il/ym/api/DownloadFile?token={token}&path=ivr2:/" def add_silence(audio_segment): silence = AudioSegment.silent(duration=1000) return silence + audio_segment + silence def recognize_speech(audio_segment): recognizer = sr.Recognizer() with tempfile.NamedTemporaryFile(suffix=".wav", delete=True) as temp_wav: audio_segment.export(temp_wav.name, format="wav") with sr.AudioFile(temp_wav.name) as source: data = recognizer.record(source) try: return recognizer.recognize_google(data, language="he-IL") except sr.UnknownValueError: return "" # לא זוהה דיבור except sr.RequestError as e: return f"Error: {e}" # בעיה עם ה‑API if __name__ == "__main__": # argv[1] = שם הקובץ בתוך ivr2:/ (למשל "1/003.wav") file_name = sys.argv[1] file_url = f"{BASE_URL}{file_name}" # 1️⃣ הורדת הקובץ מהאינטרנט response = requests.get(file_url) if response.status_code != 200: print("Error downloading audio file") sys.exit(1) # 2️⃣ שמירתו זמנית וטעינה עם pydub with tempfile.NamedTemporaryFile(suffix=".wav", delete=True) as temp_audio: temp_audio.write(response.content) temp_audio.flush() audio = AudioSegment.from_file(temp_audio.name, format="wav") # 3️⃣ הוספת שנייה שקט audio = add_silence(audio) # 4️⃣ זיהוי דיבור recognized_text = recognize_speech(audio) # ✅ הדפסת התוצאה print(recognized_text)השגיאה שאני מקבל:
[716b56ab1a7cfd79b974fa0d55f5cbbd65915674]: Cannot send id_list_message after sending response (probably done from uncaughtErrorHandler due to error in asynchronous code after returning response)
אני לא מוצא על איזה id_list_message הוא מתכוון... הוא לא משמיע כלום. גם לא את הid_list_message של השגיאה, בוודאות!
הקטע שהוא רושם ללוג את 2 הטקסטים גם שלפני הid_list_message וגם שאחרי, ז"א שהריצה לא מסתיימת.
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
זה הקובץ פייתון (מתמלל מצוין, אגב)
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
return recognizer.recognize_google(data, language="he-IL")ברור שזה מזהה מצוין, כי זה STT של גוגל והשרת עושה 0 עגול של עבודה
 - 
@צדיק-תמים
{
"name": "real-estate-brokerage-platform",
"version": "0.0.1",
"main": "app.js",
"private": "true",
"scripts": {
"start": "node app.js"
},
"keywords": [],
"author": "eido taib",
"license": "UNLICENSED",
"type": "module",
"dependencies": {
"express": "^4.21.2",
"yemot-router2": "file:.."
}
}node_modules]# ls -l yemot-router2
lrwxrwxrwx. 1 root root 5 Oct 30 16:44 yemot-router2 -> ../.. - 
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
זה הקובץ פייתון (מתמלל מצוין, אגב)
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
return recognizer.recognize_google(data, language="he-IL")ברור שזה מזהה מצוין, כי זה STT של גוגל והשרת עושה 0 עגול של עבודה
@צדיק-תמים כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
זה הקובץ פייתון (מתמלל מצוין, אגב)
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
return recognizer.recognize_google(data, language="he-IL")ברור שזה מזהה מצוין, כי זה STT של גוגל והשרת עושה 0 עגול של עבודה
נכון, אני ממש מבסוט מזה שלא צריך להסתבךעם ספריות ותלויות, רק מקוה שלא יחסמו את זה יום אחד...
 - 
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
"yemot-router2": "file:.."
תסיר את yemot-router2 ותתקין מחדש מnpm
@צדיק-תמים כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
"yemot-router2": "file:.."
תסיר את yemot-router2 ותתקין מחדש מnpm
זה מה שעשיתי וזה השתנה למשהו אחר.
אבל לענין הכי בוער אין לך תשובה? זה ממש מתסכל... אולי איך שהספריה עובדת מאחורי הקלעים?
 - 
@צדיק-תמים כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
"yemot-router2": "file:.."
תסיר את yemot-router2 ותתקין מחדש מnpm
זה מה שעשיתי וזה השתנה למשהו אחר.
אבל לענין הכי בוער אין לך תשובה? זה ממש מתסכל... אולי איך שהספריה עובדת מאחורי הקלעים?
 - 
@צדיק-תמים מה ששלחתי מקודם זה כל הקוד.
הענין הוא שאין שם שום call.idוכו' לפני כן... - 
@צדיק-תמים מה ששלחתי מקודם זה כל הקוד.
הענין הוא שאין שם שום call.idוכו' לפני כן... - 
@עידו300 השגיאה נזרקת כשאקספרס מסמן שכבר נשלחו לקליינט הheaders, אתה צריך לבדוק איפה קודם אתה מחזיר תשובה בדרך כלשהיא
@צדיק-תמים אין...
 - 
ב"ה מצאתי את הבעיה והוא כבר לא זורק שגיאה.
אבל עכשיו יש בעיה מוזרה...
מסיבה לא ברורה הוא לא מחכה שתגיע תשובה מהסקריפט הנ"ל אלא ממשיך הלאה ורק אח"כ מגיעה התשובה, מה שגורם לזה שהפלט למשתמש וללוג מגיע בלי התשובה...
השתמשתי בawait כמובן.let textFromSpeech=""; let ans = await call.read([{type: 'text', data: "אנא הקלט משהו"}], "record"); **console.log(ans);** await execFile("python3", ["/home/node.stamandsefer.co.il/public_html/recognize.py",ans], (error, stdout, stderr) => { // console.log(stdout); textFromSpeech = stdout; **console.log(textFromSpeech);** if (error) { console.error(error); call.id_list_message([{type:'text', data: "Error processing audio" }]); return; } }); **console.log(` התוצאה היא ${textFromSpeech}`);** call.id_list_message([{type:'text', data: ` התוצאה היא ${textFromSpeech}`}]);ניסיתי לסמן את הקונסולים בשביל ההבנה. בעצם מה שמגיע זה
"1/021.wav"
"התוצאה היא"
והתוצאה שהגיעה...
לא לפי הסדר (כמו שאמר כאן @צדיק-תמים שהawait לא חוסם את זה לגמרי). - 
ב"ה מצאתי את הבעיה והוא כבר לא זורק שגיאה.
אבל עכשיו יש בעיה מוזרה...
מסיבה לא ברורה הוא לא מחכה שתגיע תשובה מהסקריפט הנ"ל אלא ממשיך הלאה ורק אח"כ מגיעה התשובה, מה שגורם לזה שהפלט למשתמש וללוג מגיע בלי התשובה...
השתמשתי בawait כמובן.let textFromSpeech=""; let ans = await call.read([{type: 'text', data: "אנא הקלט משהו"}], "record"); **console.log(ans);** await execFile("python3", ["/home/node.stamandsefer.co.il/public_html/recognize.py",ans], (error, stdout, stderr) => { // console.log(stdout); textFromSpeech = stdout; **console.log(textFromSpeech);** if (error) { console.error(error); call.id_list_message([{type:'text', data: "Error processing audio" }]); return; } }); **console.log(` התוצאה היא ${textFromSpeech}`);** call.id_list_message([{type:'text', data: ` התוצאה היא ${textFromSpeech}`}]);ניסיתי לסמן את הקונסולים בשביל ההבנה. בעצם מה שמגיע זה
"1/021.wav"
"התוצאה היא"
והתוצאה שהגיעה...
לא לפי הסדר (כמו שאמר כאן @צדיק-תמים שהawait לא חוסם את זה לגמרי). - 
@ע-ה-דכו-ע לא מגדיר
רק מה שכתוב בקוד הנ"ל ובimport {execFile} from 'child_process'; - 
@ע-ה-דכו-ע לא מגדיר
רק מה שכתוב בקוד הנ"ל ובimport {execFile} from 'child_process';@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@ע-ה-דכו-ע לא מגדיר
רק מה שכתוב בקוד הנ"ל ובimport {execFile} from 'child_process';תייבא ככה
תנסה לשנות לזה
import { execFile } from 'child_process/promises';לא מאה אחוז שזה קשור, אבל אני חושב.
 - 
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@ע-ה-דכו-ע לא מגדיר
רק מה שכתוב בקוד הנ"ל ובimport {execFile} from 'child_process';תייבא ככה
תנסה לשנות לזה
import { execFile } from 'child_process/promises';לא מאה אחוז שזה קשור, אבל אני חושב.
@ע-ה-דכו-ע כשכותבים ככה הוא זורק שגיאה
 - 
@ע-ה-דכו-ע כשכותבים ככה הוא זורק שגיאה
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@ע-ה-דכו-ע כשכותבים ככה הוא זורק שגיאה
נכון, צודק, זה מצריך לכתוב גם את המשך הקוד בתחביר קצת שונה של Promise, לא יודע כרגע לכתוב לך את הקוד הזה מחדש בצורה המתוקנת.
 - 
ב"ה מצאתי את הבעיה והוא כבר לא זורק שגיאה.
אבל עכשיו יש בעיה מוזרה...
מסיבה לא ברורה הוא לא מחכה שתגיע תשובה מהסקריפט הנ"ל אלא ממשיך הלאה ורק אח"כ מגיעה התשובה, מה שגורם לזה שהפלט למשתמש וללוג מגיע בלי התשובה...
השתמשתי בawait כמובן.let textFromSpeech=""; let ans = await call.read([{type: 'text', data: "אנא הקלט משהו"}], "record"); **console.log(ans);** await execFile("python3", ["/home/node.stamandsefer.co.il/public_html/recognize.py",ans], (error, stdout, stderr) => { // console.log(stdout); textFromSpeech = stdout; **console.log(textFromSpeech);** if (error) { console.error(error); call.id_list_message([{type:'text', data: "Error processing audio" }]); return; } }); **console.log(` התוצאה היא ${textFromSpeech}`);** call.id_list_message([{type:'text', data: ` התוצאה היא ${textFromSpeech}`}]);ניסיתי לסמן את הקונסולים בשביל ההבנה. בעצם מה שמגיע זה
"1/021.wav"
"התוצאה היא"
והתוצאה שהגיעה...
לא לפי הסדר (כמו שאמר כאן @צדיק-תמים שהawait לא חוסם את זה לגמרי).@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
לא לפי הסדר (כמו שאמר כאן @צדיק-תמים שהawait לא חוסם את זה לגמרי).
זה לא מה שאמרתי.
 - 
@עידו300 כבר כתבתי לך פעם ללמוד איך אסינכרוניות עובדת...
await רק מעכב את השורות הבאות, לא תוקע את התוכנה, וכיוון שזה בפונקציה אנונימית זה לא יעכב את המעבר לשורה הבאה
תכלס הawait פה הוא רק לסמן שזה משהו ארוך, למעיישה חסר גם async בהגדרה של הפונקציית חץ@צדיק-תמים כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
await רק מעכב את השורות הבאות, לא תוקע את התוכנה, וכיוון שזה בפונקציה אנונימית זה לא יעכב את המעבר לשורה הבאה
ככה הבנתי
 - 
@עידו300 כתב בבקשת מידע | פעולה אחרי id_listוכו' בימות ראוטר:
@ע-ה-דכו-ע כשכותבים ככה הוא זורק שגיאה
נכון, צודק, זה מצריך לכתוב גם את המשך הקוד בתחביר קצת שונה של Promise, לא יודע כרגע לכתוב לך את הקוד הזה מחדש בצורה המתוקנת.
@ע-ה-דכו-ע אז GPT הביא לי תיקון:
הבעיה בקוד שלך היא שקריאת
execFileהיא אסינכרונית, ולכן הפקודהconsole.log(` התוצאה היא ${textFromSpeech}`); call.id_list_message([...]);מתבצעת לפני שהפונקציה הפנימית של
execFileסיימה לרוץ — כלומר, לפני ש־textFromSpeechעודכן בפועל.כדי לתקן זאת, יש לעטוף את
execFileב־Promiseולחכות לה באמצעותawait.כך זה צריך להיראות:
import { execFile } from 'child_process'; import { promisify } from 'util'; const execFileAsync = promisify(execFile); let textFromSpeech = ""; let ans = await call.read([{ type: 'text', data: "אנא הקלט משהו" }], "record"); console.log("ans:", ans); try { // מריץ את הסקריפט פייתון וממתין לתוצאה const { stdout } = await execFileAsync("python3", [ "/home/node.stamandsefer.co.il/public_html/recognize.py", ans ]); textFromSpeech = stdout.trim(); // הסר רווחים ושורות מיותרות console.log(`התוצאה היא: ${textFromSpeech}`); await call.id_list_message([ { type: 'text', data: `התוצאה היא ${textFromSpeech}` } ]); } catch (error) { console.error("Error:", error); await call.id_list_message([ { type: 'text', data: "אירעה שגיאה בעיבוד האודיו" } ]); }הסבר קצר:
- 
promisify(execFile)הופך את הפונקציה לגרסה תואמת ל־await. - 
השורה
await execFileAsync(...)גורמת לקוד להמתין עד שפייתון יסיים לעבד את הקלט ויחזיר פלט. - 
לאחר מכן אתה יכול להשתמש בתוצאה בביטחון, בלי שהקוד ירוץ מוקדם מדי.
 
אם תרצה — אפשר להוסיף גם טיפול במקרה שהקלט
ansלא מכיל נתיב לקובץ תקין או שההקלטה נכשלה.די כמו שאמרת
תודה רבה לכולם -