利用飞书多维表格自动发布版本
文章目录
- 背景
- 尝试1,轮询
- 尝试2,长连接
背景
博主所在的部门比较奇特,每个车型每周都需要发版,所以实际上一周会发布好几个版本。经过之前使用流水线自动发版改造之后,发版的成本已经大大降低了,具体参考: 利用流水线实现版本一键发布。
但是由于发版的时间不固定,且忙起来之后容易忘记,所以现状就是每周由 pm 制定好了发版计划,然后到时间了之后由测试同学在群里@开发同学进行发版。
有没有什么方法可以每周设定好了发版时间,然后到时间之后自动触发发版流程,并在群里通知呢?我想到了飞书的多维表格。飞书的多维表格有自动化的能力,我们每周只需要设定好版本发布的时间,可以让其自动触发版本发布,并在群里通知所有人。

想象比较美好,但现实是公司的内网和飞书并不在同一个网络,因此飞书的自动化流程没办法触发到内网的流水线,为此我做了一些尝试。
尝试1,轮询
我们在飞书表格当中设定好发版车型,版本号,时间等一系列参数之后,可以在内网的服务器开启一个轮询,不断的从飞书表格当中获取这些值,到了设定好的时间之后,就在内网触发流水线进行版本发布。
但是有个问题,我们一周最多可能发布四个版本,如何设定轮询的时间间隔呢?
假定我们每天获取一次,也就是时间间隔控制在一天,那么就会出现信息获取不及时的现象,例如今天早上获取了发版信息,下午要发布一个版本,但是如果中午修改了发版计划,取消了下午发版,此时就没办法即时通知到内网,导致下午还会触发版本发布。
那么假定我们每隔10分钟获取一次,除非在发版前10分钟内修改发版计划,否则都能感知到版本计划的变更,出现上述问题的概率就大大降低,但是一直轮询,大量的网络请求其实都是无效的,而且也没有利用到飞书的自动化能力。
因此这个方法并不好。
尝试2,长连接
如果轮询不可以,那么我们是否能够在外网和内网当中建立一个长连接,利用飞书的自动化能力,当到达设定的时间时,可以通过长连接将相应的发版信息推送到内网当中,这样不就实现自动发版了么?
说干就干,在腾讯云上买了一台云服务器,最便宜的(一年才90几块钱),不过配置也够用了。

接着在云上部署了两个服务,一个是 http 服务,用于让飞书表格触发,一个是 websocket 服务,用于和内网保持长连接,具体如下:
http 服务
部署在云端,这里使用的是 python 的 Flask 框架
@app.route("/trigger", methods=['POST'])
def triggerEvent():try:data = json.dumps(dict(request.form))print(f"received msg:{data}")logging.info(f"received trigger msg:{data}")executor.submit(WebsocketService.sendMsg,data)return "OK"except Exception as ex:return f"error,{ex}"def start():print("service start")app.run(host='0.0.0.0',port=8888)
websocket 服务
部署在云端,这里主要的逻辑就是,当有 websocket 客户端连接上之后就将其保存在 set 集合里面,一旦 http 服务收到消息,就会通过 set 集合里面的 websocket 客户端将消息转发出去。
clients = set()async def __handleClient(websocket):print(f"new connection from {websocket.remote_address}")try:while True:clients.add(websocket)message = await websocket.recv()print(f"received message:{message}")except Exception as ex:print(f"exception :{ex}")clients.remove(websocket)async def __sendMsgToClient(msg):for client in clients:try:logging.info(f"websocket send:{msg}")await client.send(msg)except Exception as ex:print("send msg failed")logging.info(f"websocket send failed:{ex}")def sendMsg(msg):asyncio.run(__sendMsgToClient(msg))async def __start():server = await websockets.serve(__handleClient,'0.0.0.0',8889)await server.wait_closed()def start():print("websocket service start")asyncio.run(__start())
websocket 客户端
部署在内网,这里开启了一个死循环,一直监听服务端发送的消息,然后根据消息再做响应事件。
async def __webscoketClient():uri = "ws://xxx:8889"while True:try:async with websockets.connect(uri) as websocket:await websocket.send("hello,server!")while True:msg = await websocket.recv()logging.info(f"received message from server:{msg}")__handleSocketMsg(msg)except Exception as ex:logging.info(f"connect exception :{ex}")print(f"reconnecting in 10 seconds")await asyncio.sleep(10)
飞书多维表格配置
表格当中我们可以将需要的参数都写进去,我们需要关注的是 publisTime 版本发布时间,我们需要根据时间来进行自动触发。

