Translate

2008-07-02

Script de montee de fiche CRM avec Asterisk

Voici le code en C# d'un petit module que j'ai écrit , qui se connecte au manager d'Asterisk détecte si l'agent présent sur la machine a répondu a un appel et lance un url en conséquence.
Très utile pour faire monter une fiche client lors d'un appel entrant.
Telechargement : http://rapidshare.com/files/126553896/montee_fiche.rar.html

Code Source:

Le fichier config.xml



Mainform.cs

/*
* SAMUEL LEVY
* Date: 21/01/2007
* Time: 11:23
* monte_fiche.cs
* Script de montee de fiche
* Il recupere l'evenement Link du manager d'Asterisk, recupere le numero de
* l'appel entrant puis lans ce browser pour ouvrir la fiche correspondante
*/
using System.Net;
using System.Xml;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Text;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Win32;

namespace monte_fiche
{

// SL 21/01/2007
// Classe de connexion au manager d'asterisk
// Gere la reception d'evenements tels les appels entrants
// Permet l'ouverture de la fiche associee au numero entrant
class manager_access
{
private string IPadress;
private int port;
private string utilisateur;
private string password;
private string sipuser;
private string scriptmontee;
private Socket MyAstSocket;
private IPEndPoint MyAstServerEndPoint;

//constructeur par defaut
public manager_access()
{
this.IPadress="";
this.port=0;
this.utilisateur="";
this.password="";
this.sipuser="";
this.scriptmontee="";
}

//constructeur
public manager_access(string t_server,int t_port,string t_utilisateur,
string t_password,string t_sipuser,string t_scriptmontee)
{
this.IPadress=t_server;
this.port=t_port;
this.utilisateur=t_utilisateur;
this.password=t_password;
this.sipuser=t_sipuser;
this.scriptmontee=t_scriptmontee;
}

//constructeur a partir du fichier XML
public manager_access(XmlTextReader FileConf)
{
FileConf.WhitespaceHandling=WhitespaceHandling.None;

//parsing du fichier de conf et ecriture dans les variables de la classe
while(FileConf.Read())
{

if(FileConf.LocalName=="serveur")
{
this.IPadress = FileConf.ReadString();
FileConf.Read();
this.port = Convert.ToInt32(FileConf.ReadString());
FileConf.Read();
this.utilisateur = FileConf.ReadString();
FileConf.Read();
this.password = FileConf.ReadString();
FileConf.Read();
this.scriptmontee = FileConf.ReadString();
FileConf.Read();
this.sipuser = FileConf.ReadString();
}
}
FileConf.Close();

//recuperation de l'user xlite de la machine
//this.sipuser = Recupere_User_Xlite();
}

~manager_access()
{
MyAstSocket.Close();
}

private string[] SplitByString(string testString, string split) {
int offset = 0;
int index = 0;
int[] offsets = new int[testString.Length + 1];

while(index < testString.Length) {
int indexOf = testString.IndexOf(split, index);
if ( indexOf != -1 ) {
offsets[offset++] = indexOf;
index = (indexOf + split.Length);
} else {
index = testString.Length;
}
}

string[] final = new string[offset+1];
if (offset == 0 ) {
final[0] = testString;
} else {
offset--;
final[0] = testString.Substring(0, offsets[0]);
for(int i = 0; i < offset; i++) {
final[i + 1] = testString.Substring(offsets[i] + split.Length, offsets[i+1] - offsets[i] - split.Length);
}
final[offset + 1] = testString.Substring(offsets[offset] + split.Length);
}
return final;
}

private string Recupere_User_Xlite()
{
//recupere dans la base de registre le nom du user X-Lite en cours
RegistryKey rk = Registry.CurrentUser;
RegistryKey rk2 = rk.OpenSubKey("Software\\CounterPathSolutionsInc\\X-Lite");
return rk2.GetValue("general:Username").ToString();
}
//Fonction de connexion au socket pour dialoguer avec le manager Asterisk
public void Ast_Connecte()
{
this.MyAstSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.MyAstServerEndPoint = new IPEndPoint(IPAddress.Parse(this.IPadress), this.port);
MyAstSocket.Connect(this.MyAstServerEndPoint);

}

//Cette fonction se logue au manager Asterisk et attend un evenement Link
// Si link cela veut dire qu'une communication est etablie pour le user
// on recupere alors le numero et l'on ouvre le browser sur la fiche correspondante
public void Ast_Logue_Et_Ecoute()
{
// Se logue
this.MyAstSocket.Send(Encoding.ASCII.GetBytes("Action: Login\r\nUsername: "+this.utilisateur+"\r\nSecret: "+this.password+"\r\nActionID: 1\r\n\r\n"));
int bytesRead = 0;
char[] delimiterChars = { ' ', '\n' };
string delimiterChars2 = "\r\n\r\n";
do
{
int affiche = 0;
byte[] buffer = new byte[1024];
bytesRead = this.MyAstSocket.Receive(buffer);
string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);

string[] blocs = SplitByString(response,delimiterChars2);
//string[] blocs = response.Split(delimiterChars2);
foreach(string bloc in blocs)
{
string[] reponseclatees = bloc.Split(delimiterChars);

if(Regex.Match(bloc, sipuser, RegexOptions.IgnoreCase).Success
&& Regex.Match(bloc, "Link", RegexOptions.IgnoreCase).Success
&& !Regex.Match(bloc, "UnLink", RegexOptions.IgnoreCase).Success
&& !(Regex.Match(bloc, "Channel2: SIP", RegexOptions.IgnoreCase).Success
&& Regex.Match(bloc, "Channel1: SIP", RegexOptions.IgnoreCase).Success
)
)
{
foreach(string s in reponseclatees)
{
if(affiche == 1)
{
//Si appel entrants lance le browser
if(!Regex.Match(s, sipuser, RegexOptions.IgnoreCase).Success)
{
affiche = 0;
//Lancement du browser et de la fiche
System.Diagnostics.Process.Start(scriptmontee+s);
affiche = 0;
// reponseclatees = null;
// break;
}
//appel sortant ne lance pas le browser
else
{
affiche = 0;
}
}
if(Regex.Match(s, "CallerID1:", RegexOptions.IgnoreCase).Success)
//if(Regex.Match(s, "CallerID2:", RegexOptions.IgnoreCase).Success)
//if(Regex.Match(s, "Channel2:", RegexOptions.IgnoreCase).Success)
{
affiche = 1;
}
else
{
affiche = 0;
}
}
}

if(Regex.Match(bloc, "Message: Authentication accepted", RegexOptions.IgnoreCase).Success)
{
// Send a ping request the asterisk server will send back a pong response.
this.MyAstSocket.Send(Encoding.ASCII.GetBytes("Action: Events\r\nEventMask: ON\r\n\r\n"));
}
}
}while(bytesRead != 0);
}

//accesseurs
public string a_serveur
{
get
{
return this.IPadress;
}
set
{
this.IPadress = value;
}
}
public int a_port
{
get
{
return this.port;
}
set
{
this.port = value;
}
}

public string a_utilisateur
{
get
{
return this.utilisateur;
}
set
{
this.utilisateur = value;
}
}

public string a_password
{
get
{
return this.password;
}
set
{
this.password = value;
}
}

public string a_sipuser
{
get
{
return this.sipuser;
}
set
{
this.sipuser = value;
}
}

public string a_scriptmontee
{
get
{
return this.scriptmontee;
}
set
{
this.scriptmontee = value;
}
}
//Fin accesseurs

}//Fin Classe manager_access



public partial class MainForm
{
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MainForm());
}

public MainForm()
{
//this.Show();
//this.Hide();
this.Activate();

string configuration_file = "C:\\Program Files\\montee_fiche\\config.xml";
//InitializeComponent();

//lecture de la configuration
XmlTextReader filexml=new XmlTextReader(configuration_file);

//cree une instance de connexion au Manager Asterisk grace au fichier de conf
manager_access MyManager = new manager_access(filexml);

// Se connecte au manager.
MyManager.Ast_Connecte();

// Se met en position d'attente d'evenements du manager
MyManager.Ast_Logue_Et_Ecoute();


}
}
}



Pour fonctionner , ce script doit être compile et installe avec le fichier de config dans C:\Program Files\montee_fiche\.
Il necessite .NET.

No comments: