outgoing钉钉机器人实现

本地测试与线上环境可以做到最大相同,需要:
钉钉提供的内网穿透-https://ding-doc.dingtalk.com/doc#/kn6zg7/hb7000(有了它就可以模拟一个真实域名,可以指定端口)
我使用的是python3.7,线上环境是python2.7.5,实际并无太大影响

# -*- coding: UTF-8 -*-
from flask import Flask, request, jsonify
import json
import os
import hmac
import hashlib
import base64
import time
import requests
# ast包可以将字符串转换为有效字典
import ast
import re
import json


lgoin_session = requests.session()
wiki_url = 'https://*'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'
header_wiki = {
    'referfer': 'https://*',
    'user-agent': user_agent
}

app = Flask(__name__)# Flask构造函数使用当前模块(__name __)的名称作为参数。
# route()函数是一个装饰器,它告诉应用程序哪个URL应该调用相关的函数。
@app.route('/data', methods=['GET', 'POST'])
def index():
# 获取headers数据
    headers_data = request.headers
# 获取body数据
    body_data = request.get_json()
    
    wiki_sl = wiki(headers_data,body_data)
    wiki_sl.run()

    return ''

class wiki:

    def __init__(self,ss,bb):
        self.username='******'
        self.password='******'
        self.post_sign=''
        self.post_time=''
        self.post_man=''
        self.post_msg=''
        self.send_msg=''
        self.time_now=''
        self.count_sing=''
        self.message=''
        self.senddata={}
        self.headers_data=ss
        self.body_data=bb

    def getPost(self): # 这个方法是为了把需要的数据剥离出来
        # post_sign=self.post_sign
        # post_time=self.post_time
        # post_man=self.post_man
        # post_msg=self.post_msg
        self.post_sign = self.headers_data
        self.post_sign = self.headers_data['Sign'].lstrip()
        self.post_time = self.headers_data['Timestamp'].lstrip()
        self.post_man = self.body_data['senderNick'].lstrip()
        self.post_msg = self.body_data['text']['content'].strip()

    def initKey(self):	# 这个方法是用来提供钉钉验证的时间戳和sign
        self.time_now = str(round(time.time()) * 1000)
        app_secret = '钉钉开放平台机器人基础信息的AppSecret'

        app_secret_enc = app_secret.encode('utf-8')
        string_to_sign = '{}\n{}'.format(self.post_time, app_secret)
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        self.count_sing = base64.b64encode(hmac_code).decode('utf-8')

    def login_wiki(self):	# 这个方法是用来登录内网的wiki进行查询,并把我需要的数据剥离出来
        post_data = {
            'os_username': self.username,
            'os_password': self.password,
            'login': '登陆',
            'os_destination': '/ pages / viewpage.action?pageId = 6620637os_destination: /pages/viewpage.action?pageId=6620637'
        }
		# 使用requests的session数据进行post登陆
        response_wiki = lgoin_session.post(wiki_url, headers=header_wiki, data=post_data)

        search_url = 'https://*' + self.post_msg + '*'
        
        search_html = lgoin_session.get(search_url, headers=header_wiki)
        search_dictionary = ast.literal_eval(search_html.text)
        list = search_dictionary['results']

        if list == []:
            file_nothing = '没有查询到任何东西哦~'
            self.senddata = file_nothing
        else :
            for key_list in list:
                list_word = key_list['title']
                word_cear = '[标题]:' + re.sub('@|end|hl', '', list_word)

                list_bodytext = key_list['bodyTextHighlights']
                bodytext_cear ='[内容]:' + re.sub('@|end|hl', '', list_bodytext)

                list_url = key_list['url']
                url_generate ='[链接]:' + 'https://*/' + list_url

                send_data = str(word_cear)+'\n'+str(bodytext_cear)+'\n'+str(url_generate)
                file_op = open('./data.txt','a')
                file_wr = file_op.write(send_data+'\n\n')
                file_opr = open('./data.txt','r')
                file_read = file_opr.read()
                
                self.senddata= file_read # {'[标题]': word_cear, '[内容]': bodytext_cear, '[链接]': url_generate}

    def selectMsg(self):	# 这个方法为发送给钉钉的信息进行选择
        if self.post_msg == '':
            self.send_msg = '为空,无法查询'
            self.sendText()
        else:
            self.send_msg = self.senddata
            self.sendText()


    def sendText(self):		# 这个方法是钉钉机器人文档提供的文本模板,at不生效,不清楚为什么
        self.message = {
            "msgtype": "text",
            "text": {
                "content": self.send_msg
            },
            "at": {
                "atMobiles": [self.post_man],
                "isAtAll": False
            }
        }
        # print(message)

    def sData(self):	# 进行验证判断,并发送机器人回复
        hook_token = '*'
        if (abs(int(float(self.post_time)) - int(float(self.time_now))) < 3600000 and self.post_sign == self.count_sing):
            webhook = 'https://oapi.dingtalk.com/robot/send?access_token=' + hook_token + '×tamp=' + self.time_now + '&sign=' + self.count_sing
            header = {
                "Content-Type": "application/json",
                "Charset": "UTF-8"
            }
            message_json = json.dumps(self.message)

            info = requests.post(url=webhook, headers=header, data=message_json)
            os.remove('./data.txt')
            # print(json.loads(info.text))
        else:
            print("Warning:Not DingDing's post")


    def run(self):  # 方法启动顺序
        self.getPost()
        self.initKey()
        self.login_wiki()
        self.selectMsg()
        self.sendText()
        self.sData()

if __name__ == '__main__':

    app.run(port=***, debug=True)

遇到了很多坑,还好学到了很多。

你可能感兴趣的:(outgoing钉钉机器人实现)