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