Gimhoy's Blog

[文章目录]

您曾经浏览过

SAE域名绑定后,宕机时自动修改A记录并飞信通知

本文最后更新于2014年4月1日,已超过三年没有更新,如果文章内容失效,请反馈给我们,谢谢!

SAE域名绑定之后,一般是用CNAME方式将域名绑定到应用中。但是有时候我们需要用到A记录(比如说根域名,虽然在DNSPOD上可以设置CNAME记录,但很可能会影响到MX记录),而SAE的IP地址经常改变,ping应用二级域名得到的IP没多久就失效了(前些天网站因此几天打不开都没发现,我用的是教育网,自己能打开,但是电信线路变了)。还好DNSPOD有个功能叫D监控,可以帮你监控网站能否正常打开。如果发现宕机,DNSPOD会用邮件、短信、微信等方式提醒你。这里用到的是它的另一个通知方式,那就是URL回调。

“通过DNSPod 提供的D监控 URL 回调功能,您可以让宕机或恢复信息提交到您指定的 URL 上,从而更加灵活地处理各种通知信息。”

我们可以通过宕机之后的URL回调取得相关参数,并通过DNSPOD API实现自动修改记录的功能,再通过飞信发送宕机通知。

代码在后面,先说设置方法:
 

设置方法

1.点此下载代码,修改其中的参数为你自己的。

2.将代码上传到网站。

3.在DNSPOD开启D监控,在通知设置中回调URL一栏填入monitorCallback.php的地址,如https://blog.gimhoy.com/monitorCallback.php?rHost=hipic.sinaapp.com.其中rHost是SAE的二级域名。并设置回调密钥。

4.Enjoy~

dnspod-monitor-callback

 

代码

monitorCallback.php

<?php header('Content-type:text/html; charset=utf-8');
/*
 * Copyright 2007-2014 Gimhoy Studio.
 * 
 * @author		Gimhoy
 * @email		contact@gimhoy.com
 * @version     1.0.0
 */
$rHost = $_GET['rHost'];     // SAE二级域名
if(empty($rHost)) $rHost = 'sinaapp.com';
$logName = 'monitorLog.txt';  //log 文件名
$logStorDomain = 'log';  // Storage Domain
$FetionNum = ''; //飞信登陆号码
$FetionPwd = ''; //飞信登陆密码
$MobileNum = ''; //接收通知短信的号码
 
$callback_key  = 'MYKEY';                    // 添加监控时设置的密钥

$monitor_id     = $_POST['monitor_id'];     // 监控编号
$domain_id     = $_POST['domain_id'];      // 域名编号
$domain          = $_POST['domain'];         // 域名名称
$record_id       = $_POST['record_id'];      // 记录编号
$sub_domain  = $_POST['sub_domain'];     // 主机名称
$record_line    = $_POST['record_line'];    // 记录线路
$ip         			 = $_POST['ip'];             // 记录IP
$status             = $_POST['status'];         // 当前状态
$status_code  = $_POST['status_code'];    // 状态代码
$reason           = $_POST['reason'];         // 宕机原因
$created_at     = $_POST['created_at'];     // 发生时间
$checksum     = $_POST['checksum'];       // 校检代码

if (md5($monitor_id. $domain_id. $record_id. $callback_key. $created_at) != $checksum) {
    // 非法请求
    echo 'BAD REQUEST';
} else {
    // 开始处理
    if ($status == 'Warn' || $status == 'Ok') {
        // 宕机恢复
		$msg =  date("Y-m-d H:i:s").'  '.$sub_domain.'.'.$domain."(".$record_line." ".$ip.")宕机恢复";
   } elseif ($status == 'Down') {
        // 宕机
		$msg = date("Y-m-d H:i:s").'  '.$sub_domain.'.'.$domain."(".$record_line." ".$ip.")在".$created_at."宕机。宕机原因:".$reason."可用IP:";
		$ips = @gethostbyname($rHost); 
		include_once 'dnspod.class.php';
			$newIP = $ips;
			$data = array(
					'domain_id' => $domain_id,
					'record_id' => $record_id,
					'sub_domain' => $sub_domain,
					'record_type' => 'A',
					'record_line' => $record_line,
					'ttl'	=> '600',
					'value' => $newIP
				);
			$dnspod = new dnspod();
			$response = $dnspod->api_call('Record.Modify', $data);
			if(isset($response['status']['code']) && $response['status']['code'] == 1) {
					$msg = $msg.$newIP.'(已切换)';
				}
				else {
					$msg = $msg.$newIP.'(切换失败,错误代码'.$response['status']['code'].')';
				}
	}
		//飞信通知
		require_once 'Fetion.class.php';
		$fetion = new PHPFetion($FetionNum, $FetionPwd); 
		$result = $fetion->send($MobileNum, $msg); 
		if(strpos($result, '短信发送成功!') || strpos($result, '发送消息成功!')) { $r = "成功。";}else{$r = "失败。";}		
		$s = new SaeStorage();
		$content = $s -> read($logStorDomain, $logName);
		$content = $content.$msg.'。飞信通知'.$r.'
  ';
		$s -> write($logStorDomain, $logName, $content);

    // 处理完成
    echo 'DONE';
}

