Build a DingTalk Enterprise Bot with Python Flask for Domain & SSL Expiry Checks
This guide walks through creating a DingTalk enterprise robot using Python Flask, covering incoming vs outgoing modes, required prerequisites, step‑by‑step robot creation, backend webhook implementation, domain and SSL certificate expiry detection with code samples, and real‑world integration scenarios.
Two Concepts
If your organization uses DingTalk, you may have used group robots (incoming mode) for tasks like issue or tag notifications. The outgoing mode, called an enterprise robot, allows interactive communication based on backend logic, similar to WeChat bots.
Prerequisites for Using DingTalk Enterprise Robots
1. An authenticated DingTalk organization (company or personal)
2. A public IP address (required for robot registration)
3. A POST‑type message push interface reachable from the internet
4. Python
5. Flask
Creating a DingTalk Group Robot
Use a personal DingTalk organization for demonstration; companies can use their own organization.
Create Robot
If not authenticated, you will be prompted to authenticate.
After authentication, proceed to create the robot.
Provide a clear description for the robot.
Enter the public IP and the message‑receiving endpoint.
The endpoint can be a temporary Flask hello world POST service; ensure the route matches the one entered in the robot configuration.
# -- coding:UTF-8 --
from flask import Flask, request
app = Flask(__name__)
@app.route('/call', methods=['POST'])
def call():
if request.method == 'POST':
return 'This is a POST request'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)After creation, save the robot's key and secret for message authentication.
Publish the robot.
Add the Enterprise Robot to a DingTalk Group
Backend Code Logic for Detection
Modify the Verification Endpoint
Ensure the route matches the one configured in DingTalk and return processed messages.
# -- coding:UTF-8 --
from flask import Flask, request
app = Flask(__name__)
@app.route('/call', methods=['POST'])
def call():
if request.method == 'POST':
content = request.get_json().get('text').get('content')
msg = {"msgtype":"text","text":{"content":f"You said: {content}"},"at":{"atMobiles":[],"isAtAll":False}}
return msg
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)How to Detect Domain Expiry
Use the python-whois package; note that some TLDs (e.g., .life) may not be fully supported.
Install python-whois
pip install python-whoisPseudo‑code for checking domain expiry
# -- coding:UTF-8 --
import sys, whois
def expire_result(domain):
domain_infos = whois.whois(domain)
expire_date = domain_infos.expiration_date[1]
return expire_dateIntegrate into the Flask Endpoint
# -- coding:UTF-8 --
from flask import Flask, request
from check_domain_expire import expire_result
app = Flask(__name__)
@app.route('/call', methods=['POST'])
def call():
if request.method == 'POST':
content = request.get_json().get('text').get('content')
domain_expire_date = expire_result(content.strip())
msg = {"msgtype":"text","text":{"content":f"Domain: {content}
Expiry: {domain_expire_date}
"},"at":{"atMobiles":[],"isAtAll":False}}
return msg
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)How to Detect SSL Certificate Expiry
Use pyopenssl to retrieve the certificate and parse its notAfter field.
Install pyopenssl
pip install pyopensslPseudo‑code for checking SSL expiry
# -- coding:UTF-8 --
import OpenSSL, ssl, socket
def ssl_expire_result(domain):
cert = ssl.get_server_certificate((domain, 443))
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
return x509.get_notAfter()Update the Flask Endpoint
# -- coding:UTF-8 --
from flask import Flask, request
from check_ssl_expire import ssl_expire_result
app = Flask(__name__)
@app.route('/call', methods=['POST'])
def call():
if request.method == 'POST':
content = request.get_json().get('text').get('content')
ssl_expire_date = ssl_expire_result(content.strip())
msg = {"msgtype":"text","text":{"content":f"Domain: {content}
SSL Expiry: {ssl_expire_date}
"},"at":{"atMobiles":[],"isAtAll":False}}
return msg
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)More Complex Scenarios
Combine both functions by parsing user input prefixes such as 域名|xxx.com for domain checks and 证书|xxx.com for SSL checks, or use numeric codes to select the operation.
# Default response when no input is provided
msg = {"msgtype":"text","text":{"content":"Query format:
1. Domain expiry: 域名|xxxx.com
2. SSL expiry: 证书|xxxx.com"},"at":{"atMobiles":[],"isAtAll":False}}Practical Use Cases in Operations
Integrate with CMDB for conversational retrieval of service domain and monitoring information.
Connect to monitoring tools for chat‑based operations like log compression.
Fetch real‑time log streams from logging systems.
Schedule tasks via at‑bot (e.g., weekly work plan).
General operational scripting.
Issues Encountered
Debugging DingTalk robot responses: body data may be incomplete, making it hard to obtain userid.
Signature authentication mentioned in official docs is optional.
Official Documentation
DingTalk Enterprise Robot and DingTalk Group Robot documentation.
Author: a seasoned DevOps engineer interested in Kubernetes and DevOps, open to discussion.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
