设为首页收藏本站新闻投稿

MOD中国同盟社

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1310|回复: 1

[教程] PHP写的飞信API接口,不需要第三方API [复制链接]

Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20

帖子
2836
精华
2
声望
12984 点
金币
2999 Mold
被赞许
28 次
注册时间
2006-4-28

Mod中国同盟社至高荣誉

发表于 2010-8-28 10:33:48 |显示全部楼层
PHP写的飞信API接口,不需要第三方API。网上找到的。保留以便于以后使用。呵呵。
  1. <?php
  2. /*
  3. Fetion Api
  4. License        :部分代码来自bit.kevin@gmail.com 本人增加了群发  所需PHP扩展:curl, **xml。字符编码均为UTF-8
  5. Author:threesky@gmail.com, http://www.heqee.com/
  6. */
  7. class fetion {
  8.    
  9.     //communicate url
  10.     private static $sd_url = "http://221.130.44.194/ht/sd.aspx";
  11.         //"http://221.176.31.42/ht/sd.aspx"
  12.     //sign in url
  13.     private static $sign_in_url = "https://uid.fetion.com.cn/ssiportal/SSIAppSignIn.aspx";
  14.     //SSIC
  15.     private $ssic;
  16.     //guid
  17.     private $guid;
  18.    
  19.     //user
  20.     private $user;

  21.     //mobile no.
  22.     private $mobileno;
  23.     //pwd
  24.     private $pwd;
  25.    
  26.     //error
  27.     public $error;
  28.    
  29.     //version
  30.     public static $version = "0.1";
  31.    
  32.     public function __construct($mobileno, $pwd)
  33.     {
  34.             $this->guid = self::guid();
  35.             $this->mobileno = $mobileno;
  36.             $this->pwd = $pwd;
  37.                 $this->init();
  38.     }
  39.    
  40.     /**
  41.      * init. sign in and reg on server
  42.      *
  43.      * @return bool
  44.      */
  45.     public function init()
  46.     {
  47.             return $this->sign_in() && $this->reg_server();
  48.     }
  49.    
  50.     /**
  51.      * 生成GUID
  52.      *
  53.      * @return string
  54.      */
  55.     private static function guid()
  56.     {
  57.         if (function_exists('com_create_guid')){
  58.             return com_create_guid();
  59.         }else{
  60.             mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
  61.             $charid = strtoupper(md5(uniqid(rand(), true)));
  62.             $hyphen = chr(45);// "-"
  63.             $uuid = chr(123)// "{"
  64.                     .substr($charid, 0, 8).$hyphen
  65.                     .substr($charid, 8, 4).$hyphen
  66.                     .substr($charid,12, 4).$hyphen
  67.                     .substr($charid,16, 4).$hyphen
  68.                     .substr($charid,20,12)
  69.                     .chr(125);// "}"
  70.             return $uuid;
  71.         }
  72.     }   
  73.    
  74.     /**
  75.      * 获取通信次数
  76.      *
  77.      * @return int
  78.      */
  79.     private function call_id()
  80.     {
  81.         static $call_id=0;
  82.         return ++$call_id;
  83.     }
  84.         
  85.     /**
  86.      * 请求URL
  87.      *
  88.      * @param string $t
  89.      * @return string
  90.      */
  91.     private function request_url($t='s') {
  92.             static $seq = 0;
  93.             ++$seq;
  94.             return self::$sd_url."?t=$t&i=$seq";
  95.     }

  96.     //hex to binary
  97.     private function hex2bin($hex) {
  98.             $bin = '';
  99.             $len = strlen($hex);
  100.             for ($I = 0; $I < $len; $I += 2) {
  101.                     $bin .= chr(hexdec(substr($hex, $I, 2)));
  102.             }
  103.             return $bin;
  104.     }
  105.    
  106.     //get hash password
  107.     private function hash_password() {
  108.             // in fact, salt is constant value
  109.             $salt = chr(0x77).chr(0x7A).chr(0x6D).chr(0x03);
  110.             $src = $salt.hash('sha1', $this->pwd, true);
  111.             return strtoupper(bin2hex($salt.sha1($src, true)));
  112.     }
  113.    
  114.     //create a random cnonce
  115.     private function calc_cnonce() {
  116.             return sprintf("%04X%04X%04X%04X%04X%04X%04X%04X",
  117.                     rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
  118.                     rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF,
  119.                     rand() & 0xFFFF, rand() & 0xFFFF);
  120.     }
  121.    
  122.     //get salt from real password
  123.     private function calc_salt() {
  124.             return substr($this->hash_password(), 0, 8);
  125.     }
  126.    
  127.     //calculate response
  128.     private function calc_response($nonce, $cnonce) {
  129.             $str = $this->hex2bin(substr($this->hash_password(), 8));
  130.             $key = sha1($this->user['sid'].':'.$this->user['domain'].':'.$str, true);
  131.             $h1 = strtoupper(md5("$key:$nonce:$cnonce"));
  132.             $h2 = strtoupper(md5("REGISTER:".$this->user['sid']));
  133.             $res = strtoupper(md5("$h1:$nonce:$h2"));
  134.             return $res;
  135.     }

  136.     //create sip package
  137.     private function sip_request_create($request_line, $fields, $arg = '') {
  138.             $sip = $request_line."\r\n";
  139.             foreach ($fields as $k=>$v) {
  140.                     $sip .= "$k: $v\r\n";
  141.             }
  142.             $sip .= "L: ".strval(strlen($arg))."\r\n\r\n{$arg}";
  143.             return $sip;
  144.     }
  145.    
  146.    
  147.     /**
  148.      * 发起一个GET、POST的HTTP请求
  149.      *
  150.      * @param string $url
  151.      * @param mixed $post_data
  152.      * @param bool $do_exec
  153.      * @return mixed
  154.      */
  155.     private function http_request($url, $post_data=null, $do_exec=true)
  156.     {   
  157.         $headers = array('Content-Type: application/oct-stream', 'Pragma: xz4BBcV'.$this->guid);
  158.         
  159.             $ch = curl_init();
  160.             curl_setopt($ch, CURLOPT_URL, $url);
  161.             curl_setopt($ch, CURLOPT_USERAGENT, 'IIC2.0/PC 3.2.0540');
  162.             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  163.             curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  164.             curl_setopt($ch, CURLOPT_HEADER, true);
  165.            
  166.         if( stripos($url, "https://") !== FALSE ) {
  167.             curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  168.             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  169.         }
  170.    
  171.             //ssic
  172.             if( $this->ssic!="" ) {
  173.                 curl_setopt($ch, CURLOPT_COOKIE, "ssic={$this->ssic}");
  174.             }
  175.            
  176.         //post data
  177.             if( $post_data != null ) {
  178.                     curl_setopt($ch, CURLOPT_POST, true);
  179.                     if( is_array($post_data) )
  180.                     {
  181.                         $encoded = "";
  182.                 foreach ( $post_data as $k=>$v)
  183.                 {
  184.                     $encoded .= ($encoded ? "&" : "");
  185.                     $encoded .= rawurlencode($k)."=".rawurlencode($v);
  186.                 }
  187.                 curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
  188.                     }else{
  189.                         curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
  190.                     }
  191.                    
  192.             }
  193.            
  194.             //no exec
  195.             if( $do_exec == false ) {
  196.                 return $ch;
  197.             }
  198.            
  199.             $res = curl_exec($ch);
  200.             if( !$res ) {
  201.                     $this->error(curl_error($ch));
  202.                     exit;//exit!
  203.             }
  204.             curl_close($ch);
  205.    
  206.             $res = explode("\r\n\r\n", $res);
  207.            
  208.             //SIP协议的HTTP承载方式中,其头部和消息主题也是采用\r\n\r\n分割
  209.             return $res;//$res[0]=>header $res[1]=>body $res[...]=>...
  210.     }
  211.    
  212.     /**
  213.      * 获取好友列表
  214.      *
  215.      * @return mixed
  216.      */
  217.     public function get_friends_list()
  218.     {   
  219.             $arg = '<args><contacts><buddy-lists /><buddies attributes="all" /><mobile-buddies attributes="all" /><chat-friends /><blacklist /></contacts></args>';
  220.             $msg = $this->sip_request_create('S fetion.com.cn SIP-C/2.0', array('F'=>$this->user['sid'], 'I'=>$this->call_id(), 'Q'=>'1 S', 'N'=>'GetContactList'), $arg)."SIPP";
  221.            
  222.             $this->http_request($this->request_url(), $msg);           
  223.             $res = $this->http_request($this->request_url(), "SIPP");
  224.            
  225.             $list_xml = substr($res[2], 0, strlen($res[2])-4);

  226.             $buddy_list = **xml_load_string($list_xml);
  227.            
  228.             $buddies = array();
  229.             foreach ($buddy_list->contacts->buddies->buddy as $buddy) {
  230.                     $buddies[strval($buddy['uri'])] = strval($buddy['local-name']);
  231.             }
  232.             foreach ($buddy_list->contacts->{'mobile-buddies'}->{'mobile-buddy'} as $buddy) {
  233.                     $buddies[strval($buddy['uri'])] = strval($buddy['local-name']);
  234.             }
  235.            
  236.             return $buddies;
  237.     }
  238.     /**
  239.      * 单点登录
  240.      * @return mixed
  241.      */
  242.     private function sign_in()
  243.     {
  244.         $ssiportal_url = self::$sign_in_url."?mobileno=".rawurlencode($this->mobileno)."&pwd=".rawurlencode($this->pwd);
  245.         $value = array();
  246.         
  247.         $res = $this->http_request($ssiportal_url);
  248.         
  249.         $matches = array();
  250.         if( preg_match("/Set-Cookie: ssic=(.*);/", $res[0], $matches)==0 ) {
  251.             $this->error("登录失败。可能原因:用户名和密码错误!");
  252.             return false;
  253.         }
  254.         $this->ssic = $matches[1];
  255.         
  256.         $xml = **xml_load_string($res[1]);
  257.         $value['uri'] = (string)$xml->user['uri'];
  258.         $value['status-code'] = (string)$xml['status-code'];
  259.         $value['mobile-no'] = (string)$xml->user['mobile-no'];
  260.         $value['user-status'] = (string)$xml->user['user-status'];
  261.    
  262.             if( preg_match("/sip:(\d+)@(.+);/", $value['uri'], $matches)==0 ) {
  263.                     $this->error("无法解析出sip相关信息。");
  264.                     return false;
  265.             }
  266.             $value['sid'] = $matches[1];
  267.         $value['domain'] = $matches[2];
  268.         
  269.         //set ues info
  270.         $this->user = $value;
  271.         
  272.         return $value;
  273.     }
  274.    
  275.     /**
  276.      * 注册到服务器
  277.      *
  278.      * @return bool
  279.      */
  280.     private function reg_server()
  281.     {   
  282.             $arg = '<args><device type="PC" version="44" client-version="3.2.0540" />';
  283.             $arg .= '<caps value="**-im;im-session;temp-group;personal-group" />';
  284.             $arg .= '<events value="contact;permission;system-message;personal-group" />';
  285.             $arg .= '<user-info attributes="all" /><presence><basic value="400" desc="" /></presence></args>';
  286.    
  287.             //$res = $this->http_request($this->request_url(), "SIPP");
  288.            
  289.             $msg = $this->sip_request_create('R fetion.com.cn SIP-C/2.0', array('F'=>$this->user['sid'], 'I'=>$this->call_id(), 'Q'=>'1 R'), $arg)."SIPP";

  290.             $this->http_request($this->request_url('i'), $msg);               
  291.             $res = $this->http_request($this->request_url(), "SIPP");
  292.                        
  293.             $matches = array();
  294.             if( preg_match('/nonce="(\w+)"/s', $res[1], $matches)==0 ) {
  295.                     $this->error('Fetion Error: no nonce found');
  296.             }
  297.            
  298.             //nonce
  299.             $nonce = $matches[1];

  300.             $cnone = $this->calc_cnonce();
  301.             $response = $this->calc_response($nonce, $cnone);
  302.    
  303.             $msg = $this->sip_request_create('R fetion.com.cn SIP-C/2.0', array('F'=>$this->user['sid'], 'I'=>$this->call_id(), 'Q'=>'2 R', 'A'=>"Digest algorithm=\"SHA1-sess\",response=\"{$response}\",cnonce=\"{$cnone}\",salt=\"".$this->calc_salt().'"'), $arg)."SIPP";
  304.    
  305.             $this->http_request($this->request_url(), $msg);
  306.             $res = $this->http_request($this->request_url(), "SIPP");
  307.            
  308.             if( substr($res[1], 0, 16) != "SIP-C/2.0 200 OK" ) {
  309.                 $this->error("注册到服务器失败.");
  310.                 return false;
  311.             }
  312.            
  313.             return true;
  314.     }


  315.     /**
  316.      * 发送短信
  317.      *
  318.      * @param string $to
  319.      * @param string $content
  320.      * @return bool
  321.      */
  322.     public function sent_sms($to, $content)
  323.     {   
  324.             $msg = $this->sip_request_create('M fetion.com.cn SIP-C/2.0', array('F'=>$this->user['sid'], 'I'=>$this->call_id(), 'Q'=>'1 M', 'T'=>$to, 'N'=>'SendSMS'), $content)."SIPP";
  325.    
  326.             $this->http_request($this->request_url(), $msg);       
  327.             $res = $this->http_request($this->request_url(), "SIPP");
  328.            
  329.         if( substr($res[1], 0, 25) != "SIP-C/2.0 280 Send SMS OK" ) {
  330.                 $this->error("发送短息失败!");
  331.                 return false;
  332.             }
  333.            
  334.             return true;
  335.     }
  336.         public function send($to,$smstxt){
  337.                 $to = $this->make_semiangle($to);
  338.                 if(strstr($to,','))
  339.                 {
  340.                         $to=explode(',',$to);
  341.                 }else{
  342.                         $to=array($to);
  343.                 }
  344.                 foreach ($to as $v)
  345.                 {
  346.                         $this ->sent_sms('tel:'.$v,$smstxt);
  347.                 }
  348.                 return true;
  349.        
  350.         }
  351.         private function make_semiangle($str)
  352.         {
  353.                 $arr = array('(' => '(', ')' => ')','%' => '%', '+' => '+', '—' => '-', '-' => '-', '–' => '-',
  354.                                          ':' => ':', '。' => '.', '、' => ',', ',' => ',', '--' => '-','’' => "'", '‘' => "'","ˊ" => "'");
  355.                 return strtr($str, $arr);
  356.         }
  357.     /**
  358.      * error handle
  359.      *
  360.      * @param string $emsg
  361.      */
  362.     private function error($emsg)
  363.     {
  364.             $this->error = $emsg;
  365.             echo "<b>Modchina Info</b>: ".$emsg;
  366.                 //exit;
  367.     }
  368. }




  369. ?>
复制代码

使用道具 举报

Rank: 3Rank: 3

帖子
195
精华
0
声望
762 点
金币
155 Mold
被赞许
0 次
注册时间
2009-7-3
发表于 2010-8-29 13:28:23 |显示全部楼层
有个google的接口api
可以利用google的那个平台免费发短信
不过不支持中文等非英语文字

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

回顶部