Azure函数从JSON内容生成文件 - Microsoft Graph API邮件生成

0 投票
2 回答
55 浏览
提问于 2025-04-14 16:32

我在写一个Azure函数时遇到了问题,这个函数需要接收一个blob输入(JSON格式),然后用这个JSON文件中的contentbyte列来创建一个文件。

JSON模板:

{
   "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('XXX.com')/messages('AQMkADAA3D%3D')/attachments",
   "value":[
      {
         "@odata.type":"#microsoft.graph.fileAttachment",
         "@odata.mediaContentType":"application/pdf",
         "id":"AQMkADA0NjA5YT",
         "lastModifiedDateTime":"2023-06-29T14:40:33Z",
         "name":"MISC.pdf",
         "contentType":"application/pdf",
         "size":314000,
         "isInline":false,
         "contentId":"5E2D20ED5265174C8C9DC1AD59FFA4outlook.com",
         "contentLocation":null,
"contentBytes":"JVBERi0xLjYNCiWAgYKDDQoxIDAgb2JqDQo8PCAvQ3JlYXRvciA8Pg0KL0NyZWF0aW9uRGF0ZSA8NDQzYTM[enter image description here](https://i.stack.imgur.com/WQJSz.png)y"
      }
   ]
}

Azure函数:

这里是图片描述

下面是我写的Azure函数:

import json
import base64
from base64 import *
import logging
import azure.functions as func

def main(req: func.HttpRequest,inputBlob: func.InputStream, outputBlob: func.Out[bytes]) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    try:
 
        with open(inputBlob.read(),encoding='utf-8-sig') as user_file:
            file_contents = user_file.read()
            contents = json.loads(file_contents)
            
        for file_contents in enumerate(contents.get("value")):
            outputBlob.set(base64.b64decode(content.get("contentBytes")))
        
        output = {"run":"success"}
        return json.dumps(output)
     except Exception as ex:
        logging.exception(ex)
        output =  {"run":"failure"}   
        return json.dumps(output)

下面是错误信息:

[Error]   [Errno 36] File name too long: b'{\r\n   "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users(\'fsdja@eadft.com\')/messages(\'AQMkADA0NjA5YTMyLWU4MDctNDZkMi04

2 个回答

0

谢谢你,Pavan。你的代码帮我找到了我犯的错误。下面是我更新后的代码,现在运行得很好。

contents = json.loads(inputBlob.read()) 
for index,content in enumerate(contents.get("value")):
   fname = content.get("name")
   cbyte = content.get("contentBytes")
   conv_cbyte= base64.b64decode(cbyte)
   outputBlob1.set(conv_cbyte) 
       

现在,我使用for循环是因为文件里有多个JSON内容。所以我们可能会有多个文件。在上面的例子中,由于我指定了输出文件的名字,所以它一直在覆盖Test.PDF这个文件。你能告诉我怎么用JSON里的名字来保存文件吗?

0

这个函数接收一个包含JSON格式的二进制数据(blob)的输入,然后利用JSON文件中的contentbyte列来创建一个文件。

  • “文件名太长”通常发生在你尝试创建一个文件名超过允许的最大长度时,确保文件名不要太长,并且不包含任何非法字符。

  • 我创建了一个使用Python的Http触发函数。我能够利用下面的输出绑定来创建一个包含内容字节的文件,并将其发送到存储容器:

函数代码:

import azure.functions as func
import logging
import base64

app = func.FunctionApp()

@app.route(route="http_trigger", methods=["POST"])
@app.blob_output(arg_name="output",
                path="pavan/pavan.pdf",
                connection="AzureWebJobsStorage")
def http_trigger(req: func.HttpRequest, output:func.Out[str]) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    try:
        req_body = req.get_json()
    except ValueError:
        return func.HttpResponse(
            "Invalid JSON input",
            status_code=400
        )

    if 'contentbyte' not in req_body:
        return func.HttpResponse(
            "Missing 'contentbyte' field in JSON",
            status_code=400
        )

    content_byte_base64 = req_body['contentbyte']

    # Decode base64 content byte
    try:
        content_bytes = base64.b64decode(content_byte_base64)
    except Exception as e:
        logging.error(f"Error decoding content byte: {str(e)}")
        return func.HttpResponse(
            "Error decoding content byte",
            status_code=500
        )

    # Decode content if it's encoded
    if 'encoding' in req_body and req_body['encoding'] == 'base64':
        try:
            content_bytes = base64.b64decode(content_bytes)
        except Exception as e:
            logging.error(f"Error decoding content: {str(e)}")
            return func.HttpResponse(
                "Error decoding content",
                status_code=500
            )

    # Write content to a file
    try:
        output.set(content_bytes)
    except Exception as e:
        logging.error(f"Error writing to file: {str(e)}")
        return func.HttpResponse(
            "Error writing to file",
            status_code=500
        )

    return func.HttpResponse(
        "File created successfully",
        status_code=200
    )

  • 我通过Postman发送了Microsoft Graph API的contentbyte,并成功创建了文件。请看下面:

这里输入图片描述

这里输入图片描述

输出文件成功发送到存储容器。请看下面:

输出:

这里输入图片描述

撰写回答