dnspod.class.php

<?php header('Content-type:text/html; charset=utf-8');
/*
 * DNSPod API PHP Web 示例
 * https://www.zhetenga.com/
 *
 * Copyright 2011, Kexian Li
 * Released under the MIT, BSD, and GPL Licenses.
 *
 */

class dnspod {
	public function api_call($api, $data) {
		if ($api == '' || !is_array($data)) {
			exit('内部错误:参数错误');
		}
		
		$api = 'https://dnsapi.cn/' . $api;
		$data = array_merge($data, array('login_email' => 'DNSPOD登陆账号', 'login_password' => 'DNSPOD登陆密码', 'format' => 'json', 'lang' => 'cn', 'error_on_empty' => 'yes'));

		$result = $this->post_data($api, $data);

		if (!$result) {
			exit('内部错误:调用失败');
		}
		
		$results = @json_decode($result, 1);
        
		if (!is_array($results)) {
			exit('内部错误:返回错误');
		}
		
		if ($results['status']['code'] != 1) {
			exit($results['status']['message']);
		}
		
		return $results;
	}
	
	private function post_data($url, $data) {
		if ($url == '' || !is_array($data)) {
			return false;
		}
		
		$ch = @curl_init();
		if (!$ch) {
			exit('内部错误:服务器不支持CURL');
		}
		
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
		curl_setopt($ch, CURLOPT_USERAGENT, 'Gimhoy Monitor/1.0 (contact@gimhoy.com)');
		$result = curl_exec($ch);
		curl_close($ch);
		
		return $result;
	}
}

Fetion.class.php

<?php
header('Content-Type: text/html; charset=utf-8');
/**
 * PHP飞信发送类
 * @author quanhengzhuang <blog.quanhz.com>
 * @version 1.5.0
 */
class PHPFetion {
	
	/**
	 * 发送者手机号
	 * @var string
	 */
	protected $_mobile;
	
	/**
	 * 飞信密码
	 * @param string
	 */
	protected $_password;
	
	/**
	 * Cookie字符串
	 * @param string
	 */
	protected $_cookie = '';
        
        /**
     	* Uid缓存
     	* @var array
     	*/
   	protected $_uids = array();
        
        /**
 	* csrfToken
 	* @param string
 	*/
	protected $_csrfToten = null;
	
	/**
	 * 构造函数
	 * @param string $mobile 手机号(登录者)
	 * @param string $password 飞信密码
	 */
	public function __construct($mobile, $password)
    {
        if ($mobile === '' || $password === '')
        {
            return;
        }
        
        $this->_mobile = $mobile;
        $this->_password = $password;
        
        $this->_login();
    }
	
	/**
	 * 析构函数
	 */
	public function __destruct() {
		$this->_logout();
	}
	
	/**
	* 登录
 	* @return string
 	*/
	protected function _login()
    {
        $uri = '/huc/user/space/login.do?m=submit&fr=space';
        $data = 'mobilenum='.$this->_mobile.'&password='.urlencode($this->_password);
        
        $result = $this->_postWithCookie($uri, $data);

        //解析Cookie
        preg_match_all('/.*?\r\nSet-Cookie: (.*?);.*?/si', $result, $matches);
        if (isset($matches[1]))
        {
            $this->_cookie = implode('; ', $matches[1]);
        }
        
        $result = $this->_postWithCookie('/im/login/cklogin.action', '');

        return $result;
    }
        
        
	/**
 	* 获取csrfToken,给好友发飞信时需要这个字段
 	* @param string $uid 飞信ID
 	* @return string
	*/
	protected function _getCsrfToken($uid)
    {
        if ($this->_csrfToten === null)
        {
            $uri = '/im/chat/toinputMsg.action?touserid='.$uid;
            
            $result = $this->_postWithCookie($uri, '');
            
            preg_match('/name="csrfToken".*?value="(.*?)"/', $result, $matches);

            $this->_csrfToten = isset($matches[1]) ? $matches[1] : '';
        }

        return $this->_csrfToten;
    }