进入自动化的编辑页面,可以设定当到达记录中的时间时,往我们刚刚在腾讯云上搭建的服务器发送消息,这样就可以通过长连接将消息发送到内网,从而实现自动发布版本的能力。

另外,需要注意的是,在腾讯云中需要在防火墙页面把相应的端口打开,不然访问会被拒绝。
相关文章:
利用飞书多维表格自动发布版本
文章目录 背景尝试1,轮询尝试2,长连接 背景 博主所在的部门比较奇特,每个车型每周都需要发版,所以实际上一周会发布好几个版本。经过之前使用流水线自动发版改造之后,发版的成本已经大大降低了,具体参考&a…...
深入内核讲明白Android Binder【一】
深入内核讲明白Android Binder【一】 前言一、Android Binder应用编写概述二、基于C语言编写Android Binder跨进程通信Demo0. Demo简介1. 服务的管理者server_manager.c2. Binder服务端代码实现 test_service.c2.1 实现思路2.2 完整实现代码 3. Binder客户端代码实现 test_clie…...
Photoshop(PS)——人像磨皮
1.新建一个文件,背景为白色,将图片素材放入文件中 2.利用CtrlJ 复制两个图层出来,选择第一个拷贝图层,选择滤镜---杂色---蒙尘与划痕 3.调整一下数值,大概能够模糊痘印痘坑,点击确定。 4.然后选择拷贝2图层…...
如何用Excel批量提取文件夹内所有文件名?两种简单方法推荐
在日常办公中,我们有时需要将文件夹中的所有文件名整理在Excel表格中,方便管理和查阅。手动复制文件名既费时又易出错,因此本文将介绍两种利用Excel自动提取文件夹中所有文件名的方法,帮助你快速整理文件信息。 方法一࿱…...
YOLOv8改进,YOLOv8通过RFAConv卷积创新空间注意力和标准卷积,包括RFCAConv, RFCBAMConv,二次创新C2f结构,助力涨点
摘要 空间注意力已广泛应用于提升卷积神经网络(CNN)的性能,但它存在一定的局限性。作者提出了一个新的视角,认为空间注意力机制本质上解决了卷积核参数共享的问题。然而,空间注意力生成的注意力图信息对于大尺寸卷积核来说是不足够的。因此,提出了一种新型的注意力机制—…...
【实验11】卷积神经网络(2)-基于LeNet实现手写体数字识别
👉🏼目录👈🏼 🍒1. 数据 1.1 准备数据 1.2 数据预处理 🍒2. 模型构建 2.1 模型测试 2.2 测试网络运算速度 2.3 输出模型参数量 2.4 输出模型计算量 🍒3. 模型训练 🍒4.模…...
chatgpt训练需要什么样的gpu硬件
训练像ChatGPT这样的大型语言模型对GPU硬件提出了极高的要求,因为这类模型的训练过程涉及大量的计算和数据处理。以下是训练ChatGPT所需的GPU硬件的关键要素: ### 1. **高性能计算能力** - **Tensor Cores**: 现代深度学习训练依赖于Tensor Cores&#…...
Kubernetes常用命令
Kubernetes常用命令 一、集群管理 kubectl cluster-info:显示集群信息,包括控制平面地址和服务的 URL。 kubectl get nodes:查看集群中的节点列表,包括节点状态、IP 地址等信息。 kubectl describe node <node-name>&…...
Flutter:key的作用原理(LocalKey ,GlobalKey)
第一段代码实现的内容:创建了3个块,随机3个颜色,每次点击按钮时,把第一个块删除 import dart:math; import package:flutter/material.dart; import package:flutter_one/demo.dart;void main() {runApp(const App()); }class App…...
R语言基础入门详解
文章目录 R语言基础入门详解一、引言二、R语言环境搭建1、安装R和RStudio1.1、步骤1.2、获取工作目录 三、R语言基础2、语法基础2.1、赋值操作2.2、注释 3、数据类型与结构3.1、向量3.2、矩阵 4、基本操作4.1、数据读取4.2、数据可视化 四、R语言使用示例4.1、统计分析示例4.2、…...
django启动项目报错解决办法
在启动此项目报错: 类似于: django.core.exceptions.ImproperlyConfigured: Requested setting EMOJI_IMG_TAG, but settings are not c启动方式选择django方式启动,以普通python方式启动会报错 2. 这句话提供了对遇到的错误的一个重要线索…...
详细描述一下Elasticsearch搜索的过程?
大家好,我是锋哥。今天分享关于【详细描述一下Elasticsearch搜索的过程?】面试题。希望对大家有帮助; 详细描述一下Elasticsearch搜索的过程? Elasticsearch 的搜索过程是其核心功能之一,允许用户对存储在 Elasticsea…...
Spring、SpringMVC、SpringBoot、Mybatis小结
Spring Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架) Spring框架的核心特性包括依赖注入(Dependency Injection ,DI)、面向切面编程(Aspe…...
.NET 9 运行时中的新增功能
本文介绍了适用于 .NET 9 的 .NET 运行时中的新功能和性能改进。 文章目录 一、支持修剪的功能开关的属性模型二、UnsafeAccessorAttribute 支持泛型参数三、垃圾回收四、控制流实施技术.NET 安装搜索行为性能改进循环优化感应变量加宽Arm64 上的索引后寻址强度降低循环计数器可…...
Linux下安装mysql8.0版本
先确定我的下载安装的目录,安装文件是下载在 /opt/install 目录下面 (安装地址不同的话注意修改地址) 1.在线下载 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz2.解压 tar -xvf mysql-8.0.20-linux-glibc2.12-x86_64.t…...
kvm-dmesg:从宿主机窥探虚拟机内核dmesg日志
在虚拟化环境中,实时获取虚拟机内核日志对于系统管理员和开发者来说至关重要。传统的 dmesg 工具可以方便地查看本地系统的内核日志,但在KVM(基于内核的虚拟机)环境下,获取虚拟机内部的内核日志则复杂得多。为了简化这…...
植物明星大乱斗15
能帮到你的话,就给个赞吧 😘 文章目录 player.hplayer.cppparticle.hparticle.cpp player.h #pragma once #include <graphics.h> #include "vector2.h" #include "animation.h" #include "playerID.h" #include &…...
go-zero(三) 数据库操作
go-zero 数据库操作 在本篇文章中,我们将实现一个用户注册和登录的服务。我们将为此构建一个简单而高效的 API,包括请求参数和响应参数的定义。 一、Mysql连接 1. 创建数据库和表 在 MySQL 中创建名为 test_zero的数据库,并创建user 表 …...
SQL面试题——间隔连续问题
间隔连续问题 某游戏公司记录的用户每日登录数据如下 +----+----------+ | id| date| +----+----------+ |1001|2021-12-12| |1001|2021-12-13| |1001|2021-12-14| |1001|2021-12-16| |1001|2021-12-19| |1001|2021-12-20| |1002|2021-12-12| |1002|2021-12-16| |1002|…...
vim配置 --> 在创建的普通用户下
在目录/etc/ 下面,有个名为vimrc 的文件,这是系统中公共的vim配置文件对所有用户都有效 我们现在创建一个普通用户 dm 创建好以后,我们退出重新链接 再切换到普通用户下 再输入密码(是不显示的,输入完后,…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
