mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-21 06:07:13 +08:00
fix: ensure get access_token thread-safe
This commit is contained in:
@@ -54,4 +54,4 @@
|
|||||||
|
|
||||||
AIGC开放社区中已经部署了多个可免费使用的Bot,扫描下方的二维码会自动邀请你来体验。
|
AIGC开放社区中已经部署了多个可免费使用的Bot,扫描下方的二维码会自动邀请你来体验。
|
||||||
|
|
||||||
<img width="360" src="./docs/images/aigcopen.png">
|
<img width="200" src="../../docs/images/aigcopen.png">
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding=utf-8 -*-
|
# -*- coding=utf-8 -*-
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
@@ -6,7 +5,7 @@ import textwrap
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
import web
|
import web
|
||||||
from wechatpy.enterprise import WeChatClient, create_reply, parse_message
|
from wechatpy.enterprise import create_reply, parse_message
|
||||||
from wechatpy.enterprise.crypto import WeChatCrypto
|
from wechatpy.enterprise.crypto import WeChatCrypto
|
||||||
from wechatpy.enterprise.exceptions import InvalidCorpIdException
|
from wechatpy.enterprise.exceptions import InvalidCorpIdException
|
||||||
from wechatpy.exceptions import InvalidSignatureException, WeChatClientException
|
from wechatpy.exceptions import InvalidSignatureException, WeChatClientException
|
||||||
@@ -14,6 +13,7 @@ from wechatpy.exceptions import InvalidSignatureException, WeChatClientException
|
|||||||
from bridge.context import Context
|
from bridge.context import Context
|
||||||
from bridge.reply import Reply, ReplyType
|
from bridge.reply import Reply, ReplyType
|
||||||
from channel.chat_channel import ChatChannel
|
from channel.chat_channel import ChatChannel
|
||||||
|
from channel.wechatcom.wechatcomapp_client import WechatComAppClient
|
||||||
from channel.wechatcom.wechatcomapp_message import WechatComAppMessage
|
from channel.wechatcom.wechatcomapp_message import WechatComAppMessage
|
||||||
from common.log import logger
|
from common.log import logger
|
||||||
from common.singleton import singleton
|
from common.singleton import singleton
|
||||||
@@ -38,7 +38,7 @@ class WechatComAppChannel(ChatChannel):
|
|||||||
"[wechatcom] init: corp_id: {}, secret: {}, agent_id: {}, token: {}, aes_key: {}".format(self.corp_id, self.secret, self.agent_id, self.token, self.aes_key)
|
"[wechatcom] init: corp_id: {}, secret: {}, agent_id: {}, token: {}, aes_key: {}".format(self.corp_id, self.secret, self.agent_id, self.token, self.aes_key)
|
||||||
)
|
)
|
||||||
self.crypto = WeChatCrypto(self.token, self.aes_key, self.corp_id)
|
self.crypto = WeChatCrypto(self.token, self.aes_key, self.corp_id)
|
||||||
self.client = WeChatClient(self.corp_id, self.secret) # todo: 这里可能有线程安全问题
|
self.client = WechatComAppClient(self.corp_id, self.secret)
|
||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
# start message listener
|
# start message listener
|
||||||
|
|||||||
21
channel/wechatcom/wechatcomapp_client.py
Normal file
21
channel/wechatcom/wechatcomapp_client.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
from wechatpy.enterprise import WeChatClient
|
||||||
|
|
||||||
|
|
||||||
|
class WechatComAppClient(WeChatClient):
|
||||||
|
def __init__(self, corp_id, secret, access_token=None, session=None, timeout=None, auto_retry=True):
|
||||||
|
super(WechatComAppClient, self).__init__(corp_id, secret, access_token, session, timeout, auto_retry)
|
||||||
|
self.fetch_access_token_lock = threading.Lock()
|
||||||
|
|
||||||
|
def fetch_access_token(self): # 重载父类方法,加锁避免多线程重复获取access_token
|
||||||
|
with self.fetch_access_token_lock:
|
||||||
|
access_token = self.session.get(self.access_token_key)
|
||||||
|
if access_token:
|
||||||
|
if not self.expires_at:
|
||||||
|
return access_token
|
||||||
|
timestamp = time.time()
|
||||||
|
if self.expires_at - timestamp > 60:
|
||||||
|
return access_token
|
||||||
|
return super().fetch_access_token()
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from wechatpy.enterprise import WeChatClient
|
from wechatpy.enterprise import WeChatClient
|
||||||
|
|
||||||
from bridge.context import ContextType
|
from bridge.context import ContextType
|
||||||
from channel.chat_message import ChatMessage
|
from channel.chat_message import ChatMessage
|
||||||
from common.log import logger
|
from common.log import logger
|
||||||
from common.tmp_dir import TmpDir
|
from common.tmp_dir import TmpDir
|
||||||
from lib import itchat
|
|
||||||
from lib.itchat.content import *
|
|
||||||
|
|
||||||
|
|
||||||
class WechatComAppMessage(ChatMessage):
|
class WechatComAppMessage(ChatMessage):
|
||||||
@@ -23,9 +18,7 @@ class WechatComAppMessage(ChatMessage):
|
|||||||
self.content = msg.content
|
self.content = msg.content
|
||||||
elif msg.type == "voice":
|
elif msg.type == "voice":
|
||||||
self.ctype = ContextType.VOICE
|
self.ctype = ContextType.VOICE
|
||||||
self.content = (
|
self.content = TmpDir().path() + msg.media_id + "." + msg.format # content直接存临时目录路径
|
||||||
TmpDir().path() + msg.media_id + "." + msg.format
|
|
||||||
) # content直接存临时目录路径
|
|
||||||
|
|
||||||
def download_voice():
|
def download_voice():
|
||||||
# 如果响应状态码是200,则将响应内容写入本地文件
|
# 如果响应状态码是200,则将响应内容写入本地文件
|
||||||
@@ -34,9 +27,7 @@ class WechatComAppMessage(ChatMessage):
|
|||||||
with open(self.content, "wb") as f:
|
with open(self.content, "wb") as f:
|
||||||
f.write(response.content)
|
f.write(response.content)
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(f"[wechatcom] Failed to download voice file, {response.content}")
|
||||||
f"[wechatcom] Failed to download voice file, {response.content}"
|
|
||||||
)
|
|
||||||
|
|
||||||
self._prepare_fn = download_voice
|
self._prepare_fn = download_voice
|
||||||
elif msg.type == "image":
|
elif msg.type == "image":
|
||||||
@@ -50,15 +41,11 @@ class WechatComAppMessage(ChatMessage):
|
|||||||
with open(self.content, "wb") as f:
|
with open(self.content, "wb") as f:
|
||||||
f.write(response.content)
|
f.write(response.content)
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(f"[wechatcom] Failed to download image file, {response.content}")
|
||||||
f"[wechatcom] Failed to download image file, {response.content}"
|
|
||||||
)
|
|
||||||
|
|
||||||
self._prepare_fn = download_image
|
self._prepare_fn = download_image
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(
|
raise NotImplementedError("Unsupported message type: Type:{} ".format(msg.type))
|
||||||
"Unsupported message type: Type:{} ".format(msg.type)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.from_user_id = msg.source
|
self.from_user_id = msg.source
|
||||||
self.to_user_id = msg.target
|
self.to_user_id = msg.target
|
||||||
|
|||||||
Reference in New Issue
Block a user