	/**
	 * 向指定的手机号发送飞信
	 * @param string $mobile 手机号(接收者)
	 * @param string $message 短信内容
	 * @return string
	 */
	public function send($mobile, $message) {
		if($message === '') {
			return '';
		}
		// 判断是给自己发还是给好友发
		if($mobile === $this->_mobile) {
			return $this->_toMyself($message);
		} 
		else if(strlen($mobile)===11){
			$uid = $this->_getUid($mobile);
		}
		else {
			$uid=$mobile;
		}
		return $uid === '' ? $this->_addFriend($mobile) : $this->_toUid($uid, $message);
		
	}
	
	protected function _getname() {
		$uri = '/im/index/index.action';
		
		$result = $this->_postWithCookie($uri, '#');
		
		// 匹配
		preg_match('/<a href="\/im\/index\/index.action\?t=(.*?)">(.*?)<\/a>/si', $result, $matches);
		
		return $matches[2];
	}
	
	
	/*
 	 * 通过手机号增加好友
 	 * @param string $number 手机号(要加的好友手机)
 	 * @param string $nickname 你的名字,出现在对方的验证短信里
 	 * @param string $buddylist 分组,默认为空
 	 * @param string $localName 好友屏显名
 	 * @return string
 	 */
 	protected function _addFriend($number) {
 		$uri = '/im/user/insertfriendsubmit.action';
 		$data = 'nickname='. urlencode($this->_getname()).'&buddylist=1&localName=&number='. $number .'&type=0';
 		$result = $this->_postWithCookie($uri, $data);
 		return $result;
 	}
 	
	/**
	 * 获取飞信ID
	 * @param string $mobile 手机号
	 * @return string
	 */
	protected function _getUid($mobile)
    {
        if (empty($this->_uids[$mobile]))
        {
            $uri = '/im/index/searchOtherInfoList.action';
            $data = 'searchText='.$mobile;
            
            $result = $this->_postWithCookie($uri, $data);
            
            //匹配
            preg_match('/toinputMsg\.action\?touserid=(\d+)/si', $result, $matches);

            $this->_uids[$mobile] = isset($matches[1]) ? $matches[1] : '';
        }
        
        return $this->_uids[$mobile];
    }
	
	/**
	 * 向好友发送飞信
	 * @param string $uid 飞信ID
	 * @param string $message 短信内容
	 * @return string
	 */
	protected function _toUid($uid, $message) {
		$uri = '/im/chat/sendMsg.action?touserid='.$uid;
                $csrfToken = $this->_getCsrfToken($uid);
                $data = 'msg='.urlencode($message).'&csrfToken='.$csrfToken;
		$result = $this->_postWithCookie($uri, $data);
		return $result;
	}
	
	/**
	 * 给自己发飞信
	 * @param string $message
	 * @return string
	 */
	protected function _toMyself($message) {
		$uri = '/im/user/sendMsgToMyselfs.action';
		$result = $this->_postWithCookie($uri, 'msg='.urlencode($message));
		
		return $result;
	}
	
	/**
	 * 退出飞信
	 * @return string
	 */
	protected function _logout() {
		$uri = '/im/index/logoutsubmit.action';
		$result = $this->_postWithCookie($uri, '');
		
		return $result;
	}
	
	protected function getgroup() {
		$uri = '/im/index/index.action';
		$data = 'type=group';
		
		$result = $this->_postWithCookie($uri, $data);
		
		// 匹配
		preg_match_all('/contactlistView\.action\?idContactList=(\d+)/si', $result, $matches);
		foreach($matches[1] as $k=>$v){
   			if( $k== 0 ){
      				$min = $v;
      				$max = $v;
   			}else if($v!=9998&&$v!=9999){
      				$min = min($min,$v);
      				$max = max($max,$v);
   			}
		}
		return $max;
	}
	
