יש לי מערכת שאני גורם לה להתקשר למערכת אחרת (לא בימות ככה"נ)
ושם להקיש מספר הקשות.
אני צריך להמתין מספר שניות (להודעת הכותרת של המערכת ההיא)
אח"כ להקיש כמה ספרות, להמתין שוב ולהקיש עוד כמה ספרות.
ניסיתי להשתמש ב-send_dtmf
זה עובד יחסית כמו שצריך, הבעיה היא שנראה שההגדרה הזו לא בדיוק מפותחת...
ניתן להגדיר שם כמה לחכות בין הקשה להקשה (נראה שזה לא פועל בדיוק כפי ההגדרה, אבל עם זה איכשהו הסתדרתי..)
מה שעשיתי זה שבכניסה למערכת מוגדרת GO_TO_FOLDER ויש שם קובץ M0000 עם שקט למשך כמה שניות שצריך לפני ההקשה הראשונה.
עד כאן עובד.
ניסיתי גם לפני ההמתנה הבאה לעשות שוב את אותו תהליך אבל אם יש הגדרה של send_dtmf הוא מתחיל את השלוחה הבאה עוד לפני שהוא גומר את ההקשות(!) וממילא אני לא יכול להגדיר כמה זמן לעשות את ההמתנה השנייה.
ניסיתי גם להעלות למערכת קבצים של DTMF שמצאתי (בויקיפדיה יש ובעוד כמה אתרים), היה לי איזשהו קו שעליו זה עבד (במערכות של ימות זה עובד לכאו'), אבל במערכת המדוברת זה לא עובד.
עשיתי ג"כ קוד בגוגל סקריפט שמעלה למערכת קובץ עם הקשות והמתנה בין ההקשות, הוא גם לא מקיש במערכת ההיא,
איך אוכל לעשות שזה יעבוד????
מצורף הקוד:
// שימוש לדוגמה
function createExampleDTMFWAV() {
const digits = '1231234'; // ההקשות לביצוע
const pauses = [5000, 500, 500, 500, 2000, 500, 500, 500]; // אלפיות שניה להמתנה בין כל הקשה
const wavBlob = createDTMFWAV(digits, pauses); // יצירת הקובץ
uploadFile("ivr2:בדיקה/M1012.wav", wavBlob); // העלאה למערכת
}
/**
* יוצר קובץ WAV עם צלילי DTMF וזמן שקט.
*
* @param {string} digits - מחרוזת ספרות להמרה לצלילי DTMF.
* @param {Array<number>} pauses - מערך של משכי הפסקה באלפיות שניות בין הספרות.
* @return {Blob} - קובץ ה-WAV כ-Blob.
*/
function createDTMFWAV(digits, pauses) {
const dtmfFrequencies = {
'1': [697, 1209],
'2': [697, 1336],
'3': [697, 1477],
'4': [770, 1209],
'5': [770, 1336],
'6': [770, 1477],
'7': [852, 1209],
'8': [852, 1336],
'9': [852, 1477],
'0': [941, 1336],
'*': [941, 1209],
'#': [941, 1477]
};
const sampleRate = 8000; // 8 kHz
const toneDuration = 250; // 250 אלפיות השנייה עבור כל צליל DTMF
const amplitude = 32767; // Maximum amplitude for 16-bit audio
let samples = [];
for (let i = 0; i < digits.length; i++) {
// הוסף שקט לפני הטון הראשון ובין צלילים
let pauseDuration = (i === 0) ? pauses[0] : pauses[i];
if (pauseDuration > 0) {
let pauseSamples = Math.floor((pauseDuration / 1000) * sampleRate);
samples = samples.concat(new Array(pauseSamples).fill(0));
}
// צור צליל DTMF
let freqs = dtmfFrequencies[digits[i]];
if (freqs) {
let numSamples = Math.floor((toneDuration / 1000) * sampleRate);
for (let j = 0; j < numSamples; j++) {
let sampleValue = amplitude * Math.sin(2 * Math.PI * freqs[0] * j / sampleRate)
+ amplitude * Math.sin(2 * Math.PI * freqs[1] * j / sampleRate);
samples.push(sampleValue / 2); // ודא שהאות המשולב נמצא בטווח של 16 סיביות
}
}
}
// המרת דגימות ל-16 סיביות PCM
let buffer = new ArrayBuffer(samples.length * 2); // 2 בתים לדגימה
let view = new DataView(buffer);
for (let i = 0; i < samples.length; i++) {
view.setInt16(i * 2, samples[i], true); // Little-endian
}
// Create WAV file header
let wavBuffer = new ArrayBuffer(44 + buffer.byteLength);
let wavView = new DataView(wavBuffer);
// RIFF header
writeString(wavView, 0, 'RIFF');
wavView.setUint32(4, 36 + buffer.byteLength, true);
writeString(wavView, 8, 'WAVE');
// fmt subchunk
writeString(wavView, 12, 'fmt ');
wavView.setUint32(16, 16, true); // Subchunk1Size (16 for PCM)
wavView.setUint16(20, 1, true); // AudioFormat (1 for PCM)
wavView.setUint16(22, 1, true); // NumChannels (1 for mono)
wavView.setUint32(24, sampleRate, true); // SampleRate
wavView.setUint32(28, sampleRate * 2, true); // ByteRate (SampleRate * NumChannels * BitsPerSample/8)
wavView.setUint16(32, 2, true); // BlockAlign (NumChannels * BitsPerSample/8)
wavView.setUint16(34, 16, true); // BitsPerSample
// data subchunk
writeString(wavView, 36, 'data');
wavView.setUint32(40, buffer.byteLength, true);
new Uint8Array(wavBuffer).set(new Uint8Array(buffer), 44);
// Convert to Blob
return Utilities.newBlob(new Uint8Array(wavBuffer), 'audio/wav', 'dtmf_tones.wav');
}
function writeString(view, offset, string) {
for (let i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
}
/**
* מעלה קובץ לכתובת ה-URL שצוינה באמצעות בקשת HTTP POST עם נתונים מרובי חלקים/טופס.
*
* @param {string} path - הנתיב שבו יש להעלות את הקובץ.
* @param {Blob} fileBlob - blob הקובץ שיש להעלות.
*/
function uploadFile(path, fileBlob) {
var YemotUrl = url + 'UploadFile';
var formData = {
'upload': fileBlob,
'token': token,
'path': path
};
var options = {
'method': 'post',
'payload': formData,
'muteHttpExceptions': true
};
var response = UrlFetchApp.fetch(YemotUrl, options);
var responseCode = response.getResponseCode();
Logger.log(response.getContentText());
if (responseCode === 200) {
return JSON.parse(response.getContentText());
} else {
return {'שגיאה': 'הבקשה נכשלה עם קוד תגובה ' + responseCode};
}
}