ClassScheduleWeChatPushServer

更新于10-8

Posted by zhangzexin on September 19, 2018

0x00 项目地址

Github

  • 效果图 效果图

    0x01 PythonPusheServer

忽略明文密码,小可爱别搞我。 系部的一个公众号,消息队列开到了2w应该够了。 轮训-查询数据库-构造信息队列-推送.

# -*- coding: utf-8 -*-
from werobot.replies import ImageReply
import werobot, requests, time, queue, threading,datetime
import PIL.Image as Image

testOpenId ='oVxSv5-ZdIShziNrcuiywhP_6GME'
testAppId = 'wxebf2b7d3b6bf3fa2'
testAppSecret = '65b42281fe6648765adaf04b8ed6ad8a'
testTmplId = 'q38dasXxRBGSTNLbtQEz3uXu0txKrsop8JobhQY7_G4'

realAppId = 'wx4f85e8e294be8491'
realAppSecret = '0c415e27d86d2d657c85da34d533e60c' 

PerHour=21
PerMins=30
MysqlIp="119.29.19.114"
MysqlName="root"
MysqlPasswd="ZZx270400."
MysqlTable="classtable"

f = open("out.txt", "a")

robot = werobot.WeRoBot(token='zhangzexin1')
robot.config['HOST'] = '0.0.0.0'
robot.config['PORT'] = 80
robot.config['APP_ID'] = realAppId
robot.config['APP_SECRET'] = realAppSecret
client = robot.client
atokenjson = client.grant_token()
print (atokenjson)
f.write(str(atokenjson))

qstu = queue.Queue(4000)
qall = queue.Queue(10000)
# 返回json

# --- function area ---
cmjson=client.create_menu({
    "button":[
        {
            "name":"在计科",
            "sub_button":[
                {
                    "type": "view", 
                    "name": "计科系官网", 
                    "url":"http://www.hfuu.edu.cn/jsjx/"
                 }, 
                  {
                    "type": "view", 
                    "name": "课程通知", 
                    "url":"http://zzx.keria-youyou.cn/wx_banding"
                 }, 
                 # {
                 #    "type": "media_id", 
                 #    "name": "计科系毕业晚会", 
                 #    "media_id":"wSB_8YM-zaEK8ExRhLeDbDajMZa3FgivLSa7MGAbZ3A"
                 # }, 
                 {
                    "type": "media_id", 
                    "name": "留言板", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbBcedCBQL-Gul1FZnTaCOLs"
                 }]
        },
        {
            "name":"在合院",
            "sub_button":[
                {
                    "type": "media_id", 
                    "name": "校园周边", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbPgM_Z0M6ZY42roS3lym2gk"
                 }, 
                 {
                    "type": "media_id", 
                    "name": "梦想时光机", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbMgAdY0ooaZKrUpaMQGgadM"
                 }, 
                 {
                    "type": "media_id", 
                    "name": "校运会", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbLx7UdZtf6zSXTcLPDxm1uM"
                 }]
        },
        {
            "name":"新生指南",
            "sub_button":[
                {
                    "type": "media_id", 
                    "name": "学生会纳新", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbMhnqdEGiKrEPAopopg8STU"
                 }, 
                 {
                    "type": "media_id", 
                    "name": "计科系公众号一览", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbC6NJl30gQSG5IqCLgmD55w"
                 }, 
                 {
                    "type": "media_id", 
                    "name": "新生报道流程", 
                    "media_id":"wSB_8YM-zaEK8ExRhLeDbIwqUIE-EBOJCVzDNJGBMHY"
                 }]
        }
    ]})

print (cmjson)
f.write(str(cmjson))
# ---获取素材ID---
# bjson=client.get_media_list('news',0,102)
# print (bjson)
# f.write(str(bjson))

templateLong_id = 'a86n8HLGmfny5pE9wS9NWMAYsVeCf0oWoPiM_KVFaTc'
# 
# 课程名:
# 授课教师:
# 地点:
# 时间:
# 
templateShort_id = 'vi3AkOJLbwWWJdZQNQC5MVqJ1cO1RHXTO9yyR_w2CnY'
# 
# 课程:
# 时间:
# 地点:
# 
def MakeDataTomorrow(head,name,stime,etime,place,teacher):
    data={
        "first": {
                "value":"head",
                "color":"#173177"
                },
        "keyword1":{
                "value":"key1",
                "color":"#173177"
                },
        "keyword2": {
                "value":"key2",
                "color":"#173177"
                },
        "keyword3": {
                "value":"key3",
                "color":"#173177"
                },
        "remark":{
                "value":"欢迎再次购买!",
                "color":"#173177"
                }
    }
    data["first"]["value"]="%s"%head
    data["keyword1"]["value"]="%s"%name
    data["remark"]["value"]="授课教师:%s"%teacher
    data["keyword3"]["value"]="%s"%place
    data["keyword2"]["value"]="%s-%s节"%(stime,etime)
    print (data)
    return data

