Ankündigung

Einklappen
Keine Ankündigung bisher.

VoiceServer

Einklappen
Dieses Thema ist geschlossen.
X
Das ist ein wichtiges Thema.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    VoiceServer

    Dieses Thema soll komplett der Einrichtung und Konfiguration des Voiceservers (VS) gewidmet sein.

    Ziel ist es einen Guide für das Bearbeiten und Erstellen neuer Projekte/Scripte zusammenzutragen und für ein zukünftiges Integrationshandbuch vorzubereiten.

    Diskussionen zu Scripten und Abläufen sind gern gesehen.


    Allgemeine Struktur
    Der VS ist als ereignisgesteuerter Zustandsautomat (SM) aufgebaut. Jedes bei ihm eingehende UDP-Paket wird als Ereignis ausgewertet und ruft SM für den entsprechenden B-Kanal auf.

    Die Definition der einzelnen Zustände ist variabel und durch den Administrator editierbar. Ursprünglich für die Anpassung auf Dateiebene entwickelt, greift der VS auf eine per Konfiguration festgelegte Verzeichnisstruktur (DATAVOICE) zu. DATAVOICE enthält
    • Unterverzeichnisse mit Projekten
    • Unterverzeichnis "lua" mit
      • "init.lua" - enthält vordefinierte Funktionen, die von den Basisprojekten genutzt werden
      • "sample.user.lua" - soll für eigene Funktionen eingesetzt werden, hier definierte Funktionen stehen in allen Scripten zur Verfügung. Die Datei muss dafür in "user.lua" umbenannt werden.
      • Schablonen (template) für extended Voice, diese Datei(en) sollten nicht verändert werden!
    • Datei "main.lua" - ohne Inhalt, aber notwendig um Unterverzeichnisse in den Projektordnern zu ignorieren. Dies ist nur wichtig in Installationen, bei denen vorher bereits ein OfficeMaster <4 installiert war.
      Vor OM 4 hat SM allein auf Dateiebene ohne Scripte gearbeitet.


    In den Unterverzeichnissen der einzelnen Projekte liegen jeweils
    • eine .lua-Datei mit Anweisungen für SM und
    • die "event.ini" mit allgemeinen Projektinformationen.
    • je nach Projekt kann auch ein "audio" Ordner vorhanden sein.


    Aufbau der Event.ini

    Diese Datei dient der Identifikation und Einordnung des Projektes. Alle Änderungen können mit einem Standard Editor vogenommen werden und folgende Einträge enthalten.
    [Parameter]
    Type=Project
    Name=Voicebox ohne Aufnahme
    Loadable=1
    description=Voicebox ohne Aufnahme
    • Name: Displayname in der Auswahl des Projektes am entsprechenden Gateway
    • Loadable: 0, Projekt kann nicht als Startprojekt genutzt sondern nur durch andere Projekte augerufen werden; 1, kann als Startprojekt eingesetzt werden
    • description: Beschreibung des Projektes, wird in verschiedenen Gateways als Wert in den Klammern hinter dem Namen angezeigt


    Scripte/Projekte
    Wird ein Script als Startzustand festgelegt, oder durch ein zuvor verlassenes Script aufgerufen, erfolgt ein sequentielles Abarbeiten des Codes. Die meisten Scripte sind als große IF-Verzweigung aufgebaut und verlassen nach Abarbeitung des entsprechenden Zweiges das Script mit einem LUA_Event und einem aktualisiertem Status.

    Als Beispiel sei das Standardstartscript ProjectVox gewählt:

    LogFmsState("projectvox.lua")

    -- *************************************
    -- ***** projectVox
    -- *************************************
    if (CheckFmsState("projectVox")) then
    if (EvtGateway()) then
    SetFmsState("projectAbfrage: replay")
    CmdGotoNode("\\\\projectAbfrage")
    return EVENT_IVRGOTONODE
    end
    if (CmdCheckPin("0") == EVENT_IVROK) then
    SetFmsState("projectConfig")
    CmdGotoNode("\\\\projectAbfrage")
    return EVENT_IVRGOTONODE
    else
    SetFmsState("projectRecord")
    CmdGotoNode("\\\\projectRecord")
    return EVENT_IVRGOTONODE
    end

    -- *************************************
    -- ***** projectVox -> INITIAL
    -- *************************************
    else
    SetFmsState("projectVox")
    return EVENT_RESTARTSCRIPT
    end
    • LogFmsState("projectvox.lua")
      - dient als Hilfe im Logfile, alle Logs hiernach werden durch projectVox verursacht.
    • if (CheckFmsState("projectVox")) then
      - Abfrage, ob sich SM im LUA-Zustand projectVox befindet, schlägt beim ersten Durchlauf durch dieses Script fehl, da noch kein LUA-Zustand angegeben wurde
    • else
      - beim ersten Aufruf wird demnach dieser Zweig aufgerufen, in dem mit "SetFmsState" der LUA-Zustand gesetzt wird
    • return EVENT_RESTARTSCRIPT
      - das Script wird nach Abarbeiten wieder neu gestartet
    • if (CheckFmsState("projectVox")) then
      - Abfrage ist nun erfolgreich, diese Verzweigung wird abgearbeitet
      • if (EvtGateway()) then
        - Wurde SM gestartet, weil ein Event vom zugehörigen Gateway(GW) gesendet wurde? Ereignisse eines GW werden bspw. durch den Button "Auf mein Telefon" im Outlook oder Notes angestoßen. Dahinter verbergen sich Scripte, die das Notesgateway oder den Exchange Connector veranlassen ein Ereignis an den Voiceserver zu senden
        • SetFmsState("")
          - Setzen des Lua-Zustandes
        • CmdGotoNode("")
          - Aufruf des nächsten Projektes,
          - mit "\\" wird der Basispfad aufgerufen,
          - "\" muss escaped werden


    LUA Kommandos
    • CmdSelectLanguage
    • CmdDeletePlayList
    • CmdStoreNumberAsDid
    • CmdGetUserInfo
    • CmdIsGateway
    • CmdAdjustPlaying
    • CmdStopRecord
    • CmdPlay
    • CmdPlayPrompt
    • CmdRecord
    • CmdDeleteRecord
    • CmdDeleteName
    • CmdDeleteGreeting
    • CmdDeleteHoliday
    • CmdDeleteSpecialMessage
    • CmdRestartPlayList
    • CmdRestartThis
    • CmdPlayPrevious
    • CmdPlayNext
    • CmdSetTimer
    • CmdCollectAll
    • CmdCollectN
    • CmdSendMessageToGateway
    • CmdDeleteMessageFromGateway
    • CmdPlayGatewayMessageCount
    • CmdAreMessagesAvailable
    • CmdCheckPin
    • CmdSetPin
    • CmdSetCounter
    • CmdDecreaseCounter
    • CmdActivatePlayList
    • CmdRecordName
    • CmdRecordGreeting
    • CmdRecordHoliday
    • CmdRecordSpecialMessage
    • CmdRecordFileMessage
    • CmdOnHook
    • CmdOnHookOutgoing
    • CmdConnect
    • CmdGosubNode
    • CmdGotoNode
    • CmdReturn
    • CmdSetVariables
    • CmdGetVariables
    • CmdDumpVariables
    • CmdDeleteVariables
    • CmdSetState
    • CmdGetDate
    • CmdGetDay
    • CmdGetTimedDest


    Aktuell nicht genutzt:
    • CmdGetCalledPartyNumber
    • CmdGetCallingPartyNumber
    • CmdGetRedirectingNumber
    • CmdGreetingMode
    • CmdGetPin
    • CfgGetMinimalPinLength
    • CfgGetUseExactPinLength
    • CfgGetPinMode //requieres Pin, requieres OAD, requieres both
    • CfgGetHolidayMode //after holiday-greetingfile start record or not


    Rückgabewerte
    Rückgabewerte aus dem Script sind Events, d.h. es können die gleichen Events aus dem Script ausgegeben werden, wie sie auch von aussen auftreten können. Zunächst die typischen Rückgabewerte, die Scripte liefern können
    • EVENT_RESTARTSCRIPT
    • EVENT_WAITFORNEXTEVENT
    • EVENT_IVRGOTONODE


    Weitere Events, auf die im Script reagiert werden kann:
    • EVENT_NOEVENT; eigentlich kein Event ;-)
    • EVENT_OPEN
    • EVENT_CLOSE
    • EVENT_DTMF0
    • EVENT_DTMF1
    • EVENT_DTMF2
    • EVENT_DTMF3
    • EVENT_DTMF4
    • EVENT_DTMF5
    • EVENT_DTMF6
    • EVENT_DTMF7
    • EVENT_DTMF8
    • EVENT_DTMF9
    • EVENT_DTMFSTAR
    • EVENT_DTMFHASHMARK
    • EVENT_TIMER
    • EVENT_RECORDSTART
    • EVENT_STATEPOPPED
    • EVENT_IVROK
    • EVENT_IVRNOK
    • EVENT_PLAYED
    • EVENT_PAST_CLOSE
    • EVENT_PRE_OPEN
    • EVENT_OPEN_OUTGOING
    • EVENT_PROMPTPLAYED
    Zuletzt geändert von Julian Cebulla; 26.03.2014, 12:01.
    Chris Helbing

    Director Product Management
    Twitter Profil
    http://www.ferrari-electronic.de

    #2
    Beispiel: Zeitgesteuerter Sprung

    Als Beispiel das zum Jahreswechsel eingesetzte Script der Ferrari electronic gewählt:
    LogFmsState("ferrari_start.lua")

    -- *************************************
    -- ***** ferrari_start: init
    -- *************************************
    if (CheckFmsState("ferrari_start: init")) then

    --never change attributenames: "dayOfWeek" and "date" voice.exe is searching for these keys
    SetFmsProjectData("dayOfWeek","1","wochentag")
    SetFmsProjectData("dayOfWeek","2","wochentag")
    SetFmsProjectData("dayOfWeek","3","wochentag")
    SetFmsProjectData("dayOfWeek","4","wochentag")
    SetFmsProjectData("dayOfWeek","5","wochentag")
    SetFmsProjectData("dayOfWeek","6","wochenende")
    SetFmsProjectData("dayOfWeek","7","wochenende")

    SetFmsProjectData("date","20101224", "feiertag")
    SetFmsProjectData("date","20101225", "feiertag")
    SetFmsProjectData("date","20101226", "feiertag")
    SetFmsProjectData("date","20101227", "feiertag")
    SetFmsProjectData("date","20101228", "feiertag")
    SetFmsProjectData("date","20101229", "feiertag")
    SetFmsProjectData("date","20101230", "feiertag")
    SetFmsProjectData("date","20101231", "feiertag")
    SetFmsProjectData("date","20110101", "feiertag")
    SetFmsProjectData("date","20110102", "feiertag")

    ---- timetable ----
    SetFmsProjectData("wochentag","00:00","ferrari_ges chlossen")
    SetFmsProjectData("wochentag","09:00","ferrari_nor mal")
    SetFmsProjectData("wochentag","17:00","ferrari_ges chlossen")

    SetFmsProjectData("wochenende","00:00","ferrari_ge schlossen")

    SetFmsProjectData("feiertag","00:00","ferrari_jahr eswechsel")

    --check date--
    if(GetFmsProjectData("date",CmdGetDate())) then
    kindOfDay = GetFmsProjectData("date",CmdGetDate())
    else
    kindOfDay = GetFmsProjectData("dayOfWeek",CmdGetDay())
    end

    --check time--
    time = CmdGetTimedDest(kindOfDay)
    project = "ferrari_normal" --default
    project = GetFmsProjectData(kindOfDay,time)
    --define to destination--
    SetFmsState(project)
    CmdGotoNode("\\\\"..project)


    return EVENT_IVRGOTONODE


    -- *************************************
    -- ***** ferrari_start -> INITIAL
    -- *************************************
    else

    SetFmsState("ferrari_start: init")
    return EVENT_RESTARTSCRIPT

    end
    SetFmsProjectData - wird für nahezu alle Variablen eingesetzt, kann als 3 dimensionaler Array ohne Initialisierung verwendet werden
    • SetFmsProjectData("dayOfWeek","1","wochentag"); dayOfWeek wird hier als MainIndex eingetragen, mit date erfolgt später das gleiche
    • GetFmsProjectData("date",CmdGetDate()); gibt den Wert der Stelle "date"; und dem Rückgabewert von CmdGetDate(); entspricht der Rückgabewert (also das aktuelle Datum im Format YYYYMMDD) einem der in "date" hinterlegten Werte, so wird der entsprechen hinterlegte Wert zurückgegeben, sonst NULL
    Zuletzt geändert von Chris Helbing; 14.01.2011, 12:31.
    Chris Helbing

    Director Product Management
    Twitter Profil
    http://www.ferrari-electronic.de

    Kommentar


      #3
      Interactive Voice Response

      Eine mögliches Szenario für den normalen Tagesbetrieb....
      LogFmsState("ivrExample_normal.lua")
      projectName = "ivrExample_normal"


      function replay()
      SetFmsProjectData("variables","counter","0")
      CmdPlayPrompt(GetFmsProjectData("init","audiofile" ))
      FmsEnableAutoStopAndDelete(true) -- *** interrupt audiofile, if receiving DTMF *** --
      CmdActivatePlayList(1)
      end



      -- *************************************
      -- ***** EvtHandler
      -- *************************************
      if (CheckFmsState(projectName..":EvtHandler")) then

      if (EvtDtmf1()) then
      IVRConnect("dtmf1", projectName..":ringing")
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtDtmf2()) then
      IVRConnect("dtmf2", projectName..":ringing")
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtDtmf3()) then
      IVRConnect("dtmf3", projectName..":ringing")
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtDtmf4()) then
      IVRConnect("dtmf4", projectName..":ringing")
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtDtmf5()) then
      IVRConnect("dtmf5", projectName..":ringing")
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtDtmf6()) then
      IVRConnect("dtmf6", projectName..":ringing")
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtOnhook()) then
      SetFmsState("projectHangup:hangup")
      CmdGotoNode("\\\\projectHangup")
      return EVENT_IVRGOTONODE

      else
      CmdPlayPrompt(GetFmsProjectData("init","audiofile" ))
      FmsEnableAutoStopAndDelete(true)
      return EVENT_WAITFORNEXTEVENT

      end

      -- *************************************
      -- ***** ringing
      -- *****
      -- ***** uses init.lua
      -- ***** function IVRConnect(event, nextState)
      -- ***** sets ProjectData "IVREVENT"
      -- *****
      -- ***** function IVRInitialize(IVRVar, IVRNumber, IVRMaxRing, IVRAudio)
      -- ***** sets ProjectData "maxRinging"
      -- ***** sets ProjectData "audiofile"
      -- *****
      -- *************************************
      elseif (CheckFmsState(projectName..":ringing")) then

      IVREvent = GetFmsProjectData("data","IVREvent")
      SetFmsProjectData("variables", "counter", tostring(GetFmsProjectData("variables","counter")+ 1))

      if (EvtPromptPlayed()) then
      if(tonumber(GetFmsProjectData("variables", "counter")) < tonumber(GetFmsProjectData(IVREvent,"maxRinging")) ) then
      CmdPlayPrompt(GetFmsProjectData(IVREvent,"audiofil e"))
      FmsEnableAutoStopAndDelete(true) -- *** interrupt audiofile, if receiving DTMF *** --
      return EVENT_WAITFORNEXTEVENT
      else
      CmdOnHookOutgoing()
      replay()
      SetFmsState(projectName..":EvtHandler")
      return EVENT_WAITFORNEXTEVENT
      end
      elseif( EvtOk()) then
      return EVENT_WAITFORNEXTEVENT

      elseif (EvtOnhook()) then
      SetFmsState("projectHangup:hangup")
      CmdGotoNode("\\\\projectHangup")
      return EVENT_IVRGOTONODE
      end

      return EVENT_WAITFORNEXTEVENT

      -- *************************************
      -- ***** -> INITIAL
      -- *************************************
      else

      -- ** define ivr variables ** --

      SetFmsProjectData("init","audiofile","greeting.raw ")
      SetFmsProjectData("variables","counter","0")

      --IVR Destinations--

      IVRInitialize("dtmf2", "0455745", "5", "calling.raw")
      IVRInitialize("dtmf4", "0455949", "5", "calling.raw")

      -- ** begin process** --

      CmdPlayPrompt(GetFmsProjectData("init","audiofile" ))
      FmsEnableAutoStopAndDelete(true) -- *** interrupt audiofile, if receiving DTMF *** --
      CmdActivatePlayList(1)

      SetFmsState(projectName..":EvtHandler")
      return EVENT_WAITFORNEXTEVENT

      end
      Dieses Beispiel finden Sie auch in dem Data-Verzeichnis von Voice.
      Zuletzt geändert von Julian Cebulla; 26.03.2014, 11:43.
      Chris Helbing

      Director Product Management
      Twitter Profil
      http://www.ferrari-electronic.de

      Kommentar

      Lädt...
      X