WeChat-Django

repository·master·Indexed 41 days ago

https://github.com/xavier-lam/wechat-django

A Django extension for integrating WeChat Official Accounts and WeChat Pay, built on top of the wechatpy library. It provides wrappers for WeChat APIs, user management, message handling, and authorization for both web and mini-programs. Features include a dedicated admin site for managing accounts, auto-replies, and materials, as well as compatibility with Django Rest Framework (DRF) via WeChatOAuthViewMixin.

Tokens
9.2K
Snippets
32
Records
44
Agent score
52%

What's inside WeChat-Django

  1. Detect first-time subscriptions

    master

    Starting from version v0.3.3, when listening for subscription messages, WeChat-Django provides a first_subscribe attribute on the user object. This attribute is True if the user is subscribing for the first time, and False otherwise.

    Prerequisite: To ensure accuracy, you must synchronize all existing followers from your WeChat Official Account before handing over management to WeChat-Django. If you do not, the first follow event triggered after management begins will be incorrectly identified as a first_subscribe event.

    @message_handler
    def on_subscribe(message):
        user = message.local_user
        if user.first_subscribe:
            # Logic for first-time follow/subscribe
            pass
  2. Use WeChatUser for Django authentication

    master

    To use wechat_django.models.WeChatUser as your primary user model for Django authentication, you must prevent Django from attempting to update the last_login field, as WeChatUser does not contain this field.

    Failure to do this will cause errors during the automatic update_last_login process triggered by the user_logged_in signal.

    To fix this, disconnect the update_last_login signal in your AppConfig.ready() method. Once disconnected, you can use standard django.contrib.auth.login to authenticate users.

    # In your app's apps.py
    from django.contrib.auth.models import update_last_login
    from django.contrib.auth.signals import user_logged_in
    from django.apps import AppConfig
    
    class YourAppConfig(AppConfig):
        name = 'your_app'
    
        def ready(self):
            # Prevent Django from trying to update last_login on WeChatUser
            user_logged_in.disconnect(update_last_login, dispatch_uid='update_last_login')
  3. Configure Automatic Replies (Auto-Reply)

    master

    The '自动回复管理' (Auto-Reply Management) module allows you to manage how the system responds to incoming messages.

    Synchronizing Replies

    You can use the '同步' (Sync) action to import all auto-replies currently configured in the WeChat Official Account backend. Warning: Every time you re-sync, any auto-replies that were synced from WeChat but have not been edited in this system will be removed.

    Editing Replies

    Each auto-reply can be configured with:

    • Enabled/Disabled status
    • Log recording (whether to log the interaction)
    • Reply Strategy

    Rules

    An auto-reply can contain one or more rules. When an incoming message matches any rule, the system executes the associated reply strategy. Note: Once a rule is matched, the system stops checking any remaining rules or other auto-replies for that message.

    Reply Strategies and Execution

    • 全部回复 (Reply All): Executes all configured replies in sequence.
    • 随机回复 (Random Reply): Randomly selects and sends one of the configured replies.

    Critical Constraints:

    1. Uncertified Accounts: For uncertified accounts, 'Reply All' will execute all logic, but WeChat will only successfully deliver the last reply in the sequence.
    2. Message Type Limits: Per WeChat regulations, for text, image, video, article, and location messages, you can only reply with a maximum of one article. To ensure articles are sent correctly, place the article reply as the last item in your reply sequence.
  4. Define custom message handling rules

    master

    You can define custom business logic to determine if a specific message rule matches by using the @message_rule decorator.

    Rules must:

    1. Be decorated with from wechat_django import message_rule.
    2. Accept a single argument of type wechat_django.models.WeChatMessageInfo.
    3. Return a bool value (True if the rule matches, False otherwise).

    Important: Rules should be lightweight and side-effect free. If a rule raises an exception or returns False, it is treated as a non-match and skipped.

    from wechat_django import message_rule
    
    @message_rule
    def custom_business(message):
        """
        :type message: wechat_django.models.WeChatMessageInfo
        """
        user = message.user
        return user.openid == "1234567"
  5. Manage Menu, Materials, and Users

    master

    The admin panel provides several management modules:

    • 用户管理 (User Management): Allows updating the follow status of users. Note: Uncertified WeChat accounts do not have permission to sync users.
    • 菜单管理 (Menu Management): Used to synchronize or publish custom menus.
    • 素材及图文 (Materials & Articles): Allows synchronizing materials from the WeChat backend and remotely deleting permanent materials.
    • 自动回复权重 (Auto-Reply Weight): You can adjust the order of rule matching by changing the weight. Higher weights are matched first; weights can be negative numbers.
  6. Configure WeChat JS-SDK in Web Applications

    master

    To use WeChat JS-SDK features (like sharing) in a web application, you must first include the official WeChat JS file and then include the configuration script provided by wechat-django to initialize wx.config with the correct signature and parameters.

    1. Include the WeChat JS file

    Add the official WeChat JS library to your HTML:

    <script src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

    2. Include the wechat-django configuration script

    You need to load the configuration generated by the package. The jsApiList parameter must include all JS interfaces you intend to use.

    If using Django Templates: Use the wechat_django:jsconfig URL name. Pass the required interfaces via the jsApiList query parameter.

    <script src="{% url 'wechat_django:jsconfig' 'debug' %}?jsApiList=onMenuShareTimeline,onMenuShareAppMessage&debug=1"></script>

    If NOT using Django Templates (Static/Direct URL): Use the direct path pattern: /wechat/<yourappname>/wx.config.js. Replace <yourappname> with your actual Django app name.

    <script src="/wechat/{{yourappname}}/wx.config.js?jsApiList=onMenuShareTimeline,onMenuShareAppMessage&debug=1"></script>

    Parameters

    • jsApiList: A comma-separated list of the JS interfaces you need (e.g., onMenuShareTimeline,onMenuShareAppMessage).
    • debug: Set to 1 to enable debug mode. This will only function if settings.py has DEBUG = True.
    <!-- Example for Django Templates -->
    <script src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
    <script src="{% url 'wechat_django:jsconfig' 'debug' %}?jsApiList=onMenuShareTimeline,onMenuShareAppMessage&debug=1"></script>
  7. Access the sample site admin and default credentials

    master

    Once the server is running, you can access the administration interface and use the following default credentials for testing:

    • Admin Interface URL: http://localhost:8000/admin
    • Superuser Account: admin / Password: 123456
    • WeChat Admin Account: wechat_admin / Password: 123546
  8. Run the WeChat-Django sample site

    master

    To run the provided sample site, follow these steps to install dependencies, initialize the database, and start the development server.

    1. Install required Python packages:
      pip install -r requirements.txt
    2. Run database migrations. During this step, you will be prompted to enter your WeChat appid and appsecret. If you leave these blank, the system will generate a default appid and secret for you:
      python manage.py migrate
    3. Start the Django development server:
      python manage.py runserver
    pip install -r requirements.txt
    python manage.py migrate
    python manage.py runserver
  9. Install WeChat-Django

    master

    To install WeChat-Django, use pip with the appropriate cryptography dependency. After installation, add wechat_django to your INSTALLED_APPS, run migrations, and include the project URLs in your urls.py.

    Steps:

    1. Install via pip: pip install wechat-django[cryptography] or pip install wechat-django[pycrypto].
    2. Add wechat_django to INSTALLED_APPS in settings.py.
    3. Run migrations: python manage.py migrate wechat_django.
    4. Include wechat_django.sites.wechat.urls in your project's urlpatterns.
    5. Ensure USE_TZ = True is set in settings.py.
    pip install wechat-django[cryptography]
    python manage.py migrate wechat_django
  10. Add a new WeChat Official Account

    master

    To add a new WeChat account to the system, navigate to the '新增微信号' (Add WeChat Account) page and provide the following details:

    • 标题 (Title): A descriptive name for manual identification in the admin panel.
    • 名称 (Name): A globally unique identifier used by the program. Note: This cannot be modified after creation.
    • AppId: The official WeChat AppId. Note: This cannot be modified after creation.
    • 微信号类型 (Account Type): Select the appropriate WeChat account type.

    Post-creation Setup: After creating the account, enter its edit page to find the 消息回调地址 (Message Callback URL). You must copy this URL and paste it into the 'Developer Configuration' section of your WeChat Official Account Platform to enable message callbacks.

  11. Manage WeChat Content and Permissions

    master

    Once a WeChat account is added, you can manage its content through the '内容管理' (Content Management) menu.

    Important Note on Permissions: If you are not a Super Administrator, newly configured WeChat accounts will not automatically appear on your homepage. You must manually assign the administrator the specific permissions for that new account to make it visible.

  12. Use a custom request client via Model Proxying

    master

    If the default request client does not meet your requirements (e.g., you are interfacing with a third-party WeChat API instead of the official one), you can implement a custom client by subclassing WeChatClient and using a Django Model Proxy to inject it into WeChatApp.

    Steps:

    1. Define a custom client by inheriting from wechat_django.client.WeChatClient.
    2. Create a proxy model for wechat_django.models.WeChatApp by setting proxy = True in the Meta class.
    3. Override the _get_client method in your proxy model to return an instance of your custom client.
    4. Use the proxy model to retrieve app instances instead of the original WeChatApp model.
    from wechat_django.client import WeChatClient
    from wechat_django.models import WeChatApp
    
    # 1. Define custom client
    class CustomWeChatClient(WeChatClient):
        def _fetch_access_token(self, url, params):
            return dict(
                access_token="1234567",
                expires_in=60*30
            )
    
    # 2. Implement proxy model
    class CustomWeChatApp(WeChatApp):
        class Meta:
            proxy = True
    
        def _get_client(self):
            return CustomWeChatClient(self)
    
    # 3. Use proxy to get app instance
    app = CustomWeChatApp.objects.get_by_name("111")