דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. FreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?

FreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?

מתוזמן נעוץ נעול הועבר תכנות
7 פוסטים 3 כותבים 476 צפיות 3 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • צבי-שצ מחובר
    צבי-שצ מחובר
    צבי-ש
    כתב נערך לאחרונה על ידי צבי-ש
    #1

    (אני ממש עכשיו מתחיל לבדוק את הנושא, הדוגמאות נכתבו עם GPT, אבל ההתלבטות היא שלי באיזה צורה עדיף)
    אם יש פה איזה טעות בסיסית או חוסר הבנה שלי, אשמח לתיקון, כאומר אני עכשיו רוצה ללמוד את הנושא

    אני רוצה להקים מערכת FreeSWITCH מרובת שלוחות ותפריטים, ואני לא יודע איך עדיף לעשות אותה
    האם לעבוד עם סקריפטים עד כמה שאפשר, (פייתון, JS וכו) ומשם לשלוט על המאזין
    או כמה שאפשר להשתמש בשלוחות הרגילות או במשתני מערכת הרגילים, ואסביר

    למשל אני רוצה שמי שילחץ 1 יגיע לתת תפריט ושם הוא יוכל להקיש 1-9 ואז לנתב הלאה

    אז יש לי 2 דרכים לעשות את זה

    הראשונה, בשילוב שלוחות של המערכת עצמם (כלומר בהתחלה להגדיר עם הפייתון לפי הידע שלי באיזה שלוחה הוא ולא הוא ניגש וכו את המשתנים הרלוונטים לו)

    def handler(session, args):
        if not session.ready():
            return
    
        # הגדרת משתנים לשימוש ב־XML מאוחר יותר
        session.setVariable("min_digits", "1")
        session.setVariable("max_digits", "1")
        session.setVariable("tries", "3")
        session.setVariable("timeout", "5000")
        session.setVariable("terminator", "#")
        session.setVariable("menu_prompt", "/path/to/menu_prompt.wav")
        session.setVariable("invalid_prompt", "invalid.wav")
        session.setVariable("valid_keys", "123")
        session.setVariable("timeout_prompt", "timeout.wav")
    
        session.execute("transfer", "menu_processor XML dynamic_menu")
    

    ואז בשלוחה עצמה לעשות

    <context name="dynamic_menu">
      <extension name="menu_processor">
        <condition field="destination_number" expression="^menu_processor$">
    
          <action application="play_and_get_digits"
                  data="${min_digits} ${max_digits} ${tries} ${timeout} ${terminator} ${menu_prompt} ${invalid_prompt} ${valid_keys} ${timeout_prompt} input_digit"/>
    
          <action application="python" data="handle_menu_result.py"/>
    
          <action application="transfer" data="${result} XML main"/>
    
        </condition>
      </extension>
    </context>
    
    

    ואז בhandle_menu_result (שבעצם אחראי על להגיד לאן לנתב אחרי שלחצו) לכתוב משו כזה

    def handler(session, args):
        digit = session.getVariable("input_digit")
        menu_id = session.getVariable("menu_id")
    
        if menu_id == "main_menu":
            if digit == "1":
                session.setVariable("result", "sales")
            elif digit == "2":
                session.setVariable("result", "support")
            else:
                session.setVariable("result", "menu_processor") 
    

    הדרך השניה היא את כל התסריט שיחה לעשות עם קוד אחד ארוך, ובשלוחה פשוט להגדיר לו להפעיל את הקוד פייתון

    <extension name="go_to_dynamic_menu">
      <condition field="destination_number" expression="^123$">
        <action application="python" data="my_menu_entry.py"/>
      </condition>
    </extension>
    

    ואז את הקוד פייתון לכתוב משו כזה

    def handler(session, args):
        if not session.ready():
            return
    
        def play_menu(prompt_file, valid_digits, tries=3, timeout=5000, terminator="#"):
            session.setInputCallback(None)  # Reset input callback
            return session.playAndGetDigits(
                1,                 # min digits
                1,                 # max digits
                tries,             # max tries
                timeout,           # timeout ms
                terminator,        # terminator key
                prompt_file,       # prompt to play
                "ivr/invalid.wav", # invalid entry prompt
                valid_digits,      # valid digits
                "",                # regex (not used here)
                5000,              # digit timeout
                "input_digit"      # variable name to store result
            )
    
        # שלב 1: תפריט ראשי
        main_choice = play_menu("ivr/main_menu.wav", "12")
        if not main_choice:
            session.streamFile("ivr/timeout.wav")
            return
    
        # שלב 2: תת תפריט לפי הבחירה
        if main_choice == "1":
            submenu_prompt = "ivr/service_submenu.wav"
            menu_label = "service"
        elif main_choice == "2":
            submenu_prompt = "ivr/support_submenu.wav"
            menu_label = "support"
        else:
            session.streamFile("ivr/invalid.wav")
            return
    
        sub_choice = play_menu(submenu_prompt, "123456789")
        if not sub_choice:
            session.streamFile("ivr/timeout.wav")
            return
    
        # שלב 3: הדמיית פעולה (או העברה אמיתית)
        session.streamFile(f"ivr/you_selected_{menu_label}_{sub_choice}.wav")
        # או לצורך העברה:
        # session.execute("transfer", f"{menu_label}_{sub_choice} XML public")
    
        # סיום
        session.hangup()
    
    

    שאלה חשובה לי גם כן, האם יש עדיפות מבחינת מהירות לאחד משני הדרכים, או אולי יש דרך שלישית ?

    אני חושב שבדרך הראשונה יהיה לי הרבה יותר קל לתחזק שינויים רוחביים, למשל להוסיף לשלוחת הקלטות אופציה לשים סיסמה, אני יצטרך לשנות רק בשלוחת הקלטות אחת, במקום רוחבי על כל הקוד, כי בסוף אני צריך לאפשר שינויים תכופים ללקוחות (אולי אפילו דרך אתר ניהול) אז נראה לי הגיוני יותר הדרך הראשונה, ורק לקשר בין השלוחות, ההקלטות, וההקשות עם איזה MONGO או משהו כזה

    כיף לגלות דברים חדשים.
    חוק ה-50-50-90: בכל פעם שיש סיכוי של 50-50 שמשהו יעבוד, יש סיכוי של 90 אחוז שהוא לא. מקור

    nigunN תגובה 1 תגובה אחרונה
    1
    • צבי-שצ צבי-ש

      (אני ממש עכשיו מתחיל לבדוק את הנושא, הדוגמאות נכתבו עם GPT, אבל ההתלבטות היא שלי באיזה צורה עדיף)
      אם יש פה איזה טעות בסיסית או חוסר הבנה שלי, אשמח לתיקון, כאומר אני עכשיו רוצה ללמוד את הנושא

      אני רוצה להקים מערכת FreeSWITCH מרובת שלוחות ותפריטים, ואני לא יודע איך עדיף לעשות אותה
      האם לעבוד עם סקריפטים עד כמה שאפשר, (פייתון, JS וכו) ומשם לשלוט על המאזין
      או כמה שאפשר להשתמש בשלוחות הרגילות או במשתני מערכת הרגילים, ואסביר

      למשל אני רוצה שמי שילחץ 1 יגיע לתת תפריט ושם הוא יוכל להקיש 1-9 ואז לנתב הלאה

      אז יש לי 2 דרכים לעשות את זה

      הראשונה, בשילוב שלוחות של המערכת עצמם (כלומר בהתחלה להגדיר עם הפייתון לפי הידע שלי באיזה שלוחה הוא ולא הוא ניגש וכו את המשתנים הרלוונטים לו)

      def handler(session, args):
          if not session.ready():
              return
      
          # הגדרת משתנים לשימוש ב־XML מאוחר יותר
          session.setVariable("min_digits", "1")
          session.setVariable("max_digits", "1")
          session.setVariable("tries", "3")
          session.setVariable("timeout", "5000")
          session.setVariable("terminator", "#")
          session.setVariable("menu_prompt", "/path/to/menu_prompt.wav")
          session.setVariable("invalid_prompt", "invalid.wav")
          session.setVariable("valid_keys", "123")
          session.setVariable("timeout_prompt", "timeout.wav")
      
          session.execute("transfer", "menu_processor XML dynamic_menu")
      

      ואז בשלוחה עצמה לעשות

      <context name="dynamic_menu">
        <extension name="menu_processor">
          <condition field="destination_number" expression="^menu_processor$">
      
            <action application="play_and_get_digits"
                    data="${min_digits} ${max_digits} ${tries} ${timeout} ${terminator} ${menu_prompt} ${invalid_prompt} ${valid_keys} ${timeout_prompt} input_digit"/>
      
            <action application="python" data="handle_menu_result.py"/>
      
            <action application="transfer" data="${result} XML main"/>
      
          </condition>
        </extension>
      </context>
      
      

      ואז בhandle_menu_result (שבעצם אחראי על להגיד לאן לנתב אחרי שלחצו) לכתוב משו כזה

      def handler(session, args):
          digit = session.getVariable("input_digit")
          menu_id = session.getVariable("menu_id")
      
          if menu_id == "main_menu":
              if digit == "1":
                  session.setVariable("result", "sales")
              elif digit == "2":
                  session.setVariable("result", "support")
              else:
                  session.setVariable("result", "menu_processor") 
      

      הדרך השניה היא את כל התסריט שיחה לעשות עם קוד אחד ארוך, ובשלוחה פשוט להגדיר לו להפעיל את הקוד פייתון

      <extension name="go_to_dynamic_menu">
        <condition field="destination_number" expression="^123$">
          <action application="python" data="my_menu_entry.py"/>
        </condition>
      </extension>
      

      ואז את הקוד פייתון לכתוב משו כזה

      def handler(session, args):
          if not session.ready():
              return
      
          def play_menu(prompt_file, valid_digits, tries=3, timeout=5000, terminator="#"):
              session.setInputCallback(None)  # Reset input callback
              return session.playAndGetDigits(
                  1,                 # min digits
                  1,                 # max digits
                  tries,             # max tries
                  timeout,           # timeout ms
                  terminator,        # terminator key
                  prompt_file,       # prompt to play
                  "ivr/invalid.wav", # invalid entry prompt
                  valid_digits,      # valid digits
                  "",                # regex (not used here)
                  5000,              # digit timeout
                  "input_digit"      # variable name to store result
              )
      
          # שלב 1: תפריט ראשי
          main_choice = play_menu("ivr/main_menu.wav", "12")
          if not main_choice:
              session.streamFile("ivr/timeout.wav")
              return
      
          # שלב 2: תת תפריט לפי הבחירה
          if main_choice == "1":
              submenu_prompt = "ivr/service_submenu.wav"
              menu_label = "service"
          elif main_choice == "2":
              submenu_prompt = "ivr/support_submenu.wav"
              menu_label = "support"
          else:
              session.streamFile("ivr/invalid.wav")
              return
      
          sub_choice = play_menu(submenu_prompt, "123456789")
          if not sub_choice:
              session.streamFile("ivr/timeout.wav")
              return
      
          # שלב 3: הדמיית פעולה (או העברה אמיתית)
          session.streamFile(f"ivr/you_selected_{menu_label}_{sub_choice}.wav")
          # או לצורך העברה:
          # session.execute("transfer", f"{menu_label}_{sub_choice} XML public")
      
          # סיום
          session.hangup()
      
      

      שאלה חשובה לי גם כן, האם יש עדיפות מבחינת מהירות לאחד משני הדרכים, או אולי יש דרך שלישית ?

      אני חושב שבדרך הראשונה יהיה לי הרבה יותר קל לתחזק שינויים רוחביים, למשל להוסיף לשלוחת הקלטות אופציה לשים סיסמה, אני יצטרך לשנות רק בשלוחת הקלטות אחת, במקום רוחבי על כל הקוד, כי בסוף אני צריך לאפשר שינויים תכופים ללקוחות (אולי אפילו דרך אתר ניהול) אז נראה לי הגיוני יותר הדרך הראשונה, ורק לקשר בין השלוחות, ההקלטות, וההקשות עם איזה MONGO או משהו כזה

      nigunN מנותק
      nigunN מנותק
      nigun
      כתב נערך לאחרונה על ידי
      #2

      @צבי-ש כתב בFreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?:

      אני חושב שבדרך הראשונה יהיה לי הרבה יותר קל לתחזק שינויים רוחביים, למשל להוסיף לשלוחת הקלטות אופציה לשים סיסמה, אני יצטרך לשנות רק בשלוחת הקלטות אחת, במקום רוחבי על כל הקוד, כי בסוף אני צריך לאפשר שינויים תכופים ללקוחות (אולי אפילו דרך אתר ניהול) אז נראה לי הגיוני יותר הדרך הראשונה, ורק לקשר בין השלוחות, ההקלטות, וההקשות עם איזה MONGO או משהו כזה

      איך תארגן את הקוד? כל תפריט בקובץ נפרד?

      מייל: nigun@duck.com

      צבי-שצ תגובה 1 תגובה אחרונה
      1
      • nigunN nigun

        @צבי-ש כתב בFreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?:

        אני חושב שבדרך הראשונה יהיה לי הרבה יותר קל לתחזק שינויים רוחביים, למשל להוסיף לשלוחת הקלטות אופציה לשים סיסמה, אני יצטרך לשנות רק בשלוחת הקלטות אחת, במקום רוחבי על כל הקוד, כי בסוף אני צריך לאפשר שינויים תכופים ללקוחות (אולי אפילו דרך אתר ניהול) אז נראה לי הגיוני יותר הדרך הראשונה, ורק לקשר בין השלוחות, ההקלטות, וההקשות עם איזה MONGO או משהו כזה

        איך תארגן את הקוד? כל תפריט בקובץ נפרד?

        צבי-שצ מחובר
        צבי-שצ מחובר
        צבי-ש
        כתב נערך לאחרונה על ידי
        #3

        @nigun כתב בFreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?:

        @צבי-ש כתב בFreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?:

        אני חושב שבדרך הראשונה יהיה לי הרבה יותר קל לתחזק שינויים רוחביים, למשל להוסיף לשלוחת הקלטות אופציה לשים סיסמה, אני יצטרך לשנות רק בשלוחת הקלטות אחת, במקום רוחבי על כל הקוד, כי בסוף אני צריך לאפשר שינויים תכופים ללקוחות (אולי אפילו דרך אתר ניהול) אז נראה לי הגיוני יותר הדרך הראשונה, ורק לקשר בין השלוחות, ההקלטות, וההקשות עם איזה MONGO או משהו כזה

        איך תארגן את הקוד? כל תפריט בקובץ נפרד?

        קובץ XML עם תפריט, כאשר ההגדרות של מה ניתן לבצע, או איזה קובץ להשמיע, אגדיר לפני שאני מעביר לשם עם משתנה מערכת

        def handler(session, args):
            if not session.ready():
                return
         
            # הגדרת משתנים לשימוש ב־XML מאוחר יותר
            session.setVariable("min_digits", "1")
            session.setVariable("max_digits", "1")
            session.setVariable("tries", "3")
            session.setVariable("timeout", "5000")
            session.setVariable("terminator", "#")
            session.setVariable("menu_prompt", "/path/to/menu_prompt.wav")
            session.setVariable("invalid_prompt", "invalid.wav")
            session.setVariable("valid_keys", "123")
            session.setVariable("timeout_prompt", "timeout.wav")
         
            session.execute("transfer", "menu_processor XML dynamic_menu")
        
        <context name="dynamic_menu">
          <extension name="menu_processor">
            <condition field="destination_number" expression="^menu_processor$">
         
              <action application="play_and_get_digits"
                      data="${min_digits} ${max_digits} ${tries} ${timeout} ${terminator} ${menu_prompt} ${invalid_prompt} ${valid_keys} ${timeout_prompt} input_digit"/>
         
              <action application="python" data="handle_menu_result.py"/>
         
              <action application="transfer" data="${result} XML main"/>
         
            </condition>
          </extension>
        </context>
         
        

        כיף לגלות דברים חדשים.
        חוק ה-50-50-90: בכל פעם שיש סיכוי של 50-50 שמשהו יעבוד, יש סיכוי של 90 אחוז שהוא לא. מקור

        תגובה 1 תגובה אחרונה
        0
        • nigunN מנותק
          nigunN מנותק
          nigun
          כתב נערך לאחרונה על ידי
          #4

          ואם יש לך 8 שלוחות בתוך כל שלוחה תפריט נוסף עם 3-9 שלוחות מסוגים שונים וכדו'?

          מייל: nigun@duck.com

          צבי-שצ תגובה 1 תגובה אחרונה
          1
          • nigunN nigun

            ואם יש לך 8 שלוחות בתוך כל שלוחה תפריט נוסף עם 3-9 שלוחות מסוגים שונים וכדו'?

            צבי-שצ מחובר
            צבי-שצ מחובר
            צבי-ש
            כתב נערך לאחרונה על ידי צבי-ש
            #5

            @nigun כתב בFreeSWITCH | איך לבנות תפריטים מרובי שלוחות – XML או סקריפט מרכזי?:

            ואם יש לך 8 שלוחות בתוך כל שלוחה תפריט נוסף עם 3-9 שלוחות מסוגים שונים וכדו'?

            ראשי - פייתון אומר לו גש לשלוחה main_menu כאשר הוא מגדיר למשתנה לפני זה (משאיבה מDB ) את השלוחות הפעילות שם, הקלטה וכו

            כל הקשה תקינה נשמרת במשתנה, ואחרי זה שוב לקוד פייתון שיודע מאיזה שלוחה הגיעו ( main_menu ) ויודא מה הקישו (3) ויודע שזה שלוחת תפריט נוספת

            מגדיר את ההגדרות הרלוונטיות, ומעביר לאותה שלוחת תפריט, רק עם הגדרות אחרות
            אותו רעיון עם השמעות קבצים וכו

            כיף לגלות דברים חדשים.
            חוק ה-50-50-90: בכל פעם שיש סיכוי של 50-50 שמשהו יעבוד, יש סיכוי של 90 אחוז שהוא לא. מקור

            תגובה 1 תגובה אחרונה
            0
            • צבי-שצ מחובר
              צבי-שצ מחובר
              צבי-ש
              כתב נערך לאחרונה על ידי
              #6

              מעדכן שהתחלתי לעבוד בצורה שיש קוד פייתון שמקבל את השיחה, בודק לאן להפנות, מגדיר משתנים במערכת, מעביר, וחוזר חלילה.

              למשל, מתקשרים לקו, הקוד פייתון קולט שזה התפריט הראשי, בודק מה מוגדר להיות בתפריט ראשי, מגדיר במשתני מערכת את הנתיב להקלטת תפריט, את האופציות להקיש, זמן להמתין וכו, ואז מעביר לשלוחת תפריט רזה שרק מקבל את המשתנים האלה ומבצעת אותם ללא תנאים או משהו כזה

              בסיום היא מחזירה שוב לקוד פייתון, תוך ציון הID שלה (כדי שהוא יידע מאיפה הגיעו) ואז הוא יודע מול הDB להפנות שוב לאן שצריך

              מקווה שזה לא ייצור עומסים בלתי סבירים על מסד הנתונים, אממש קאשים וכו בהמשך כמובן

              כיף לגלות דברים חדשים.
              חוק ה-50-50-90: בכל פעם שיש סיכוי של 50-50 שמשהו יעבוד, יש סיכוי של 90 אחוז שהוא לא. מקור

              צדיק תמיםצ תגובה 1 תגובה אחרונה
              0
              • צבי-שצ צבי-ש

                מעדכן שהתחלתי לעבוד בצורה שיש קוד פייתון שמקבל את השיחה, בודק לאן להפנות, מגדיר משתנים במערכת, מעביר, וחוזר חלילה.

                למשל, מתקשרים לקו, הקוד פייתון קולט שזה התפריט הראשי, בודק מה מוגדר להיות בתפריט ראשי, מגדיר במשתני מערכת את הנתיב להקלטת תפריט, את האופציות להקיש, זמן להמתין וכו, ואז מעביר לשלוחת תפריט רזה שרק מקבל את המשתנים האלה ומבצעת אותם ללא תנאים או משהו כזה

                בסיום היא מחזירה שוב לקוד פייתון, תוך ציון הID שלה (כדי שהוא יידע מאיפה הגיעו) ואז הוא יודע מול הDB להפנות שוב לאן שצריך

                מקווה שזה לא ייצור עומסים בלתי סבירים על מסד הנתונים, אממש קאשים וכו בהמשך כמובן

                צדיק תמיםצ מנותק
                צדיק תמיםצ מנותק
                צדיק תמים
                כתב נערך לאחרונה על ידי צדיק תמים
                #7

                @צבי-ש בסדרי גודל שאני משער שיש לך אתה לא צריך קאש אלא אינדקסים
                אם אתה ממש חושש אתה יכול להשתמש במסד נתונים שבעצמו יש לו ביצועים של קאש, כמו Redis

                Don’t comment bad code — rewrite it." — Brian W. Kernighan and P. J. Plaugher"
                טיפים

                תגובה 1 תגובה אחרונה
                1
                תגובה
                • תגובה כנושא
                התחברו כדי לפרסם תגובה
                • מהישן לחדש
                • מהחדש לישן
                • הכי הרבה הצבעות


                בא תתחבר לדף היומי!
                • התחברות

                • אין לך חשבון עדיין? הרשמה

                • התחברו או הירשמו כדי לחפש.
                • פוסט ראשון
                  פוסט אחרון
                0
                • דף הבית
                • קטגוריות
                • פוסטים אחרונים
                • משתמשים
                • חיפוש
                • חוקי הפורום