def MakeDataToday(head,name,stime,etime,place,teacher):
    data={
        "first": {
                "value":"head",
                "color":"#173177"
                },
        "keyword1":{
                "value":"key1",
                "color":"#173177"
                },
        "keyword2": {
                "value":"key2",
                "color":"#173177"
                },
        "keyword3": {
                "value":"key3",
                "color":"#173177"
                },
        "remark":{
                "value":"欢迎再次购买!",
                "color":"#173177"
                }
    }
    data["first"]["value"]="%s"%head
    data["keyword1"]["value"]="%s(%s)"%(name,teacher)
    data["remark"]["value"]="即将开始!"
    data["keyword3"]["value"]="%s"%place
    data["keyword2"]["value"]="%s-%s节"%(stime,etime)
    print (data)
    return data

def gettime(cmd):
    import pymysql
    dayone = 1504454400
    eachday = 86400
    eachweek = eachday * 7
    now = int(time.time())
    now -= dayone
    week = int(now/eachweek) + 1
    day = int((now-(week-1)*eachweek)/eachday) + 1
    if (cmd=='day'):
        return day
    elif (cmd=='hour'):
        return int(time.strftime("%H"))
    elif (cmd=='week'):
        return int(time.strftime("%W"))-35
    elif (cmd=='mins'):
        return int(time.strftime("%M"))

def getdbTomorrow(day,week,hour):
    import pymysql
    db = pymysql.connect(MysqlIp,MysqlName,MysqlPasswd,MysqlTable,charset='utf8')
    cursor = db.cursor()
    sql = "select stuClass,stuOpenID from stuUser"
    print (sql,cursor)
    try:
        cursor.execute(sql)
        ret = cursor.fetchall()
        print (ret)
        for row in ret:
            list1 = []
            list1.append(row[0])
            list1.append(row[1])
            qstu.put(list1,timeout=60)
            print (row[0],row[1])
    except:
        print ("database1 error")
    
    nextday = day
    if(day<7):
        nextday = day+1
    if(day==7):
        nextday = 1

    while(qstu.qsize()):
        list1 = []
        list1 = qstu.get()
        stuclass = list1[0]
        openid = list1[1]
        # nextday = 1
        if(nextday==1):
        	week=week+1
        sql2 = "select name,stime,etime,place,teacher from `%s` where week=%d and sweek<=%d and eweek>=%d" %(stuclass,nextday,week,week)
        print (sql2)
        try:
            cursor.execute(sql2)
            ret2 = cursor.fetchall()
            for row in ret2:
                list3 = []
                list3.append(openid)
                list3.append(row[0])
                list3.append(row[1])
                list3.append(row[2])
                list3.append(row[3])
                list3.append(row[4])
                qall.put(list3,timeout=60)
        except:
            print ("database2 error")
    cursor.close()
    db.close()

def getdbToday(day,week,hour):
    import pymysql
    db = pymysql.connect(MysqlIp,MysqlName,MysqlPasswd,MysqlTable,charset='utf8')
    cursor = db.cursor()
    sql = "select stuClass,stuOpenID from stuUser"
    print (sql,cursor)
    try:
        cursor.execute(sql)
        ret = cursor.fetchall()
        print (ret)
        for row in ret:
            list1 = []
            list1.append(row[0])
            list1.append(row[1])
            qstu.put(list1,timeout=60)
            print (row[0],row[1])
    except:
        print ("database1 error")

    while(qstu.qsize()):
        list1 = []
        list1 = qstu.get()
        stuclass = list1[0]
        openid = list1[1]
        sql2 = "select name,stime,etime,place,teacher from `%s` where week=%d and sweek<=%d and eweek>=%d and shour=%d" %(stuclass,day,week,week,hour+1)
        print (sql2)
        try:
            cursor.execute(sql2)
            ret2 = cursor.fetchall()
            for row in ret2:
                list3 = []
                list3.append(openid)
                list3.append(row[0])
                list3.append(row[1])
                list3.append(row[2])
                list3.append(row[3])
                list3.append(row[4])
                qall.put(list3,timeout=60)
        except:
            print ("database2 error")
    cursor.close()
    db.close()

