21,887
社区成员
发帖
与我相关
我的任务
分享
<?php
/**
*@desc 飞信短信发送类(Encoded:UTF-8)
*使用方法:
* * $myNewFetion = new myFetion('1381111111', 'password','SELF', '测试消息' ); // 给自己发
* $myNewFetion = new myFetion('1381111111', 'password','1382222222', '测试消息' ); // 给一个人发
* $myNewFetion = new myFetion('1381111111', 'password','1382222222,13833333333,13844444444', '测试消息' ); // 给很多人发
* $myNewFetion = new myFetion('1381111111', 'password','ALL', '测试消息' ); // 给所有飞信好友发
*非常感谢CSDN论坛ycTIN在MD5加密部分的帮助!
*本程序未做容错处理,为防止诈骗短信乱发,程序不提供添加好友功能
*测试URL:http://i.isclab.org/tools/fetion.php
*
*程序运行条件:
*1.服务器能够访问飞信服务器nav.fetion.com.cn的443端口(https)
*2.服务器端PHP程序能够创建socket访问221.176.31.4的8080端口
*
*关键技术:
*1.CURL + SSL通讯
*2.PHP Socket编程
*3.PHP MD5函数的深入理解
*4.PHP DOM处理XML
*
*@author shadu AT foxmail DOT com /CNOS(http://bbs.ouropen.org)
*@version 2010-03-04
*@copyright 任意拷贝和修改!
*@update 修正了只能给自己发短信的bug,感谢jjchibin的提醒
*@update 增加了群发功能
**/
class myFetion{
private $mobile_no = '1381111111'; // 发送者手机号
private $fetion_no = '738713940' ; // 发送者飞信号,程序自动获取
private $fetion_uri = 'sip:123456789@fetion.com.cn;p=1234'; // 发送者的sip
private $fetion_pwd = 'mypassword' ; // 发送者飞信登录密码
private $cookie_file = 'cookie.txt' ; // 临时存放的cookie文件
public $SMS_RECEIVER = '1382222222' ; // 短信接收者手机号码
public $SMS_TEXT = 'sms test' ; // 短信内容,支持中文
private $fetion_ContactList = "" ;
private $fetion_ContactMapping = array();
private $NONCE = 'AAB3238922BCC25A6F606EB525FFDC56' ; // SIPC服务器返回,每次不同
private $C_NONCE = 'AAB3238922BCC25A6F606EB525FFDC56' ; // 是随机的,但是固定值也没关系
private $SSIC = '' ; // cookie中提取的变量
private $RESPONSE = '' ; // 加密后的密钥串
private $url_nav = 'https://nav.fetion.com.cn/nav/getsystemconfig.aspx' ; // 443端口获取导航信息
private $domain_fetion = 'fetion.com.cn' ; // 飞信服务器的域名
private $SIPC_PROXY = '221.176.31.4:8080'; // 8080端口飞信通讯使用
private $SSI_PROXY_SIGN_IN = 'https://uid.fetion.com.cn/ssiportal/SSIAppSignIn.aspx' ; // 登录URL
private $SSI_PROXY_SIGH_OUT = 'http://ssi.fetion.com.cn/ssiportal/SSIAppSignOut.aspx' ; // 登出URL
private $curl = NULL ;
private $socket = NULL ;
/**
*从导航网站获取信息
**/
private $REQUEST_CONFIG = "<config><user mobile-no=\"%s\" /><client type=\"PC\" version=\"2.3.0230\" platform=\"W5.1\" /><servers version=\"0\" /><service-no version=\"12\" /><parameters version=\"15\" /><hints version=\"13\" /><http-applications version=\"14\" /><client-config version=\"17\" /></config>";
/**
*使用手机号码和密码向服务器获取对应的飞信号码信息
**/
private $REQUEST_SSI_SIGN = "mobileno=%s&pwd=%s" ;
/**
*使用飞信号码向SIPC服务器注册,获取临时变量NONCE和SSIC的值
**/
private $REQUEST_SIPC_SIGN_NONCE = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 1 R\r\nL: %d\r\n\r\n%s" ;
private $REQUEST_SIPC_SIGN_NONCE_BODY = "<args><device type=\"PC\" version=\"6\" client-version=\"2.3.0230\" /><caps value=\"simple-im;im-session;temp-group\" /><events value=\"contact;permission;system-message\" /><user-info attributes=\"all\" /><presence><basic value=\"400\" desc=\"\" /></presence></args>";
/**
*使用飞信号码和加密的密码登录飞信SIPC服务器
**/
private $REQUEST_SIPC_LOGIN = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 2 R\r\nA: Digest response=\"%s\",cnonce=\"%s\"\r\nL: %d\r\n\r\n%s";
private $REQUEST_SIPC_LOGIN_BODY = "<args><device type=\"PC\" version=\"6\" client-version=\"2.3.0230\" /><caps value=\"simple-im;im-session;temp-group\" /><events value=\"contact;permission;system-message\" /><user-info attributes=\"all\" /><presence><basic value=\"400\" desc=\"\" /></presence></args>";
/**
* 发短信
*/
private $REQUEST_SIPC_SENDSMS = "M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: %s\r\nN: SendSMS\r\nL: %d\r\n\r\n%s";
/**
* 退出
**/
private $REQUEST_SIPC_LOGOUT = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n";
/**
* 获取好友列表
**/
private $REQUEST_SIPC_GetContactList = "S %s SIP-C/2.0\r\nF: %s\r\nI: 3\r\nQ: 1 S\r\nN: GetContactList\r\nL: %d\r\n\r\n%s" ;
private $REQUEST_SIPC_GetContactListBody = "<args><contacts><buddy-lists /><buddies attributes=\"all\" /><mobile-buddies attributes=\"all\" /><chat-friends /><blacklist /></contacts></args>";
/**
* 获取好友信息
**/
private $REQUESR_SIPC_GetContactsInfo = "S %s SIP-C/2.0\r\nF: %s\r\nI: 9\r\nQ: 1 S\r\nN: GetContactsInfo\r\nL: %d\r\n\r\n%s";
private $REQUESR_SIPC_GetContactsInfo_body = "<args><contacts attributes=\"provisioning;impresa;mobile-no;nickname;name;gender;portrait-crc;ivr-enabled\" extended-attributes=\"score-level\">%s</contacts></args>" ;
/**
*@param $sender 短信发送者手机号
*@param $passwd 短信发送者密码
*@param $receiver 短信接收者手机号
*@param $msg 短信内容
**/
public function __construct($sender, $passwd, $receiver, $msg){
$this->mobile_no = $sender ;
$this->fetion_pwd = $passwd;
$this->SMS_RECEIVER = $receiver;
$this->SMS_TEXT = $msg;
$this->cookie_file = $this->mobile_no . $this->cookie_file ;
$this->FetionStart();
}
/**
* 开始Fetion短信发送处理流程
*
*/
private function FetionStart(){
$this->FetionGetConfig(); // 从导航网站443端口获取登录信息
if($this->FetionSocektInit()) // 初始化到SIPC的8080端口socket连接
{
$this->FetionGetSIPCNonce(); // 向服务器注册飞信号,获取关键变量值
if($this->FetionLogin()){ // 发送登录认证命令
if(!$this->FetionGetContactLists()){ // 取飞信用户列表
$this->SMS_RECEIVER == "SELF";
};
$this->FetionGetContactsInfo(); // 建立电话号码到飞信号码的映射
//$this->FetionSendSMS(); // 发短信!
if("ALL" == $this->SMS_RECEIVER){ // 给飞信上所有好友发
foreach($this->fetion_ContactMapping as $sip){
$this->FetionSendSMS($sip);
}
}
elseif("SELF" == $this->SMS_RECEIVER){ // 给自己发
$this->FetionSendSMS($this->fetion_uri);
}
else{ // 发给指定的手机号集合"13811111111,13822222222,13833333333"
$mobile_array = split("," , $this->SMS_RECEIVER);
foreach($mobile_array as $mobile){
$this->FetionSendSMS($this->fetion_ContactMapping["$mobile"]);
}
}
$this->FetionLogout();
}
else
{
echo "登录失败\n";
}
}
else
{
echo "Socket 初始化失败\n";
}
}
/**
*从导航地址获取配置信息
**/
private function FetionGetConfig(){
$this->REQUEST_CONFIG = sprintf($this->REQUEST_CONFIG,
$this->mobile_no);
$this->curl = curl_init();
curl_setopt($this->curl, CURLOPT_URL, $this->url_nav);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookie_file);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->curl, CURLOPT_POST, 1);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->REQUEST_CONFIG);
$xml_config = curl_exec($this->curl);
// 以下是从导航页面返回的XML里取相关信息
file_put_contents("test3.xml", $xml_config) ;
$xmlDom = new DOMDocument() ;
$xmlDom->loadXML($xml_config);
$fetion_server = $xmlDom->getElementsByTagName('servers');
$fetion_server->item(0)->getElementsByTagName('sipc-proxy')->item(0)->nodeValue;
$this->SSI_PROXY_SIGN_IN = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-in')->item(0)->nodeValue;
$this->SSI_PROXY_SIGH_OUT = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-out')->item(0)->nodeValue;
$this->SSI_PROXY_SIGN_IN;
// 以下获取手机号对应的飞信号
sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd) ;
curl_setopt($this->curl, CURLOPT_URL, $this->SSI_PROXY_SIGN_IN);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd));
$Result = curl_exec($this->curl);
curl_close($this->curl);
file_put_contents("test4.xml", $Result) ;
$xmlDom->loadXML($Result);
$uri = $xmlDom->getElementsByTagName("user")->item(0)->getAttribute("uri");
//"sip:738713940@fetion.com.cn;p=5914"
$this->fetion_uri = $uri ; // 发送者自己的sip
if(preg_match('/^sip:(\d+)@(\S+);.*$/', $uri, $matches)){
$this->fetion_no = $matches[1] ;
$this->domain_fetion = $matches[2] ;
}
}
/**
*初始化Fetion通讯Socket
**/
private function FetionSocektInit(){
$this->SIPC_PROXY;
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
list($ip_fetion, $port_fetion) = split(':', $this->SIPC_PROXY) ; // "221.176.31.4:8080"
return socket_connect($this->socket, $ip_fetion, $port_fetion) ;
}