	public function getyou1() {
		$list=$this->getgroup();
		for($i=0;$i<=$list;$i++){
			$uri = '/im/index/contactlistView.action';
			$data = 'idContactList='.$i.'&type=group';
			$result = $this->_postWithCookie($uri, $data);
			preg_match('/<br\/>(.*?)\|(.*?)\((.*?)\/(.*?)\)<br\/>/si', $result, $listn);
			if(!$listn[2]){continue;}
			$shuchu.=str_replace(" ","",$listn[2])."(".$listn[4].")\n";
			preg_match('/共(\d+)页/si', $result, $zpage);
			preg_match('/共<a href="\/im\/index\/contactlistView\.action\?idContactList=(\d+)\&amp;page=(\d+)\&amp;t=(\d+)" class="c_ash" >(\d+)<\/a>页/si', $result, $dpage);
			isset($zpage[1]) ? $page=$zpage[1] : $page=$dpage[4];
			for($j=1;$j<=$page;$j++){
				$uri = '/im/index/contactlistView.action';
				$data = 'idContactList='.$i.'&page='.$j;
				$result = $this->_postWithCookie($uri, $data);
				preg_match_all('/<a href="\/im\/chat\/toinputMsg\.action\?touserid=(.*?)\&amp;(.*?)">(.*?)<\/a>/si', $result, $matches);
				if(!$matches[1][0]){break;}
				for($x=0;$x<=9;$x++){
					if(!$matches[1][$x]){continue;}
					$shuchu.=$matches[1][$x]." ".str_replace(" ","",$matches[3][$x])."\n";
				}
			 }
		
		}
		return $shuchu; 
	}
	
	public function getyou() {
		$list=$this->getgroup();
		for($i=0;$i<=$list;$i++){
			$uri = '/im/index/contactlistView.action';
			$data = 'idContactList='.$i.'&type=group';
			$result = $this->_postWithCookie($uri, $data);
			preg_match('/<br\/>(.*?)\|(.*?)\((.*?)\/(.*?)\)<br\/>/si', $result, $listn);
			if(!$listn[2]){continue;}
			$shuchu.=str_replace(" ","",$listn[2])."(".$listn[4].")\n";
			preg_match('/共(\d+)页/si', $result, $zpage);
			preg_match('/共<a href="\/im\/index\/contactlistView\.action\?idContactList=(\d+)\&amp;page=(\d+)\&amp;t=(\d+)" class="c_ash" >(\d+)<\/a>页/si', $result, $dpage);
			isset($zpage[1]) ? $page=$zpage[1] : $page=$dpage[4];
			for($j=1;$j<=$page;$j++){
				$uri = '/im/index/contactlistView.action';
				$data = 'idContactList='.$i.'&page='.$j;
				$result = $this->_postWithCookie($uri, $data);
				preg_match_all('/<a href="\/im\/chat\/toinputMsg\.action\?touserid=(.*?)\&amp;(.*?)">(.*?)<\/a>/si', $result, $matches);
				if(!$matches[1][0]){break;}
				for($x=0;$x<=9;$x++){
					if(!$matches[1][$x]){continue;}
					$shuchu.=$matches[1][$x]." ".str_replace(" ","",$matches[3][$x])."\n";
				}
			 }
		
		}
		return $shuchu; 
	}
	
	
	/**
	 * 携带Cookie向f.10086.cn发送POST请求
	 * @param string $uri
	 * @param string $data
	 */
	protected function _postWithCookie($uri, $data)
    {
        $fp = fsockopen('f.10086.cn', 80);
        fputs($fp, "POST $uri HTTP/1.1\r\n");
        fputs($fp, "Host: f.10086.cn\r\n");
        fputs($fp, "Cookie: {$this->_cookie}\r\n");
        fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
        fputs($fp, "User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1\r\n");
        fputs($fp, "Content-Length: ".strlen($data)."\r\n");
        fputs($fp, "Connection: close\r\n\r\n");
        fputs($fp, $data);

        $result = '';
        while (!feof($fp))
        {
            $result .= fgets($fp);
        }

        fclose($fp);

        return $result;
    }
}



免费获得每月10G空间+10G免费流量
  • Comment (3)
  • Trackback (0)
  • 某人 Google Chrome Windows 2014/10/26 22:14 @Ta

    谢谢博主,这个留着以后有用

    #25
  • 孙继祖 Safari  Android 4.2.2 H30-T00 Build/HuaweiH30-T00 2014/07/11 00:40 @Ta

    专程来点赞,博客做的好用心!

    #24
  • Ryu Google Chrome Windows 2014/04/18 16:36 @Ta

    很厉害,谢谢博主,这个留着以后有用

    #23
  • 还没有Trackback
Leave a Reply

*

*