⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callfunc.pas

📁 用Delphi写的呼叫中心
💻 PAS
字号:
unit CallFunc;

interface


type TRUNK_STATE =(
	TRK_IDLE,
        TRK_WAIT_CONNECT,
	TRK_PLAY_WELCOM,
	TRK_CHECK_PLAY_WELCOM,
	TRK_PLAY_SELECT,
	TRK_CHECK_PLAY_PASSWORD,
	TRK_CHECK_REC_END,
	TRK_CHECK_PLAY_BYEBYE,
	TRK_CHECK_PLAY_RECORD,
	TRK_CHECK_PLAY_SELECT,
	TRK_CHECK_REC_START,
        TRK_NOTRK
        );

type TRUNK_STRUCT = record
        EnCalled:Boolean;
	lineState:Integer;
	Step:TRUNK_STATE;		//state of current channel
	UserCh:integer;

	pErrMsg:String;
	pCallerId:String;
        dwTimeOutCounter:LongWord;
end;
///////////////////////////////////////////
procedure UpDateATrunkChListCtrl();
procedure InitATrunkCh;
function InitCtiSystem():boolean;
procedure AppErrorHandler(ch:Integer);
procedure ScanATrunkCh;
procedure ExitCtiSystem;

///////////////////////////////////////////////////////////
var
  nTotUserCh:Integer;
  nTotATrkCh:Integer;
  ATrkCh:array[0..100] of TRUNK_STRUCT;

///////////////////////////////////////////////////////////
implementation
uses Shpa3api,Main,filectrl,Windows, Messages, SysUtils, Classes, Graphics,
     Controls, Forms, Dialogs,ComCtrls, ExtCtrls;

////////////////////////////////////////////////////////////
function InitCtiSystem():boolean;
var
  strCurrentDir:string;
  fnIni:string;
  fnIndex:string;

  ErrMsg:PChar;
begin
  strCurrentDir:=GetCurrentDir();
  fnIni:=strCurrentDir+'\ShConfig.ini';
  fnIndex:=strCurrentDir+'\ShIndex.ini';

  if SsmStartCti( @fnIni[1], @fnIndex[1] ) <> 0 then
  begin
    GetMem(ErrMsg,200);
    SsmGetLastErrMsg(ErrMsg); //取得初始化出错信息
    Application.MessageBox(ErrMsg,'错误', MB_OK );
    FreeMem(ErrMsg);
    InitCtiSystem:=False;
    Exit;
  end;

  InitCtiSystem:=true;
end;

////////////////////////////////////////////////////////////
procedure ExitCtiSystem;
begin
  SsmCloseCti() ;
end;

/////////////////////////////////////////////////////////////
procedure ScanATrunkCh();
var
  i:Integer;
  tmp:char;
  strCurrentDir:string;
  pBuf:PChar;
