Cool-Y.github.io/2019/03/23/auto-send-WX/index.html
2019-03-28 15:55:23 +08:00

1425 lines
50 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html class="theme-next gemini use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.8.0">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">
<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">
<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">
<link rel="apple-touch-icon" sizes="180x180" href="/images/hackerrank.png?v=5.1.4">
<link rel="icon" type="image/png" sizes="32x32" href="/images/hackerrank.png?v=5.1.4">
<link rel="icon" type="image/png" sizes="16x16" href="/images/hackerrank.png?v=5.1.4">
<link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">
<meta name="keywords" content="itchat,微信,">
<meta name="description" content="我们实验室有个光荣传统每天早上起床叫醒我的不是闹钟而是群里雷打不动的安全新闻其实我免提醒了2333而这个发送新闻的人一代一代的传承我没想到竟然有一天会落在我头上哭了o(╥﹏╥)o为了不暴露我的起床时间同时能保质保量的完成任务我决定做个机器人帮我完成。这就是这片po文的由来啦 大杀器itchatintroduction先来一段itchat的官方介绍吧 itchat是一个开源的微">
<meta name="keywords" content="itchat,微信">
<meta property="og:type" content="article">
<meta property="og:title" content="利用itchat定时转发微信消息">
<meta property="og:url" content="https://cool-y.github.io/2019/03/23/auto-send-WX/index.html">
<meta property="og:site_name" content="混元霹雳手">
<meta property="og:description" content="我们实验室有个光荣传统每天早上起床叫醒我的不是闹钟而是群里雷打不动的安全新闻其实我免提醒了2333而这个发送新闻的人一代一代的传承我没想到竟然有一天会落在我头上哭了o(╥﹏╥)o为了不暴露我的起床时间同时能保质保量的完成任务我决定做个机器人帮我完成。这就是这片po文的由来啦 大杀器itchatintroduction先来一段itchat的官方介绍吧 itchat是一个开源的微">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2019-03-23T13:44:58.402Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="利用itchat定时转发微信消息">
<meta name="twitter:description" content="我们实验室有个光荣传统每天早上起床叫醒我的不是闹钟而是群里雷打不动的安全新闻其实我免提醒了2333而这个发送新闻的人一代一代的传承我没想到竟然有一天会落在我头上哭了o(╥﹏╥)o为了不暴露我的起床时间同时能保质保量的完成任务我决定做个机器人帮我完成。这就是这片po文的由来啦 大杀器itchatintroduction先来一段itchat的官方介绍吧 itchat是一个开源的微">
<script type="text/javascript" id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Gemini',
version: '5.1.4',
sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<link rel="canonical" href="https://cool-y.github.io/2019/03/23/auto-send-WX/">
<title>利用itchat定时转发微信消息 | 混元霹雳手</title>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div class="container sidebar-position-left page-post-detail">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-wrapper">
<div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">混元霹雳手</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle"></p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br>
首页
</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about/" rel="section">
<i class="menu-item-icon fa fa-fw fa-user"></i> <br>
关于
</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section">
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
标签
</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section">
<i class="menu-item-icon fa fa-fw fa-th"></i> <br>
分类
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
归档
</a>
</li>
<li class="menu-item menu-item-bookmarks">
<a href="/bookmarks/" rel="section">
<i class="menu-item-icon fa fa-fw fa-map"></i> <br>
书签
</a>
</li>
<li class="menu-item menu-item-search">
<a href="javascript:;" class="popup-trigger">
<i class="menu-item-icon fa fa-search fa-fw"></i> <br>
搜索
</a>
</li>
</ul>
<div class="site-search">
<div class="popup search-popup local-search-popup">
<div class="local-search-header clearfix">
<span class="search-icon">
<i class="fa fa-search"></i>
</span>
<span class="popup-btn-close">
<i class="fa fa-times-circle"></i>
</span>
<div class="local-search-input-wrapper">
<input autocomplete="off" placeholder="搜索..." spellcheck="false" type="text" id="local-search-input">
</div>
</div>
<div id="local-search-result"></div>
</div>
</div>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<div id="posts" class="posts-expand">
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="https://cool-y.github.io/2019/03/23/auto-send-WX/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Cool-Y">
<meta itemprop="description" content>
<meta itemprop="image" content="/images/avatar.png">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="混元霹雳手">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">利用itchat定时转发微信消息</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2019-03-23T19:48:46+08:00">
2019-03-23
</time>
</span>
<span class="post-category">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/杂七杂八/" itemprop="url" rel="index">
<span itemprop="name">杂七杂八</span>
</a>
</span>
</span>
<span class="post-comments-count">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-comment-o"></i>
</span>
<a href="/2019/03/23/auto-send-WX/#comments" itemprop="discussionUrl">
<span class="post-comments-count gitment-comments-count" data-xid="/2019/03/23/auto-send-WX/" itemprop="commentsCount"></span>
</a>
</span>
<span id="/2019/03/23/auto-send-WX/" class="leancloud_visitors" data-flag-title="利用itchat定时转发微信消息">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-eye"></i>
</span>
<span class="post-meta-item-text">阅读次数&#58;</span>
<span class="leancloud-visitors-count"></span>
</span>
<div class="post-wordcount">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span title="字数统计">
989 字
</span>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span title="阅读时长">
4 分钟
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>我们实验室有个光荣传统每天早上起床叫醒我的不是闹钟而是群里雷打不动的安全新闻其实我免提醒了2333<br>而这个发送新闻的人一代一代的传承我没想到竟然有一天会落在我头上哭了o(╥﹏╥)o<br>为了不暴露我的起床时间,同时能保质保量的完成任务,我决定做个机器人帮我完成。<br>这就是这片po文的由来啦</p>
<h1 id="大杀器itchat"><a href="#大杀器itchat" class="headerlink" title="大杀器itchat"></a>大杀器itchat</h1><h2 id="introduction"><a href="#introduction" class="headerlink" title="introduction"></a>introduction</h2><p>先来一段<a href="https://itchat.readthedocs.io/zh/latest/" target="_blank" rel="noopener">itchat</a>的官方介绍吧</p>
<blockquote>
<p>itchat是一个开源的微信个人号接口使用python调用微信从未如此简单。<br>使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人。<br>当然该api的使用远不止一个机器人更多的功能等着你来发现比如这些。<br>该接口与公众号接口itchatmp共享类似的操作方式学习一次掌握两个工具。<br>如今微信已经成为了个人社交的很大一部分,希望这个项目能够帮助你扩展你的个人的微信号、方便自己的生活。</p>
</blockquote>
<p>实际上itchat是对微信网页端的爬虫所以网页端可以实现的功能都有那么我想要的定时群发微信消息自然不在话下</p>
<h2 id="初步尝试"><a href="#初步尝试" class="headerlink" title="初步尝试"></a>初步尝试</h2><ul>
<li><p>安装</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install itchat</span><br></pre></td></tr></table></figure>
</li>
<li><p>一个简单实例:实现给文件传输助手发送消息</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">import itchat</span><br><span class="line">itchat.auto_login()</span><br><span class="line">itchat.send(&apos;Hello, filehelper&apos;, toUserName=&apos;filehelper&apos;)</span><br></pre></td></tr></table></figure>
<h1 id="实现定时转发"><a href="#实现定时转发" class="headerlink" title="实现定时转发"></a>实现定时转发</h1><p>这个的实现需要注册msg_register,逻辑很简单,当收到指定群里的指定消息时,将消息转发到另一个群。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">import itchat</span><br><span class="line">from datetime import datetime</span><br><span class="line">import time</span><br><span class="line">import re</span><br><span class="line">import threading</span><br><span class="line">from itchat.content import TEXT</span><br><span class="line">from itchat.content import *</span><br><span class="line">from apscheduler.schedulers.blocking import BlockingScheduler</span><br><span class="line"></span><br><span class="line">@itchat.msg_register([TEXT], isFriendChat=True, isGroupChat=True, isMpChat=True)</span><br><span class="line">def getContent(msg):</span><br><span class="line"> global g_msg</span><br><span class="line"> groups = itchat.get_chatrooms(update = True)</span><br><span class="line"> for g in groups:</span><br><span class="line"> #print(g[&apos;NickName&apos;])</span><br><span class="line"> if g[&apos;NickName&apos;] == &apos;被转发的群名&apos;:</span><br><span class="line"> from_group = g[&apos;UserName&apos;]</span><br><span class="line"> if &apos;每日安全简讯&apos; in msg[&apos;Content&apos;]:</span><br><span class="line"> print(&quot;get message from &quot; + msg[&apos;FromUserName&apos;])</span><br><span class="line"> if msg[&apos;FromUserName&apos;] == from_group:</span><br><span class="line"> g_msg = msg[&apos;Content&apos;]</span><br><span class="line"> print(&apos;成功获得群消息,等待转发&apos;)</span><br><span class="line"> print(int(time.strftime(&quot;%H%M%S&quot;)))</span><br><span class="line"> while(1):</span><br><span class="line"> if int(time.strftime(&quot;%H%M%S&quot;)) &gt; 80000:</span><br><span class="line"> SendMessage(g_msg,&apos;发送的对象群名&apos;)</span><br><span class="line"> g_msg = &apos;&apos;</span><br><span class="line"> break</span><br><span class="line"></span><br><span class="line">def SendMessage(context,gname):</span><br><span class="line"> itchat.get_chatrooms(update = True)</span><br><span class="line"> users = itchat.search_chatrooms(name=gname)</span><br><span class="line"> userName = users[0][&apos;UserName&apos;]</span><br><span class="line"> itchat.send_msg(context,toUserName=userName)</span><br><span class="line"> print(&quot;\n发送时间: &quot; + datetime.now().strftime(&quot;%Y-%m-%d %H:%M:%S&quot;) + &quot;\n&quot; &quot;发送到:&quot; + gname + &quot;\n&quot; + &quot;发送内容:&quot; + context + &quot;\n&quot;)</span><br><span class="line"> print(&quot;*********************************************************************************&quot;)</span><br><span class="line"></span><br><span class="line">if __name__ == &apos;__main__&apos;:</span><br><span class="line"> itchat.auto_login(hotReload=True,enableCmdQR=2)</span><br><span class="line"> itchat.run(blockThread=False)</span><br></pre></td></tr></table></figure></p>
<h1 id="添加周期防掉线"><a href="#添加周期防掉线" class="headerlink" title="添加周期防掉线"></a>添加周期防掉线</h1><p>据说每三十分钟发送一次消息可防止网页端微信掉线~~<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">def loop_send():</span><br><span class="line"> nowTime = datetime.now().strftime(&quot;%Y-%m-%d %H:%M:%S&quot;)</span><br><span class="line"> context = &apos;现在是北京时间 :\n&apos;+ nowTime +&apos;\n\n我们还活着&apos;</span><br><span class="line"> itchat.get_chatrooms(update = True)</span><br><span class="line"> users = itchat.search_friends(name=u&apos;chengkun&apos;)</span><br><span class="line"> userName = users[0][&apos;UserName&apos;]</span><br><span class="line"> itchat.send_msg(context,toUserName=userName)</span><br><span class="line"></span><br><span class="line">if __name__ == &apos;__main__&apos;:</span><br><span class="line"> sched = BlockingScheduler()</span><br><span class="line"> sched.add_job(loop_send,&apos;interval&apos;,minutes=30)</span><br><span class="line"> sched.start()</span><br></pre></td></tr></table></figure></p>
<h1 id="把程序放在服务器上"><a href="#把程序放在服务器上" class="headerlink" title="把程序放在服务器上"></a>把程序放在服务器上</h1><p>我是在腾讯云有个服务器,因为自己的电脑不可能时时刻刻开机,所以就放在服务器上,方法是:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo nohup python -u auto_Send.py &gt;&gt; auto_Send.log 2&gt;&amp;1 &amp;</span><br></pre></td></tr></table></figure></p>
<ul>
<li>使用nohup可以让程序在后台运行</li>
<li>然后将日志输出到auto_Send.log方便我们后期出bug了排错</li>
<li>-u可以防止输出到python缓冲区</li>
</ul>
<h1 id="遇到的坑"><a href="#遇到的坑" class="headerlink" title="遇到的坑"></a>遇到的坑</h1><h2 id="线程阻塞问题"><a href="#线程阻塞问题" class="headerlink" title="线程阻塞问题"></a>线程阻塞问题</h2><p>这里有两个线程一个是定时转发一个是循环发送因此要设置为itchat.run(blockThread=False)以及sched = BlockingScheduler()否则会卡在某个方法。</p>
<h2 id="找不到群组"><a href="#找不到群组" class="headerlink" title="找不到群组"></a>找不到群组</h2><p>这是因为users = itchat.search_chatrooms(name=gname),在搜索的是你保存到通讯录的群组。</p>
<h2 id="二维码显示不全"><a href="#二维码显示不全" class="headerlink" title="二维码显示不全"></a>二维码显示不全</h2><p>itchat.auto_login(hotReload=True,enableCmdQR=2)需要设置为2</p>
</div>
<div>
<div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
<div>您的支持将鼓励我继续创作!</div>
<button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
<span>打赏</span>
</button>
<div id="QR" style="display: none;">
<div id="wechat" style="display: inline-block">
<img id="wechat_qr" src="/images/Wechatpay.png" alt="Cool-Y 微信支付">
<p>微信支付</p>
</div>
<div id="alipay" style="display: inline-block">
<img id="alipay_qr" src="/images/Alipay.png" alt="Cool-Y 支付宝">
<p>支付宝</p>
</div>
</div>
</div>
</div>
<footer class="post-footer">
<div class="post-tags">
<a href="/tags/itchat/" rel="tag"># itchat</a>
<a href="/tags/微信/" rel="tag"># 微信</a>
</div>
<div class="post-nav">
<div class="post-nav-next post-nav-item">
<a href="/2019/03/16/小米固件工具mkxqimage/" rel="next" title="小米固件工具mkxqimage">
<i class="fa fa-chevron-left"></i> 小米固件工具mkxqimage
</a>
</div>
<span class="post-nav-divider"></span>
<div class="post-nav-prev post-nav-item">
<a href="/2019/03/25/Samba-CVE/" rel="prev" title="小米路由器与Samba漏洞CVE-2017-7494">
小米路由器与Samba漏洞CVE-2017-7494 <i class="fa fa-chevron-right"></i>
</a>
</div>
</div>
</footer>
</div>
</article>
<div class="post-spread">
</div>
</div>
</div>
<div class="comments" id="comments">
<div id="gitment-container"></div>
</div>
</div>
<div class="sidebar-toggle">
<div class="sidebar-toggle-line-wrap">
<span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
<span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
<span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
</div>
</div>
<aside id="sidebar" class="sidebar">
<div class="sidebar-inner">
<ul class="sidebar-nav motion-element">
<li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
文章目录
</li>
<li class="sidebar-nav-overview" data-target="site-overview-wrap">
站点概览
</li>
</ul>
<section class="site-overview-wrap sidebar-panel">
<div class="site-overview">
<div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
<img class="site-author-image" itemprop="image" src="/images/avatar.png" alt="Cool-Y">
<p class="site-author-name" itemprop="name">Cool-Y</p>
<p class="site-description motion-element" itemprop="description"></p>
</div>
<nav class="site-state motion-element">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">11</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/index.html">
<span class="site-state-item-count">7</span>
<span class="site-state-item-name">分类</span>
</a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/index.html">
<span class="site-state-item-count">25</span>
<span class="site-state-item-name">标签</span>
</a>
</div>
</nav>
<div class="links-of-author motion-element">
<span class="links-of-author-item">
<a href="https://github.com/Cool-Y" target="_blank" title="GitHub">
<i class="fa fa-fw fa-github"></i>GitHub</a>
</span>
<span class="links-of-author-item">
<a href="http://weibo.com/HanYanOpenFire" target="_blank" title="Weibo">
<i class="fa fa-fw fa-weibo"></i>Weibo</a>
</span>
<span class="links-of-author-item">
<a href="mailto:cool.yim@whu.edu.cn" target="_blank" title="E-Mail">
<i class="fa fa-fw fa-envelope"></i>E-Mail</a>
</span>
<span class="links-of-author-item">
<a href="https://www.instagram.com/yan__han/" target="_blank" title="Instagram">
<i class="fa fa-fw fa-instagram"></i>Instagram</a>
</span>
</div>
</div>
</section>
<!--noindex-->
<section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
<div class="post-toc">
<div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#大杀器itchat"><span class="nav-number">1.</span> <span class="nav-text">大杀器itchat</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#introduction"><span class="nav-number">1.1.</span> <span class="nav-text">introduction</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#初步尝试"><span class="nav-number">1.2.</span> <span class="nav-text">初步尝试</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#实现定时转发"><span class="nav-number">2.</span> <span class="nav-text">实现定时转发</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#添加周期防掉线"><span class="nav-number">3.</span> <span class="nav-text">添加周期防掉线</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#把程序放在服务器上"><span class="nav-number">4.</span> <span class="nav-text">把程序放在服务器上</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#遇到的坑"><span class="nav-number">5.</span> <span class="nav-text">遇到的坑</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#线程阻塞问题"><span class="nav-number">5.1.</span> <span class="nav-text">线程阻塞问题</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#找不到群组"><span class="nav-number">5.2.</span> <span class="nav-text">找不到群组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#二维码显示不全"><span class="nav-number">5.3.</span> <span class="nav-text">二维码显示不全</span></a></li></ol></li></ol></div>
</div>
</section>
<!--/noindex-->
</div>
</aside>
</div>
</main>
<footer id="footer" class="footer">
<div class="footer-inner">
<div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
<span class="with-love">
<i class="fa fa-user"></i>
</span>
<span class="author" itemprop="copyrightHolder">Cool-Y</span>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-area-chart"></i>
</span>
<span title="Site words total count">14.9k</span>
</div>
<div class="powered-by"><a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>
<div class="busuanzi-count">
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<span class="site-uv">
<i class="fa fa-user"></i>
<span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
</span>
<span class="site-pv">
<i class="fa fa-eye"></i>
<span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
</span>
</div>
</div>
</footer>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
</div>
</div>
<script type="text/javascript">
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
window.Promise = null;
}
</script>
<script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
<script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
<script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
<script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
<script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
<script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
<script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>
<!-- LOCAL: You can save these files to your site and update links -->
<link rel="stylesheet" href="https://aimingoo.github.io/gitmint/style/default.css">
<script src="https://aimingoo.github.io/gitmint/dist/gitmint.browser.js"></script>
<!-- END LOCAL -->
<script type="text/javascript">
function renderGitment(){
var gitment = new Gitmint({
id: window.location.pathname,
owner: 'Cool-Y',
repo: 'gitment-comments',
lang: "" || navigator.language || navigator.systemLanguage || navigator.userLanguage,
oauth: {
client_secret: '1c5db4da72df5e6fc318d12afe5f4406f7c54343',
client_id: '180955a2c3ae3d966d9a'
}});
gitment.render('gitment-container');
}
renderGitment();
</script>
<script type="text/javascript">
// Popup Window;
var isfetched = false;
var isXml = true;
// Search DB path;
var search_path = "search.xml";
if (search_path.length === 0) {
search_path = "search.xml";
} else if (/json$/i.test(search_path)) {
isXml = false;
}
var path = "/" + search_path;
// monitor main search box;
var onPopupClose = function (e) {
$('.popup').hide();
$('#local-search-input').val('');
$('.search-result-list').remove();
$('#no-result').remove();
$(".local-search-pop-overlay").remove();
$('body').css('overflow', '');
}
function proceedsearch() {
$("body")
.append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
.css('overflow', 'hidden');
$('.search-popup-overlay').click(onPopupClose);
$('.popup').toggle();
var $localSearchInput = $('#local-search-input');
$localSearchInput.attr("autocapitalize", "none");
$localSearchInput.attr("autocorrect", "off");
$localSearchInput.focus();
}
// search function;
var searchFunc = function(path, search_id, content_id) {
'use strict';
// start loading animation
$("body")
.append('<div class="search-popup-overlay local-search-pop-overlay">' +
'<div id="search-loading-icon">' +
'<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
'</div>' +
'</div>')
.css('overflow', 'hidden');
$("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');
$.ajax({
url: path,
dataType: isXml ? "xml" : "json",
async: true,
success: function(res) {
// get the contents from search data
isfetched = true;
$('.popup').detach().appendTo('.header-inner');
var datas = isXml ? $("entry", res).map(function() {
return {
title: $("title", this).text(),
content: $("content",this).text(),
url: $("url" , this).text()
};
}).get() : res;
var input = document.getElementById(search_id);
var resultContent = document.getElementById(content_id);
var inputEventFunction = function() {
var searchText = input.value.trim().toLowerCase();
var keywords = searchText.split(/[\s\-]+/);
if (keywords.length > 1) {
keywords.push(searchText);
}
var resultItems = [];
if (searchText.length > 0) {
// perform local searching
datas.forEach(function(data) {
var isMatch = false;
var hitCount = 0;
var searchTextCount = 0;
var title = data.title.trim();
var titleInLowerCase = title.toLowerCase();
var content = data.content.trim().replace(/<[^>]+>/g,"");
var contentInLowerCase = content.toLowerCase();
var articleUrl = decodeURIComponent(data.url);
var indexOfTitle = [];
var indexOfContent = [];
// only match articles with not empty titles
if(title != '') {
keywords.forEach(function(keyword) {
function getIndexByWord(word, text, caseSensitive) {
var wordLen = word.length;
if (wordLen === 0) {
return [];
}
var startPosition = 0, position = [], index = [];
if (!caseSensitive) {
text = text.toLowerCase();
word = word.toLowerCase();
}
while ((position = text.indexOf(word, startPosition)) > -1) {
index.push({position: position, word: word});
startPosition = position + wordLen;
}
return index;
}
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
});
if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
isMatch = true;
hitCount = indexOfTitle.length + indexOfContent.length;
}
}
// show search results
if (isMatch) {
// sort index by position of keyword
[indexOfTitle, indexOfContent].forEach(function (index) {
index.sort(function (itemLeft, itemRight) {
if (itemRight.position !== itemLeft.position) {
return itemRight.position - itemLeft.position;
} else {
return itemLeft.word.length - itemRight.word.length;
}
});
});
// merge hits into slices
function mergeIntoSlice(text, start, end, index) {
var item = index[index.length - 1];
var position = item.position;
var word = item.word;
var hits = [];
var searchTextCountInSlice = 0;
while (position + word.length <= end && index.length != 0) {
if (word === searchText) {
searchTextCountInSlice++;
}
hits.push({position: position, length: word.length});
var wordEnd = position + word.length;
// move to next position of hit
index.pop();
while (index.length != 0) {
item = index[index.length - 1];
position = item.position;
word = item.word;
if (wordEnd > position) {
index.pop();
} else {
break;
}
}
}
searchTextCount += searchTextCountInSlice;
return {
hits: hits,
start: start,
end: end,
searchTextCount: searchTextCountInSlice
};
}
var slicesOfTitle = [];
if (indexOfTitle.length != 0) {
slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
}
var slicesOfContent = [];
while (indexOfContent.length != 0) {
var item = indexOfContent[indexOfContent.length - 1];
var position = item.position;
var word = item.word;
// cut out 100 characters
var start = position - 20;
var end = position + 80;
if(start < 0){
start = 0;
}
if (end < position + word.length) {
end = position + word.length;
}
if(end > content.length){
end = content.length;
}
slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
}
// sort slices in content by search text's count and hits' count
slicesOfContent.sort(function (sliceLeft, sliceRight) {
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
return sliceRight.hits.length - sliceLeft.hits.length;
} else {
return sliceLeft.start - sliceRight.start;
}
});
// select top N slices in content
var upperBound = parseInt('1');
if (upperBound >= 0) {
slicesOfContent = slicesOfContent.slice(0, upperBound);
}
// highlight title and content
function highlightKeyword(text, slice) {
var result = '';
var prevEnd = slice.start;
slice.hits.forEach(function (hit) {
result += text.substring(prevEnd, hit.position);
var end = hit.position + hit.length;
result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
prevEnd = end;
});
result += text.substring(prevEnd, slice.end);
return result;
}
var resultItem = '';
if (slicesOfTitle.length != 0) {
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
} else {
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
}
slicesOfContent.forEach(function (slice) {
resultItem += "<a href='" + articleUrl + "'>" +
"<p class=\"search-result\">" + highlightKeyword(content, slice) +
"...</p>" + "</a>";
});
resultItem += "</li>";
resultItems.push({
item: resultItem,
searchTextCount: searchTextCount,
hitCount: hitCount,
id: resultItems.length
});
}
})
};
if (keywords.length === 1 && keywords[0] === "") {
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
} else if (resultItems.length === 0) {
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
} else {
resultItems.sort(function (resultLeft, resultRight) {
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
return resultRight.searchTextCount - resultLeft.searchTextCount;
} else if (resultLeft.hitCount !== resultRight.hitCount) {
return resultRight.hitCount - resultLeft.hitCount;
} else {
return resultRight.id - resultLeft.id;
}
});
var searchResultList = '<ul class=\"search-result-list\">';
resultItems.forEach(function (result) {
searchResultList += result.item;
})
searchResultList += "</ul>";
resultContent.innerHTML = searchResultList;
}
}
if ('auto' === 'auto') {
input.addEventListener('input', inputEventFunction);
} else {
$('.search-icon').click(inputEventFunction);
input.addEventListener('keypress', function (event) {
if (event.keyCode === 13) {
inputEventFunction();
}
});
}
// remove loading animation
$(".local-search-pop-overlay").remove();
$('body').css('overflow', '');
proceedsearch();
}
});
}
// handle and trigger popup window;
$('.popup-trigger').click(function(e) {
e.stopPropagation();
if (isfetched === false) {
searchFunc(path, 'local-search-input', 'local-search-result');
} else {
proceedsearch();
};
});
$('.popup-btn-close').click(onPopupClose);
$('.popup').click(function(e){
e.stopPropagation();
});
$(document).on('keyup', function (event) {
var shouldDismissSearchPopup = event.which === 27 &&
$('.search-popup').is(':visible');
if (shouldDismissSearchPopup) {
onPopupClose();
}
});
</script>
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
<script>AV.initialize("EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz", "x8FxDrYG79C8YFrTww9ljo8K");</script>
<script>
function showTime(Counter) {
var query = new AV.Query(Counter);
var entries = [];
var $visitors = $(".leancloud_visitors");
$visitors.each(function () {
entries.push( $(this).attr("id").trim() );
});
query.containedIn('url', entries);
query.find()
.done(function (results) {
var COUNT_CONTAINER_REF = '.leancloud-visitors-count';
if (results.length === 0) {
$visitors.find(COUNT_CONTAINER_REF).text(0);
return;
}
for (var i = 0; i < results.length; i++) {
var item = results[i];
var url = item.get('url');
var time = item.get('time');
var element = document.getElementById(url);
$(element).find(COUNT_CONTAINER_REF).text(time);
}
for(var i = 0; i < entries.length; i++) {
var url = entries[i];
var element = document.getElementById(url);
var countSpan = $(element).find(COUNT_CONTAINER_REF);
if( countSpan.text() == '') {
countSpan.text(0);
}
}
})
.fail(function (object, error) {
console.log("Error: " + error.code + " " + error.message);
});
}
function addCount(Counter) {
var $visitors = $(".leancloud_visitors");
var url = $visitors.attr('id').trim();
var title = $visitors.attr('data-flag-title').trim();
var query = new AV.Query(Counter);
query.equalTo("url", url);
query.find({
success: function(results) {
if (results.length > 0) {
var counter = results[0];
counter.fetchWhenSave(true);
counter.increment("time");
counter.save(null, {
success: function(counter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(counter.get('time'));
},
error: function(counter, error) {
console.log('Failed to save Visitor num, with error message: ' + error.message);
}
});
} else {
var newcounter = new Counter();
/* Set ACL */
var acl = new AV.ACL();
acl.setPublicReadAccess(true);
acl.setPublicWriteAccess(true);
newcounter.setACL(acl);
/* End Set ACL */
newcounter.set("title", title);
newcounter.set("url", url);
newcounter.set("time", 1);
newcounter.save(null, {
success: function(newcounter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(newcounter.get('time'));
},
error: function(newcounter, error) {
console.log('Failed to create');
}
});
}
},
error: function(error) {
console.log('Error:' + error.code + " " + error.message);
}
});
}
$(function() {
var Counter = AV.Object.extend("Counter");
if ($('.leancloud_visitors').length == 1) {
addCount(Counter);
} else if ($('.post-title-link').length > 1) {
showTime(Counter);
}
});
</script>
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
</body>
</html>