coze实践-处理飞书多维表格图片并重新存储
最近有个需要在飞书多维表格上统一管理图片模板,并使用coze工作流对图片模板进行一些处理,处理后需要再次上传回飞书多维表格中,做的过程中在全网好像还没看到全过程的教程,遂完成后上来写一个
获取飞书多维表格附件
前置条件:飞书有开通coze权限,上传附件的表格权限为可编辑(不懂的可以去看主页的另外一篇,有讲)
- 正常使用coze组件对表格数据进行获取
- 多维表格中有附件时获取到的内容是
"{配图\":
[
{\"file_token\":\"HGekbh1HioKhAdx1c7Y0Knwe\",
\"name\":\"image.png\",
\"size\":142520,
\"tmp_url\":\"https://open.feishu.cn/open-apis/drive/v1/medias/batch_get_tmp_download_url?file_tokens=HGekoKhAdx1aXGc7Y0Knwe\",
\"type\":\"image/png\",
\"url\":\"https://open.feishu.cn/open-apis/drive/v1/medias/HGekbh1Adx1aXGc7Y0Knwe/download\"
}
]
其中的字段url是后续获取图片的二进制数据的请求url
3. 在coze工作流中调用获取飞书鉴权token插件
4. 组件中需要传入在飞书中创建的应用的app_id和app_secret。可通过 https://open.feishu.cn/app 进入进行应用的创建
5. 节点正确调用后回tenant_access_token 字段,该字段用于请求多维表格中的图片数据,需要放入请求头中
上传图片到coze
- 由于coze提供的发送http请求的组件输出数据类型并没有bytes类型,会导致直接使用http请求组件发送请求获取的数据乱码,且coze在工作流中要读取外部图片也需要进行图片上传,获取到上传的file_id后才能处理图片,所以将获取飞书中的图片数据和将图片上传到coze中都写在同一个代码组件中
import requests_async
import base64
from io import BytesIO
async def main(args: Args) -> Output:
picture_url = args.params['picture_url']
tenant_access_token = args.params['tenant_access_token']
# 示例代码(需替换实际参数)
headers = {"Authorization": "Bearer {}".format(tenant_access_token)}
response = await requests_async.get(
picture_url,
headers=headers
)
binary_data = response.content
file_obj = BytesIO(binary_data)
file_obj.name = "generated_image.png" # 必须指定文件名后缀
files = {
"file": (file_obj.name, file_obj, "image/png")
}
headers = {"Authorization": "Bearer {}".format("pat_example")} # 需要填入实际的coze的token
upload_response = await requests_async.post(
"https://api.coze.cn/v1/files/upload",
headers=headers,
files= files
)
# 构建输出对象
ret: Output = {
"image": upload_response.json()
}
return ret
- coze的token在授权的个人访问令牌中获取
- 图片上传成功后会返回
coze工作流处理图片
- 返回数据中的id字段,就是后面调用coze工作流处理图片需要传入的file_id字段
- 由于coze直接调用处理图片的组件,只能传入图片url或人工手动上传图片,但是我需要的是自动的读取从飞书中获取的图片,并处理。所以我单独构建了一个处理图片的工作流,并将该工作流发布,发布后使用代码组件,通过api来访问该工作流,具体请求方式可以查看coze的官方文档
- 调用工作流的输入参数为:
“parameters” : { "input": "{\"file_id\": \"xxxxx\"}" }
- 工作流执行成功后会返回coze处理完成后的图片url
将处理后图片重新存入飞书多维表格
- 现在只剩下将处理完成后的图片上传到飞书就大功告成,在飞书多维表格中上传图片的流程和coze类型,也是需要先上传图片,再使用上传图片成功后返回的token,进行表行的添加
- 飞书要在多维表格中上传附件,首先需要获取该表格的token,如果不是知识库的表格,直接可以从url中获取,如果是知识库中的表格,需要发送请求进行获取,具体参考:https://open.feishu.cn/document/server-docs/docs/drive-v1/media/introduction
- 获取到表格token后,请求coze工作流返回的图片的url,能够获取到图片的二进制数据,将二进制数据上传到飞书中,通过调用 https://open.feishu.cn/open-apis/drive/v1/medias/upload_all 进行图片上传,注意这里发送请求的Content-Type需要是multipart/form-data,且需要用requests_toolbelt库进行自动识别,但是coze的代码节点中无法安装该库,所以手动构建
# 构建 multipart/form-data 数据
boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW"
body = (
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"file_name\"\r\n\r\n"
f"{picture_name}\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"parent_type\"\r\n\r\n"
f"bitable_image\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"parent_node\"\r\n\r\n"
f"PxB7bhGN0arSrZsQSACcNdmlnie\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"size\"\r\n\r\n"
f"{len(picture_data.content)}\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"file\"; filename=\"tiezi_picture.png\"\r\n"
f"Content-Type: image/png\r\n\r\n"
).encode() + picture_data.content + f"\r\n--{boundary}--\r\n".encode()
# 设置请求头
headers = {
'Authorization': f'Bearer {tenant_access_token}',
'Content-Type': f'multipart/form-data; boundary={boundary}'
}
response = await requests_async.post(url, headers=headers, data=body)
- 上传成功后会返回一个file_token
- 最后再使用正常的多维表格添加行组件,在构建添加的请求参数时,格式为
[
{"fields":
{"配图":
[
{"file_token": file_token}
]
},
"其他字段": 其他字段内容
}
]
参考文章: https://blog.csdn.net/ling913/article/details/146621384?spm=1001.2014.3001.5506
https://open.feishu.cn/document/server-docs/docs/drive-v1/media/upload_all?appId=cli_a88caa9ad022d00e
飞书的官方文档写的还是很不错的,非常清晰有不懂的可以直接去看官方文档