begin
  for i:=0 to nTotATrkCh-1 do
  if ATrkCh[i].EnCalled then
  begin
    ATrkCh[i].lineState := SsmGetChState(i);

    case ATrkCh[i].Step of
    TRK_IDLE:
    begin
      if ATrkCh[i].lineState = S_CALL_RINGING then  //ring detected
      begin
        SsmPickup(i);
        GetMem(pBuf,100);
        if SsmGetCallerId(i,pBuf)>0 then  ATrkCh[i].pCallerId:=StrPas(pBuf)
        else ATrkCh[i].pCallerId:='';
        FreeMem(pBuf);
        ATrkCh[i].dwTimeOutCounter := 0;
        ATrkCh[i].Step := TRK_WAIT_CONNECT;
      end
      else
      begin
        ATrkCh[i].pCallerId := '';
      end;
    end;

    TRK_WAIT_CONNECT:
    begin

      if ATrkCh[i].lineState = S_CALL_TALKING then
      begin
        ATrkCh[i].Step := TRK_PLAY_WELCOM;
      end;
    end;

    TRK_PLAY_WELCOM:
    begin
      SsmClearFileList(i);
      if (SsmAddToFileList(i,'..\..\..\..\DemoVoc\Welcom1.voc',6,0,$FFFFFFFF)= -1)
      or (SsmAddToFileList(i,'..\..\..\..\DemoVoc\Welcom2.voc',6,0,$FFFFFFFF)= -1) then
        AppErrorHandler(i)
      else
      begin
        if SsmPlayFileList(i) = -1 then AppErrorHandler(i)
        else ATrkCh[i].Step := TRK_CHECK_PLAY_WELCOM;
      end;
    end;

    TRK_CHECK_PLAY_WELCOM:
    begin
        if SsmCheckPlay(i) > 0 then//end of playing "welcom"
                ATrkCh[i].Step := TRK_PLAY_SELECT;
    end;
    TRK_PLAY_SELECT:
    begin
      SsmSetDtmfStopPlay(i,TRUE);	//enable DTMF-Stop-Play function
      if(SsmPlayIndexString(i,'Select') = -1) then
        AppErrorHandler(i)
      else
      begin
        SsmClearRxDtmfBuf(i);
        ATrkCh[i].dwTimeOutCounter := 0;
        ATrkCh[i].Step := TRK_CHECK_PLAY_SELECT;
      end;
    end;

    TRK_CHECK_PLAY_SELECT:
    begin
      if (SsmGetRxDtmfLen(i) >= 1) and (SsmCheckPlay(i) > 0) then
      begin
        SsmGet1stDtmf(i,@tmp);
        SsmClearRxDtmfBuf(i);
        case tmp of

        '1'://DTMF=1: record to file "test.voc"
        begin
          if(SsmPlayIndexString(i,'RecPrompt') = -1) then	//play "press any key to start, and any key again to stop".
            AppErrorHandler(i)
          else
          begin
            ATrkCh[i].dwTimeOutCounter := 0;
            ATrkCh[i].Step := TRK_CHECK_REC_START;
          end;
        end;

        '2'://DTMF=2: play recorded file "test.voc"
        begin
          strCurrentDir:=GetCurrentDir();
          if FileSearch('test.voc', strCurrentDir) <>'' then
          begin
            if SsmPlayFile(i,'test.voc',6,0,$FFFFFFFF) = -1 then
              AppErrorHandler(i)
            else ATrkCh[i].Step := TRK_CHECK_PLAY_RECORD;
          end
	  else begin
            if SsmPlayIndexString(i,'FileNotFound') = -1 then AppErrorHandler(i)	//play "file not found" message
            else ATrkCh[i].Step := TRK_CHECK_PLAY_RECORD;
          end;
        end;

        '3'://DTMF=3: play user's password,some sample digital
        begin
          SsmSetDtmfStopPlay(i,FALSE);	//disable DTMF-Stop-Play function while playing password
          if SsmPlayIndexString(i,'YourPasswordIs,1,2,3,4') = -1 then//play "your password is 1234".
            AppErrorHandler(i)
          else ATrkCh[i].Step := TRK_CHECK_PLAY_PASSWORD;
        end;

        '0'://DTMF=0:  end of service,play "Byebye"
        begin
          if ( SsmPlayIndexString(i, 'Byebye' )= -1 ) then AppErrorHandler(i)
          else ATrkCh[i].Step := TRK_CHECK_PLAY_BYEBYE;
        end;

        end;//end of case
      end
      else if(SsmCheckPlay(i) > 0) then // end of playing "Select"
      begin
        if ATrkCh[i].lineState = S_CALL_PENDING then//check if remote user hangup
        begin
          SsmHangup(i);
          ATrkCh[i].Step := TRK_IDLE;
        end
        else begin
          ATrkCh[i].dwTimeOutCounter:=ATrkCh[i].dwTimeOutCounter+1;
          if(ATrkCh[i].dwTimeOutCounter > 300) then // wait DTMF key for maximum 30 seconds
          begin
            if ( SsmPlayIndexString( i, 'Byebye' )= -1 ) then AppErrorHandler(i)
            else ATrkCh[i].Step := TRK_CHECK_PLAY_BYEBYE;
          end;
        end;
      end;
    end;

    TRK_CHECK_PLAY_PASSWORD:
      if(SsmCheckPlay(i) > 0) then ATrkCh[i].Step := TRK_PLAY_SELECT;//this channel is not playing index now

    TRK_CHECK_REC_START:
    begin
      if(SsmGetRxDtmfLen(i) >= 1) then
      begin
        SsmClearRxDtmfBuf(i);
        if( SsmRecToFile(i,'test.voc',6,0,10*8000,0,0) = -1) then //start from 16000L,maxmium 10 seconds
          AppErrorHandler(i)
        else ATrkCh[i].Step := TRK_CHECK_REC_END;
      end
      else begin
        ATrkCh[i].dwTimeOutCounter:=ATrkCh[i].dwTimeOutCounter+1;
        if(ATrkCh[i].dwTimeOutCounter > 300) then//wait 15 seconds for DTMF-key
        begin
          if ( SsmPlayIndexString( i, 'Byebye' )= -1 ) then
            AppErrorHandler(i)
          else ATrkCh[i].Step := TRK_CHECK_PLAY_BYEBYE;
        end;
      end;
    end;

    TRK_CHECK_REC_END:
    begin
      if( SsmGetRxDtmfLen(i) >= 1 )
      or( SsmChkRecToFile(i)=0) then
      begin
        SsmStopRecToFile(i);
        ATrkCh[i].Step := TRK_PLAY_SELECT;
      end;
    end;

    TRK_CHECK_PLAY_RECORD:
      if(SsmCheckPlay(i) > 0) then ATrkCh[i].Step := TRK_PLAY_SELECT;

    TRK_CHECK_PLAY_BYEBYE:
    begin
      if(SsmCheckPlay(i) > 0) then
      begin
        SsmHangup(i);
        ATrkCh[i].Step := TRK_IDLE;
      end;
    end;
    end;//end of case
  end;//end of for