def sendtmpl(cmd):
    while(qall.qsize()):
        list1 = []
        list1 = qall.get()
        openid = list1[0]
        name = list1[1]
        stime = list1[2]
        etime = list1[3]
        place = list1[4]
        teacher = list1[5]
        print (openid,name,stime,etime,place,teacher)
        f.write(str(openid)+str(name)+str(stime)+str(etime)+str(place)+str(teacher)+"\n")
        head=str(datetime.date.today()+datetime.timedelta(days=1))
        if cmd=="Tomorrow":
        	data = MakeDataTomorrow(head,name,stime,etime,place,teacher)
        if cmd=="Today":
        	data = MakeDataToday(str(datetime.date.today()),name,stime,etime,place,teacher)
        try:
        	client.send_template_message(openid,templateShort_id,data,url='')
        except:
        	continue

def onduty():
    while 1:
        day=gettime("day")
        hour=gettime("hour")
        week=gettime("week")
        mins=gettime("mins")
        print (week,day,hour,mins)
        if hour==PerHour and mins==PerMins:
            getdbTomorrow(day,week,hour)
            sendtmpl("Tomorrow")
        if (hour==7 or hour==9 or hour==13 or hour==15 or hour==18) and mins==20:
        	getdbToday(day,week,hour)
        	sendtmpl("Today")
        time.sleep(60)


# 轮训线程
timer = threading.Timer(1,onduty)

@robot.text
def func(message):
        f.write(time.asctime(time.localtime(time.time())) + " - " + message.content + "\n")
        return "不懂"

@robot.image
def nonsense(message):
        return "看不懂"

@robot.subscribe
def subscribe(message):
    return 'Hello My Friend!'


if __name__=='__main__':
    timer.start()
    robot.run()

0x02 前端注册部分

先看逻辑后上代码

菜单点击事件相应地址为:http://xx.com/wx_banding 注册openid部分本来先用ajax、vue、node.js来完成,但是做不了,最后还是最基础的servlet了。XD 请设置自己的appid、密钥和跳转地址,自行下载fastjson-1.1.24.jar

servlet wx_banding

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = "/wx_banding")
public class Jumping extends HttpServlet{
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=url&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect");
    }

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException {

    }
}

oauth.jsp

<body>
<%

    String code = null;
    try {
        code = request.getParameter("code");
    } catch (Exception e) {
        response.sendRedirect("http://url/wx_banding");
    }
%>
<%--<%=code%>--%>
<script type="text/javascript">
    window.location.href = "oauthLoading?code=<%=code%>"
</script>
</body>

servlet oauthLoading

import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.net.*;
import com.alibaba.fastjson.*;

import static com.alibaba.fastjson.JSON.parseObject;

@WebServlet(name = "/oauthLoading")
public class Loading extends HttpServlet {
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException,
            MalformedURLException, IOException {

        String code = request.getParameter("code");
        StringBuilder json = new StringBuilder();
        String url = null;
        BufferedReader in = null;
        String inputLine = null;
        String json1 = null;
        //这里的appid与secret换成你自己的secret
        url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=appid&secret=sss&code="
                + code + "&grant_type=authorization_code";
        in = new BufferedReader(new InputStreamReader(new URL(url)
                .openConnection().getInputStream(), "utf-8"));
        while ((inputLine = in.readLine()) != null) {
            json.append(inputLine);
        }
        in.close();
        switch (json1 = json.toString()) {
        }
        JSONObject jobject = JSONObject.parseObject(json1);
        json = new StringBuilder();

        url = "https://api.weixin.qq.com/sns/userinfo?access_token="
                + jobject.getString("access_token") + "&openid="
                + jobject.getString("openid");
        in = new BufferedReader(new InputStreamReader(new URL(url)
                .openConnection().getInputStream(), "utf-8"));
        inputLine = null;
        while ((inputLine = in.readLine()) != null) {
            json.append(inputLine);
        }
        in.close();

        json1 = json.toString();
        jobject = parseObject(json1);
        request.setAttribute("jobject", jobject);
//        String openid = jobject.getString("openid");

        try {
            request.getRequestDispatcher("index.jsp").forward(request,
                    response);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException {

    }
}

index.jsp(openid存到存到session中)

<%
    JSONObject jobject=(JSONObject)request.getAttribute("jobject");
    String openid = jobject.getString("openid");
    session.setAttribute("openid",openid);
%>

0x03运营维护篇

  • 系统环境为centos7发行版
  • xshell和xftp,用于远程控制文件传输
  • screen后台桌面管理工具
  • python3.6运行环境,werobot、image、pymysql等第三方库
  • openjdk1.8.0+jdbc环境
  • tomcat9环境

11111