微信扫码
与创始人交个朋友
我要投稿
NtWork是基于PC企业微信的API接口,支持收发文本、群@、名片、图片、文件、视频、链接卡片等。
代码位置:dify-on-wechat/app.py
这段代码的作用是在程序接收到特定信号时,保存用户数据,并根据原有的信号处理逻辑决定是否结束程序。
def sigterm_handler_wrap(_signo):
old_handler = signal.getsignal(_signo)
def func(_signo, _stack_frame):
logger.info("signal {} received, exiting...".format(_signo))
conf().save_user_datas()
if callable(old_handler):#check old_handler
return old_handler(_signo, _stack_frame)
sys.exit(0)
signal.signal(_signo, func)
这段代码定义了一个名为 sigterm_handler_wrap
的函数,它接受一个参数 _signo
,这个参数代表一个信号的编号。这个函数的主要目的是为了处理程序接收到的特定信号。
首先,它获取当前已经设置的信号处理函数 old_handler
,这是通过调用 signal.getsignal(_signo)
实现的。
然后,它定义了一个新的信号处理函数 func
。这个函数在接收到信号时会被调用,它接受两个参数:信号编号 _signo
和栈帧对象 _stack_frame
。
在 func
函数内部,首先会记录一条日志,表示接收到了信号。然后,它会调用 conf().save_user_datas()
来保存用户数据。
接下来,它会检查 old_handler
是否是可调用的。如果是,那么就调用 old_handler
,并将信号编号和栈帧对象作为参数传入。这样做的目的是为了保留原有的信号处理逻辑。
如果 old_handler
不是可调用的,那么就直接调用 sys.exit(0)
来结束程序。
最后,通过调用 signal.signal(_signo, func)
将新的信号处理函数 func
设置为 _signo
信号的处理函数。
signal.SIGINT
和 signal.SIGTERM
是 Python 中的信号处理模块 signal
中的两个预定义信号。
signal.SIGINT
这个信号通常是由用户生成的,当用户在命令行中按下 Ctrl+C
时,就会发送 SIGINT
信号。这个信号的默认行为是终止进程,但是我们可以通过编程来改变这个行为。
signal.SIGTERM
这个信号通常是由 kill
命令发送的。它的默认行为也是终止进程,但是和 SIGINT
一样,我们也可以通过编程来改变这个行为。
在代码中,sigterm_handler_wrap(signal.SIGINT)
和 sigterm_handler_wrap(signal.SIGTERM)
是为 SIGINT
和 SIGTERM
信号设置了新的处理函数。当这两个信号被接收到时,会执行 sigterm_handler_wrap
函数中定义的 func
函数,这个函数会保存用户数据,然后根据原有的信号处理逻辑决定是否结束程序。
代码位置:dify-on-wechat/app.py
这个函数的作用是根据传入的通道名称创建一个通道对象,加载插件,可能会启动 linkai_client
,并启动这个通道。
def start_channel(channel_name: str):
channel = channel_factory.create_channel(channel_name)
if channel_name in ["wx", "wxy", "terminal", "wechatmp", "wechatmp_service", "wechatcom_app", "wework", "wechatcom_service", const.FEISHU, const.DINGTALK]:
PluginManager().load_plugins()
if conf().get("use_linkai"):
try:
from common import linkai_client
threading.Thread(target=linkai_client.start, args=(channel,)).start()
except Exception as e:
pass
channel.startup()
这段代码定义了一个名为 start_channel
的函数,它接受一个参数 channel_name
,这个参数代表一个通道的名称。
首先,它调用 channel_factory.create_channel(channel_name)
来创建一个通道对象,并将其赋值给变量 channel
。channel_factory
是一个工厂对象,它的 create_channel
方法根据传入的通道名称创建对应的通道对象。
然后,它检查 channel_name
是否在一个特定的列表中。这个列表包含了 "wx"
, "wxy"
, "terminal"
, "wechatmp"
, "wechatmp_service"
, "wechatcom_app"
, "wework"
, "wechatcom_service"
, const.FEISHU
, const.DINGTALK
等值。如果 channel_name
在这个列表中,那么就调用 PluginManager().load_plugins()
来加载插件。
接下来,它检查配置项 "use_linkai"
的值。如果这个配置项的值为真,那么就尝试从 common
模块导入 linkai_client
,并在一个新的线程中启动 linkai_client
。这个新线程的目标函数是 linkai_client.start
,并将 channel
作为参数传入。如果在这个过程中发生任何异常,那么就忽略这个异常。
最后,它调用 channel.startup()
来启动这个通道。
代码位置:dify-on-wechat/channel/wework/wework_channel.py
这个方法的作用是启动企业微信的服务,获取并保存联系人和聊天室的信息,然后启动主循环。
def startup(self):
smart = conf().get("wework_smart", True)
wework.open(smart)
logger.info("等待登录······")
wework.wait_login()
login_info = wework.get_login_info()
self.user_id = login_info['user_id']
self.name = login_info['nickname']
logger.info(f"登录信息:>>>user_id:{self.user_id}>>>>>>>>name:{self.name}")
logger.info("静默延迟60s,等待客户端刷新数据,请勿进行任何操作······")
time.sleep(60)
contacts = get_with_retry(wework.get_external_contacts)
rooms = get_with_retry(wework.get_rooms)
directory = os.path.join(os.getcwd(), "tmp")
if not contacts or not rooms:
logger.error("获取contacts或rooms失败,程序退出")
ntwork.exit_()
os.exit(0)
if not os.path.exists(directory):
os.makedirs(directory)
# 将contacts保存到json文件中
with open(os.path.join(directory, 'wework_contacts.json'), 'w', encoding='utf-8') as f:
json.dump(contacts, f, ensure_ascii=False, indent=4)
with open(os.path.join(directory, 'wework_rooms.json'), 'w', encoding='utf-8') as f:
json.dump(rooms, f, ensure_ascii=False, indent=4)
# 创建一个空字典来保存结果
result = {}
# 遍历列表中的每个字典
for room in rooms['room_list']:
# 获取聊天室ID
room_wxid = room['conversation_id']
# 获取聊天室成员
room_members = wework.get_room_members(room_wxid)
# 将聊天室成员保存到结果字典中
result[room_wxid] = room_members
# 将结果保存到json文件中
with open(os.path.join(directory, 'wework_room_members.json'), 'w', encoding='utf-8') as f:
json.dump(result, f, ensure_ascii=False, indent=4)
logger.info("wework程序初始化完成········")
run.forever()
这段代码是 WeworkChannel
类的 startup
方法,它的主要作用是启动企业微信(WeWork)的相关服务。首先,它从配置中获取 "wework_smart"
的值,如果没有这个配置项,则默认为 True
。然后,它调用 wework.open(smart)
来打开企业微信的服务。
接着,它调用 wework.wait_login()
来等待用户登录。当用户登录后,它会获取登录信息,并将用户的 ID 和昵称保存到 self.user_id
和 self.name
中。
然后,它会暂停 60 秒,等待客户端刷新数据。接下来,它会尝试获取企业微信的外部联系人(contacts
)和聊天室(rooms
)。如果获取失败,那么就会退出程序。
如果获取成功,那么就会将 contacts
和 rooms
保存到本地的 JSON 文件中。同时,它还会遍历每个聊天室,获取聊天室的成员,并将结果保存到本地的 JSON 文件中。
最后,它会打印一条日志,表示企业微信的程序已经初始化完成,并调用 run.forever()
来启动主循环。
NLP工程化(公众号)
NLP工程化(星球号)
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-01-17
从 Dify 到 Rill-Flow:大模型应用平台的进化之路
2025-01-13
前后端源码部署:Dify v0.15.0 升级 v1.0.0-beta.1 的尝试
2025-01-11
Dify v1.0.0-beta:插件开启公测
2025-01-07
Dify v0.15.0:全新父子检索策略 - 更精准,更全面的知识检索
2024-12-27
【场景驱动】企业的哪些重复性任务,最适合用Coze循环节点来解决?——慢慢学AI146
2024-12-24
Coze,Dify,FastGPT,哪个更强?全方位对比分析来了!
2024-12-19
打开日本市场背后,Dify 是怎么做 AI 全球化的?
2024-12-15
有了 NewAPI 之后,Dify 的可玩儿性又高了
2024-04-25
2024-04-24
2024-07-16
2024-07-20
2024-12-24
2024-05-08
2024-05-07
2024-05-09
2024-06-21
2024-04-25