end;

////////////////////////////////////////////////////////////////////////
procedure UpDateATrunkChListCtrl;
var
  state:Pchar ;
  tmpstr:String;
  i:Integer;
  nIndex : Integer;

begin
  nIndex:=0;
  for i:=0 to nTotATrkCh-1 do
  if ATrkCh[i].EnCalled = true  then
  begin
    case ATrkCh[i].Step of
    TRK_IDLE:			state := '空闲';
    TRK_WAIT_CONNECT:		state := '等待连接';
    TRK_PLAY_WELCOM:            state := '正在播放欢迎词';
    TRK_CHECK_PLAY_WELCOM:	state := '播放欢迎词';
    TRK_CHECK_PLAY_SELECT:	state := '等待按键选择';
    TRK_CHECK_REC_START:	state := '等待录音开始';
    TRK_CHECK_REC_END:		state := '录制留言';
    TRK_CHECK_PLAY_RECORD:	state := '播放留言';
    TRK_CHECK_PLAY_BYEBYE:	state := '播放结束语';
    TRK_CHECK_PLAY_PASSWORD:	state := '播放密码';
    TRK_NOTRK:                  state := '非模拟外线通道';
    else			state := '未定义';
    end;
    tmpstr:=MainForm.StateListView.Items[nIndex].SubItems[0];
    if  state <> tmpstr then
      MainForm.StateListView.Items[nIndex].SubItems[0]:=state;

    tmpstr:=MainForm.StateListView.Items[nIndex].SubItems[1];
    if tmpstr <> ATrkCh[i].pCallerId then
      MainForm.StateListView.Items[nIndex].SubItems[1]:=ATrkCh[i].pCallerId;


    if ATrkCh[i].Step = TRK_IDLE then
    begin
      state := '';
      tmpstr:=MainForm.StateListView.Items[nIndex].SubItems[2];
        if state <> tmpstr then
          MainForm.StateListView.Items[nIndex].SubItems[2]:=StrPas(state);
    end
    else
    begin
      GetMem(state,100);
      if SsmGetDtmfStr(i, state) > 0 then //receive and display DTMF keys
      begin
        tmpstr:=MainForm.StateListView.Items[nIndex].SubItems[2];
        if state <> tmpstr then
          MainForm.StateListView.Items[nIndex].SubItems[2]:=StrPas(state);
      end;
      FreeMem(state);
    end;

    tmpstr:=MainForm.StateListView.Items[nIndex].SubItems[3];//display error messages occured
    if ATrkCh[i].pErrMsg <> tmpstr then
      MainForm.StateListView.Items[nIndex].SubItems[3]:=ATrkCh[i].pErrMsg;
    nIndex:=nIndex+1;

  end;
end;


///////////////////////////////////////////////////////////////////////
procedure InitATrunkCh;
var
  i:Integer;
  nDirection:Integer;
begin
  nTotATrkCh := SsmGetMaxCh();
  for i:=0 to nTotATrkCh-1 do
  begin
    ATrkCh[i].EnCalled := false;

    if SsmGetAutoCallDirection(i,@nDirection) = 1  then //允许自动接续
    begin
      if ( nDirection = 0) or (nDirection = 2) then //enable call in
      begin
        ATrkCh[i].Step := TRK_IDLE;
        ATrkCh[i].EnCalled := true;
      end;
    end;
  end;
end;

///////////////////////////////////////////////////////////////////////
procedure AppErrorHandler(ch:Integer);
var
  ErrMsg:PChar;
begin
  SsmHangup(ch);
  GetMem(ErrMsg,200);
  SsmGetLastErrMsg(ErrMsg);
  ATrkCh[ch].pErrMsg:=StrPas(ErrMsg);
  FreeMem(ErrMsg);
  ATrkCh[ch].Step := TRK_IDLE;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -