WeCom + DeepSeek: A Practical Record of Building a Usable AI Agent from 0 to 1
When doing AI automation within an enterprise, many people get stuck on the most basic problem:
“The WeCom callback works fine, but it just doesn’t reply.”
This article is a complete record of the practical process: from integrating the WeCom callback, to driving AI replies with DeepSeek, and finally getting a usable AI Agent up and running.
This is not a concept, but a system that actually runs in production.
I. Overall Goal
What we want to build is a minimal viable AI Agent:
WeCom message → AI processing (DeepSeek) → Auto-reply
Core pipeline:
WeCom
↓
OpenResty / Nginx
↓
FastAPI service
↓
DeepSeek API
↓
Encrypted reply
↓
WeCom
II. Technology Stack
To ensure stability and maintainability, we chose the following combination:
- WeCom: message entry point
- FastAPI: callback service
- wechatpy: encryption/decryption library
- DeepSeek: LLM capability
- Docker: runtime environment
- OpenResty/Nginx: reverse proxy
III. The Essence of WeCom Callback (The Most Pitfall-Prone Spot)
The WeCom callback is not a normal HTTP API, but an encrypted communication protocol:
1. The request is encrypted XML
<xml>
<Encrypt>...</Encrypt>
<MsgSignature>...</MsgSignature>
<TimeStamp>...</TimeStamp>
<Nonce>...</Nonce>
</xml>
2. You must decrypt it to get the actual message content
3. The reply must be encrypted again
👉 Key point:
❗ “Receiving an HTTP request is not the end; you must complete the full encryption-decryption round trip.”
IV. Core Implementation (Final Stable Logic)
1. Decrypt the entire XML (Critical fix)
decrypted_xml = crypto.decrypt_message(
body.decode("utf-8"),
msg_signature,
timestamp,
nonce
)
✔ Correct: pass the entire XML body ❌ Wrong: pass only the Encrypt field
2. Parse business content
msg_xml = ET.fromstring(decrypted_xml)
content = msg_xml.find("Content").text
from_user = msg_xml.find("FromUserName").text
3. Call DeepSeek
reply = ask_deepseek(content)
if not reply:
reply = "ok"
Must also:
- Use try/except isolation
- Prevent AI from blocking the entire callback
4. Build reply XML
reply_xml = f"""
<xml>
<ToUserName><![CDATA[{from_user}]]></ToUserName>
<FromUserName><![CDATA[{CORP_ID}]]></FromUserName>
<CreateTime>{int(time.time())}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{reply}]]></Content>
</xml>
"""
5. Encrypt again for the response
encrypted = crypto.encrypt_message(
reply_xml,
nonce,
str(int(time.time()))
)
6. Return standard WeCom response
return Response(content=encrypted, media_type="application/xml")
V. Pitfalls Summary (The Most Critical Part)
The pitfalls encountered here are very typical and apply to all WeCom developers:
❌ Pitfall 1: Wrong parsing of the Encrypt field
Wrong way:
encrypt = xml.find("Encrypt").text
👉 Leads to incorrect input for decryption.
❌ Pitfall 2: Wrong parameters for decrypt
Wrong way:
decrypt_message(encrypt, ...)
👉 You must actually pass the entire XML body.
❌ Pitfall 3: Returning “success” instead of an encrypted response
WeCom message mode requires:
❗ Return encrypted XML, not “success”.
❌ Pitfall 4: AI blocking the callback
Must:
- Use try/except
- Provide a fallback reply
- Avoid interface timeout
VI. Final Architecture (Stable Version)
[WeCom]
↓
[Nginx/OpenResty]
↓
[FastAPI Callback Service]
↓
Decrypt
↓
Parse message
↓
DeepSeek API
↓
Generate reply
↓
Encrypt response
↓
[WeCom]
VII. System in Action
Once the system is up and running, you can achieve:
- ✔ Auto-reply AI Q&A in WeCom
- ✔ Internal enterprise knowledge assistant
- ✔ Automated customer service bot
- ✔ Workflow entry point (can later integrate with n8n / Hermes)
VIII. Next Upgrades (Advanced Architecture)
To go from “usable” to “production-grade”, you can extend further:
1. Async queue (to avoid AI blocking)
- Redis Queue / Celery / n8n
2. Message deduplication (WeCom retries)
- Redis message_id
3. Multi-model routing
- DeepSeek (complex questions)
- Rule engine (simple questions)
4. Enterprise knowledge base integration
- RAG / Vector database
IX. Summary
The most important takeaway from this exercise is not the code, but a key insight:
The difficulty of a WeCom AI Agent is not in AI, but in “correctness of the encryption/decryption protocol + callback closure”.
Once this pipeline is correct, everything that follows—AI, workflows—are just plug‑ins.
In the future, this system can be upgraded to:
A complete enterprise AI hub architecture with WeCom + DeepSeek + n8n + vector knowledge base.
Something that can be turned directly into an enterprise-grade product.
Appendix: Relevant code