add sync_xbot_activity_info
continuous-integration/drone/push Build is passing

This commit is contained in:
jianxin committed 2024-02-20 20:04:04 +08:00
1 parent 57e98728eb
commit f6202d551e
13 files changed
+386 -41

No files matched your search

+5
View File
@@ -14,6 +14,11 @@ VERIFICATION_TOKEN=35LaoAPYTXRyBmjeaBvzRbRUsJSL1KBx
BITABLE_TOKEN=XDmHbhbZcaY4gZsOvBJcLcHonKh BITABLE_TOKEN=XDmHbhbZcaY4gZsOvBJcLcHonKh
TABLE_ID=tblwgGCDCE74Ugv6 TABLE_ID=tblwgGCDCE74Ugv6
# category
OFFICE_XBOT_BITABLE_TOKEN=XDmHbhbZcaY4gZsOvBJcLcHonKh
OFFICE_XBOT_TABLE_ID=tbl2GcBvkvMtOBnl
OFFICE_XBOT_VIEW_ID=vewIAewVD2
# REDIS # REDIS
BROKER_URL=redis://office-xbot-redis BROKER_URL=redis://office-xbot-redis
RESULT_BACKEND=redis://office-xbot-redis RESULT_BACKEND=redis://office-xbot-redis
+9 -5
View File
@@ -5,6 +5,7 @@ import time
import lark_oapi as lark import lark_oapi as lark
from celery import Celery from celery import Celery
from celery import Task from celery import Task
from celery.schedules import crontab
from flask import Flask from flask import Flask
@@ -101,11 +102,6 @@ def create_app() -> Flask:
resp = handler.do(parse_req()) resp = handler.do(parse_req())
return parse_resp(resp) return parse_resp(resp)
@app.route("/test", methods=["GET"])
def test():
add.delay(1, 2)
return {"test": "ok"}
@app.route("/index", methods=["GET"]) @app.route("/index", methods=["GET"])
def index(): def index():
return {"test": "ok"} return {"test": "ok"}
@@ -122,5 +118,13 @@ def celery_init_app(app: Flask) -> Celery:
celery_app = Celery(app.name, task_cls=FlaskTask) celery_app = Celery(app.name, task_cls=FlaskTask)
celery_app.config_from_object(app.config["CELERY"]) celery_app.config_from_object(app.config["CELERY"])
celery_app.set_default() celery_app.set_default()
celery_app.conf.timezone = "Asia/Shanghai"
celery_app.conf.beat_schedule = {
"sync-office-xbot-info": {
"task": "app.task.sync_xbot_activity_info",
"schedule": crontab(hour=19, minute=57),
},
}
app.extensions["celery"] = celery_app app.extensions["celery"] = celery_app
return celery_app return celery_app
Binary file not shown.
+7 -7
View File
@@ -2,10 +2,10 @@ from app import create_app
flask_app = create_app() flask_app = create_app()
celery_app = flask_app.extensions["celery"] celery_app = flask_app.extensions["celery"]
celery_app.conf.beat_schedule = { # celery_app.conf.beat_schedule = {
"add-every-30-seconds": { # "add-every-30-seconds": {
"task": "app.task.sync_xbot_activity_info", # "task": "app.task.sync_xbot_activity_info",
"schedule": 1800, # "schedule": 1800,
} # }
} # }
celery_app.conf.timezone = "UTC" # celery_app.conf.timezone = "UTC"
View File
Whitespace-only changes.
+71
View File
@@ -0,0 +1,71 @@
import os
import json
import lark_oapi as lark
from flask import Flask
from lark_oapi.adapter.flask import *
from lark_oapi.api.im.v1 import *
from lark_oapi.api.bitable.v1 import *
import lark_oapi as lark
from lark_oapi.api.drive.v1 import *
from lark_oapi.api.bitable.v1 import *
from app.utils.yd_utils import get_activity_info, get_token, get_office_app_uuids
from app.utils.utils import get_filtered_record_by_uuid, update_record, add_record
app_id = os.environ["APP_ID"]
app_secret = os.environ["APP_SECRET"]
bitable_token = os.environ["BITABLE_TOKEN"]
table_id = os.environ["TABLE_ID"]
xbot_username = os.environ["XBOT_USERNAME"]
xbot_password = os.environ["XBOT_PASSWORD"]
bitable_token = "XDmHbhbZcaY4gZsOvBJcLcHonKh"
table_id = "tbl2GcBvkvMtOBnl"
view_id = "vewIAewVD2"
client = lark.Client.builder().app_id(app_id).app_secret(app_secret).build()
token = get_token(xbot_username, xbot_password)
handle_list = []
# 同步应用数据
# office_app_uuids = get_office_app_uuids()
# print(f"office_activity_uuids count: {len(office_app_uuids)}")
# 同步指令数据
office_activity_uuids = get_activity_info(token)
print(f"office_activity_uuids count: {len(office_activity_uuids)}")
for item in office_activity_uuids:
robot_uuid = item.get("robotUuid")
package_view_name = item.get("packageViewName")
print("=====================================")
print(f"同步信息: {robot_uuid}, {package_view_name}")
record_id = get_filtered_record_by_uuid(
client, bitable_token, table_id, view_id, "UUID", robot_uuid
)
if record_id:
print(f"{robot_uuid}已同步多维表格中")
update_record(
client, bitable_token, table_id, record_id, {"名称": package_view_name}
)
else:
handle_list.append(robot_uuid)
print(f"{robot_uuid}: {package_view_name} 未同步多维表格中")
add_record(
client,
bitable_token,
table_id,
{"UUID": robot_uuid, "名称": package_view_name, "分类": "官方指令"},
)
print(f"新增的数量: {len(handle_list)}")
print("新增的uuid: ", handle_list)
+45 -23
View File
@@ -10,25 +10,6 @@ from app.utils.utils import *
from app.utils.yd_utils import get_token, get_activity_info from app.utils.yd_utils import get_token, get_activity_info
@shared_task(ignore_result=False)
def add(a: int, b: int) -> int:
return a + b
@shared_task()
def block() -> None:
time.sleep(5)
@shared_task(bind=True, ignore_result=False)
def process(self: Task, total: int) -> object:
for i in range(total):
self.update_state(state="PROGRESS", meta={"current": i + 1, "total": total})
time.sleep(1)
return {"current": total, "total": total}
@shared_task(include_result=False) @shared_task(include_result=False)
def process_message_callback( def process_message_callback(
app_id, app_secret, bitable_token, table_id, cache_dir, data app_id, app_secret, bitable_token, table_id, cache_dir, data
@@ -93,11 +74,52 @@ def process_message_callback(
@shared_task() @shared_task()
def sync_xbot_activity_info(): def sync_xbot_activity_info():
app_id = os.environ["APP_ID"]
app_secret = os.environ["APP_SECRET"]
bitable_token = os.environ["OFFICE_XBOT_BITABLE_TOKEN"]
table_id = os.environ["OFFICE_XBOT_TABLE_ID"]
view_id = os.environ["OFFICE_XBOT_VIEW_ID"]
xbot_username = os.environ["XBOT_USERNAME"] xbot_username = os.environ["XBOT_USERNAME"]
xbot_password = os.environ["XBOT_PASSWORD"] xbot_password = os.environ["XBOT_PASSWORD"]
client = lark.Client.builder().app_id(app_id).app_secret(app_secret).build()
token = get_token(xbot_username, xbot_password) token = get_token(xbot_username, xbot_password)
office_activity_uuids: list = get_activity_info(token)
handle_list = []
# 同步应用数据
# office_app_uuids = get_office_app_uuids()
# print(f"office_activity_uuids count: {len(office_app_uuids)}")
# 同步指令数据
office_activity_uuids = get_activity_info(token)
print(f"office_activity_uuids count: {len(office_activity_uuids)}")
for item in office_activity_uuids: for item in office_activity_uuids:
uuid = item.get("uuid") robot_uuid = item.get("robotUuid")
package_viewName = item.get("packageViewName") package_view_name = item.get("packageViewName")
print(uuid, package_viewName) print("=====================================")
print(f"同步信息: {robot_uuid}, {package_view_name}")
record_id = get_filtered_record_by_uuid(
client, bitable_token, table_id, view_id, "UUID", robot_uuid
)
if record_id:
print(f"{robot_uuid}已同步多维表格中")
update_record(
client, bitable_token, table_id, record_id, {"名称": package_view_name}
)
else:
handle_list.append(robot_uuid)
print(f"{robot_uuid}: {package_view_name} 未同步多维表格中")
add_record(
client,
bitable_token,
table_id,
{"UUID": robot_uuid, "名称": package_view_name, "分类": "官方指令"},
)
print(f"新增的数量: {len(handle_list)}")
print("新增的uuid: ", handle_list)
View File
Whitespace-only changes.
+84
View File
@@ -11,6 +11,7 @@ from lark_oapi.api.im.v1 import *
from lark_oapi.api.bitable.v1 import * from lark_oapi.api.bitable.v1 import *
import lark_oapi as lark import lark_oapi as lark
from lark_oapi.api.drive.v1 import * from lark_oapi.api.drive.v1 import *
from lark_oapi.api.bitable.v1 import *
def update_record(client, bitable_token, table_id, record_id, data): def update_record(client, bitable_token, table_id, record_id, data):
@@ -197,3 +198,86 @@ def send_message(client, receive_id, content):
# 处理业务结果 # 处理业务结果
lark.logger.info(lark.JSON.marshal(response.data, indent=4)) lark.logger.info(lark.JSON.marshal(response.data, indent=4))
def get_filtered_record_by_uuid(client, bitable_token, table_id, view_id, field_name, uuid):
request: SearchAppTableRecordRequest = (
SearchAppTableRecordRequest.builder()
.app_token(bitable_token)
.table_id(table_id)
.user_id_type("user_id")
.page_size(20)
.request_body(
SearchAppTableRecordRequestBody.builder()
.view_id(view_id)
.field_names([field_name])
.sort([Sort.builder().field_name(field_name).desc(True).build()])
.filter(
FilterInfo.builder()
.conjunction("and")
.conditions(
[
Condition.builder()
.field_name(field_name)
.operator("is")
.value([uuid])
.build()
]
)
.build()
)
.automatic_fields(False)
.build()
)
.build()
)
# 发起请求
option = (
lark.RequestOption.builder()
.user_access_token("u-caH0NMIK50kUMfBMUqgMtr1l6blBghh1Mi0015.82GbP")
.build()
)
response: SearchAppTableRecordResponse = client.bitable.v1.app_table_record.search(
request, option
)
# 处理失败返回
if not response.success():
# lark.logger.error(
# f"client.bitable.v1.app_table_record.search failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}"
# )
return
# 处理业务结果
lark.logger.info(lark.JSON.marshal(response.data))
if response.data.total == 1:
return response.data.items[0].record_id
if response.data.total == 2:
print("找到了多条记录")
if __name__ == "__main__":
app_id = os.environ["APP_ID"]
app_secret = os.environ["APP_SECRET"]
bitable_token = os.environ["BITABLE_TOKEN"]
table_id = os.environ["TABLE_ID"]
bitable_token = "XDmHbhbZcaY4gZsOvBJcLcHonKh"
table_id = "tbl2GcBvkvMtOBnl"
uuid = "4e478138-c8d6-426c-9761-3d1f4fd3cb05"
view_id = "vewIAewVD2"
# 创建client
client = (
lark.Client.builder()
.app_id(app_id)
.app_secret(app_secret)
.log_level(lark.LogLevel.DEBUG)
.build()
)
get_filtered_record_by_uuid(client, bitable_token, table_id, view_id, uuid)
+31 -1
View File
@@ -90,6 +90,36 @@ def get_activity_detail(token, package_name, package_version):
return response.json().get("data") return response.json().get("data")
def get_office_app_uuids() -> list:
"""
获取官方应用的 uuid,
:return: list, 官方应用 uuid
"""
uuids = []
tmp_list = []
page = 1
url = "https://api.winrobot360.com/api/noauth/v1/group/official/queryOfficialRobotList?page=%s&size=200"
page_response = requests.request("GET", url % page)
page_info = page_response.json().get("page").get("pages")
for item in range(1, page_info + 1):
response = requests.request("GET", url % item)
for item in response.json().get("data"):
# if item.get("robotGradeName") == "简单应用":
# continue
if item.get("uiTags") == "极速":
continue
print(item.get("name"), item.get("robotGradeName"))
uuids.append(item.get("uuid"))
name = item.get("name")
uuid = item.get("uuid")
return uuids
if __name__ == "__main__": if __name__ == "__main__":
dotenv.load_dotenv() dotenv.load_dotenv()
xbot_username = os.environ["XBOT_USERNAME"] xbot_username = os.environ["XBOT_USERNAME"]
@@ -97,4 +127,4 @@ if __name__ == "__main__":
token = get_token(xbot_username, xbot_password) token = get_token(xbot_username, xbot_password)
office_activity_uuids: list = get_activity_info(token) office_activity_uuids: list = get_activity_info(token)
for item in office_activity_uuids: for item in office_activity_uuids:
print(item) print(item.get("packageViewName"), item.get("uuid"))
+14
View File
@@ -17,6 +17,10 @@ services:
- RESULT_BACKEND=${RESULT_BACKEND} - RESULT_BACKEND=${RESULT_BACKEND}
- XBOT_USERNAME=${XBOT_USERNAME} - XBOT_USERNAME=${XBOT_USERNAME}
- XBOT_PASSWORD=${XBOT_PASSWORD} - XBOT_PASSWORD=${XBOT_PASSWORD}
- OFFICE_XBOT_BITABLE_TOKEN=${OFFICE_XBOT_BITABLE_TOKEN}
- OFFICE_XBOT_TABLE_ID=${OFFICE_XBOT_TABLE_ID}
- OFFICE_XBOT_VIEW_ID=${OFFICE_XBOT_VIEW_ID}
- TZ=Asia/Shanghai
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://office-xbot-app/index"] test: ["CMD", "curl", "-f", "http://office-xbot-app/index"]
interval: 30s interval: 30s
@@ -40,6 +44,10 @@ services:
- RESULT_BACKEND=${RESULT_BACKEND} - RESULT_BACKEND=${RESULT_BACKEND}
- XBOT_USERNAME=${XBOT_USERNAME} - XBOT_USERNAME=${XBOT_USERNAME}
- XBOT_PASSWORD=${XBOT_PASSWORD} - XBOT_PASSWORD=${XBOT_PASSWORD}
- OFFICE_XBOT_BITABLE_TOKEN=${OFFICE_XBOT_BITABLE_TOKEN}
- OFFICE_XBOT_TABLE_ID=${OFFICE_XBOT_TABLE_ID}
- OFFICE_XBOT_VIEW_ID=${OFFICE_XBOT_VIEW_ID}
- TZ=Asia/Shanghai
healthcheck: healthcheck:
test: ["CMD", "celery", "inspect", "ping"] test: ["CMD", "celery", "inspect", "ping"]
interval: 10s interval: 10s
@@ -59,6 +67,9 @@ services:
timeout: 10s timeout: 10s
retries: 3 retries: 3
environment:
- TZ=Asia/Shanghai
office-xbot-flower: office-xbot-flower:
container_name: office-xbot-flower container_name: office-xbot-flower
image: "${APP_IMAGE}" image: "${APP_IMAGE}"
@@ -70,6 +81,9 @@ services:
condition: service_healthy condition: service_healthy
restart: true restart: true
environment:
- TZ=Asia/Shanghai
networks: networks:
office-xbot-network: office-xbot-network:
Generated
+119 -4
View File
@@ -14,6 +14,28 @@ files = [
[package.dependencies] [package.dependencies]
vine = ">=5.0.0,<6.0.0" vine = ">=5.0.0,<6.0.0"
[[package]]
name = "anyio"
version = "4.2.0"
description = "High level compatibility layer for multiple asynchronous event loop implementations"
optional = false
python-versions = ">=3.8"
files = [
{file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"},
{file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"},
]
[package.dependencies]
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
idna = ">=2.8"
sniffio = ">=1.1"
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
[package.extras]
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (>=0.23)"]
[[package]] [[package]]
name = "async-timeout" name = "async-timeout"
version = "4.0.3" version = "4.0.3"
@@ -286,6 +308,20 @@ files = [
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
] ]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]] [[package]]
name = "flask" name = "flask"
version = "3.0.0" version = "3.0.0"
@@ -326,6 +362,62 @@ prometheus-client = ">=0.8.0"
pytz = "*" pytz = "*"
tornado = ">=5.0.0,<7.0.0" tornado = ">=5.0.0,<7.0.0"
[[package]]
name = "h11"
version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
optional = false
python-versions = ">=3.7"
files = [
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
[[package]]
name = "httpcore"
version = "1.0.3"
description = "A minimal low-level HTTP client."
optional = false
python-versions = ">=3.8"
files = [
{file = "httpcore-1.0.3-py3-none-any.whl", hash = "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2"},
{file = "httpcore-1.0.3.tar.gz", hash = "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544"},
]
[package.dependencies]
certifi = "*"
h11 = ">=0.13,<0.15"
[package.extras]
asyncio = ["anyio (>=4.0,<5.0)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
trio = ["trio (>=0.22.0,<0.24.0)"]
[[package]]
name = "httpx"
version = "0.26.0"
description = "The next generation HTTP client."
optional = false
python-versions = ">=3.8"
files = [
{file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"},
{file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"},
]
[package.dependencies]
anyio = "*"
certifi = "*"
httpcore = "==1.*"
idna = "*"
sniffio = "*"
[package.extras]
brotli = ["brotli", "brotlicffi"]
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
[[package]] [[package]]
name = "humanize" name = "humanize"
version = "4.9.0" version = "4.9.0"
@@ -413,16 +505,17 @@ zookeeper = ["kazoo (>=2.8.0)"]
[[package]] [[package]]
name = "lark-oapi" name = "lark-oapi"
version = "1.0.28" version = "1.2.0"
description = "Lark OpenAPI SDK for Python" description = "Lark OpenAPI SDK for Python"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "lark-oapi-1.0.28.tar.gz", hash = "sha256:18975097872a310e71a6abe48116b27741bc190244fcb0bfccd239303b5a4b19"}, {file = "lark-oapi-1.2.0.tar.gz", hash = "sha256:e6984a1213ce5ceb464023bb77ea7d675638f34c7b8c53050a4b0a121da0726c"},
{file = "lark_oapi-1.0.28-py3-none-any.whl", hash = "sha256:84ddf963dc968dd416f9577e04e27cc297989381733bdcb7e632a95ae74b4f6e"}, {file = "lark_oapi-1.2.0-py3-none-any.whl", hash = "sha256:95c9b48fe4629af2763421d62248301c787829b8d9435b9e09cc4bb4272d587f"},
] ]
[package.dependencies] [package.dependencies]
httpx = "*"
pycryptodome = "*" pycryptodome = "*"
requests = "*" requests = "*"
requests-toolbelt = "*" requests-toolbelt = "*"
@@ -671,6 +764,17 @@ files = [
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
] ]
[[package]]
name = "sniffio"
version = "1.3.0"
description = "Sniff out which async library your code is running under"
optional = false
python-versions = ">=3.7"
files = [
{file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
{file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
]
[[package]] [[package]]
name = "tornado" name = "tornado"
version = "6.4" version = "6.4"
@@ -691,6 +795,17 @@ files = [
{file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"},
] ]
[[package]]
name = "typing-extensions"
version = "4.9.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
]
[[package]] [[package]]
name = "tzdata" name = "tzdata"
version = "2023.4" version = "2023.4"
@@ -760,4 +875,4 @@ watchdog = ["watchdog (>=2.3)"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "2e056586ede929b134afce8a0b28ce5189b1ea298f1682472fdfde6e3e88cb79" content-hash = "274fcf51d4d82c6a4f00d9dea2f2da7a3716366414e9b54e309a1811a0d7304c"
+1 -1
View File
@@ -10,7 +10,7 @@ packages = [{include = "office_xbot_feishu"}]
python = "^3.10" python = "^3.10"
flask = "^3.0.0" flask = "^3.0.0"
python-dotenv = "^1.0.0" python-dotenv = "^1.0.0"
lark-oapi = "^1.0.28" lark-oapi = "1.2.0"
celery = "^5.3.6" celery = "^5.3.6"
redis = "^5.0.1" redis = "^5.0.1"
requests = "^2.31.0" requests = "^2.31.0"