收藏
回答

公众号自定义发送位置,location和location_select事件,回复失败?

1.需求:根据不同的发送位置做不同的处理。所以自定义了发送位置事件。eventKey为publish。可能用到多个发送位置作不同处理。

2.问题:用户发送位置时,后台收到一个带有eventKey的location_select事件,和location事件(没有eventKey)。

我需要处理完location_select(带eventKey为publish)的事件后,回复消息。

3.结果:用户不收到消息。

4.发现:location事件回复真正消息,用户能收到;location事件回复""且location_select事件回复真正消息,用户收不到。

5.猜测:因为腾讯同时向我发出了两条请求,会不会排重原因location事件回复覆盖掉location_select事件。


<FromUserName><![CDATA[oUqtYx0]]></FromUserName>

<CreateTime>1742716069</CreateTime>

<MsgType><![CDATA[event]]></MsgType>

<Event><![CDATA[location_select]]></Event>

<EventKey><![CDATA[push_car_in]]></EventKey>

<SendLocationInfo><Location_X><![CDATA[XX.203168701311291]]></Location_X>

<Location_Y><![CDATA[XX.52965488217018]]></Location_Y>

<Scale><![CDATA[15]]></Scale>

<Label><![CDATA[]]></Label>

<Poiname><![CDATA[XXXXX]]></Poiname>

</SendLocationInfo>

</xml>)]


<FromUserName><![CDATA[oZqtYx0]]></FromUserName>

<CreateTime>1742716068</CreateTime>

<MsgType><![CDATA[location]]></MsgType>

<Location_X>XX.203169</Location_X>

<Location_Y>XX.529655</Location_Y>

<Scale>15</Scale>

<Label><![CDATA[]]></Label>

<MsgId>2494XX7XX</MsgId>

</xml>)]


回答关注问题邀请回答
收藏

1 个回答

  • A思维
    A思维
    03-25

    1. 问题原因:

    当用户通过自定义菜单选择位置时,微信服务器会同时发送两个事件:

    location_select事件(带有EventKey)

    location事件(不带EventKey)

    由于这两个事件几乎同时到达,可能会造成消息覆盖

    2. 解决方案:

    建议采用以下方式处理:

    def handle_wechat_event(request):

        # 解析XML数据

        msg_type = xml_data.find('MsgType').text

        

        if msg_type == 'event':

            event_type = xml_data.find('Event').text

            

            if event_type == 'location_select':

                # 获取EventKey

                event_key = xml_data.find('EventKey').text

                # 获取位置信息

                location_x = xml_data.find('.//Location_X').text

                location_y = xml_data.find('.//Location_Y').text

                

                # 处理location_select事件,但不立即回复

                process_location_select(event_key, location_x, location_y)

                return ''  # 返回空字符串

                

            elif event_type == 'location':

                # 在location事件中进行实际的消息回复

                location_x = xml_data.find('Location_X').text

                location_y = xml_data.find('Location_Y').text

                

                # 获取之前处理的结果并回复

                reply_content = get_processed_reply(location_x, location_y)

                return format_reply(reply_content)

    03-25
    有用 1
    回复 5
    • A思维
      A思维
      03-25
      3. 关键点:
      在location_select事件中只进行数据处理,不回复消息(返回空字符串)
      在location事件中进行实际的消息回复
      可以使用缓存(如Redis)在两个事件之间传递数据
      4. 示例实现:
      import redis
      # 初始化Redis连接
      redis_client = redis.Redis(host='localhost', port=6379, db=0)
      def process_location_select(event_key, location_x, location_y):
          # 将处理结果存入Redis,设置过期时间为60秒
          key = f"location_{location_x}_{location_y}"
          result = process_by_event_key(event_key, location_x, location_y)
          redis_client.setex(key, 60, result)
      def get_processed_reply(location_x, location_y):
          # 从Redis获取之前的处理结果
          key = f"location_{location_x}_{location_y}"
          result = redis_client.get(key)
          return result if result else "默认回复消息"
      03-25
      1
      回复
    • A思维
      A思维
      03-25回复A思维
      5. 注意事项:
      确保location_x和location_y的精度处理,可能需要进行四舍五入
      设置合适的缓存过期时间
      考虑并发情况下的处理
      这样处理可以确保用户能收到正确的回复消息,同时避免消息覆盖的问题。
      03-25
      1
      回复
    • DLXT
      DLXT
      发表于移动端
      03-25回复A思维
      知道了,非常感谢。我之前也想过要是实在没办法就按照你说的一样辅助redis来做。 目前确实先收到带有eventkey的locationselect事件,后收到location事件。这样好处理。要是顺序反了就比较麻烦了,应该也有办法的, 总之非常感谢你的建议,我就这样做吧
      03-25
      1
      回复
    • DLXT
      DLXT
      发表于移动端
      03-25回复A思维
      就相当于,locationselect负责处理事情,location负责反回locationselect的消息
      03-25
      1
      回复
    • A思维
      A思维
      03-25回复DLXT
      是的,您理解得很准确!这种方式确实是比较优雅的解决方案。
      03-25
      1
      回复
登录 后发表内容