本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
您可以在函数计算控制台创建并配置原生OSS触发器,当在OSS上发生特定事件时会自动触发函数执行。这可以让您轻松响应如文件上传等事件,无需在代码中增加监听事件逻辑即可快速实现完整的流程。
示例场景
您可以配置一个OSS触发器,并将其文件前缀设置为source
。当有图片存入指定的OSS Bucket中的source
目录下,会自动触发函数执行。函数将图片进行缩放处理后存放到同一个Bucket的processed
目录下,即将source/a.png
处理为processed/a.png
。
前提条件
函数计算
对象存储OSS
使用限制
原生OSS触发器,一个Bucket最多支持关联10个触发器。
说明如果您需要在一个Bucket内,关联更多的OSS触发器,可以选择创建EventBridge类别的OSS触发器。通常情况下,不推荐一个Bucket关联10个以上的触发器。如需创建,建议您创建新的Bucket,并基于新的Bucket创建触发器。
原生OSS触发器和EventBridge类别的OSS触发器配置的文件前缀和文件后缀都不支持模糊匹配和正则匹配。如果想配置多个文件前缀和文件后缀,可使用EventBridge类别的OSS触发器。
步骤一:创建OSS触发器
登录函数计算控制台,在左侧导航栏,单击函数。
在顶部菜单栏,选择地域,然后在函数页面,单击目标函数。
在函数配置页面,选择配置页签,在左侧导航栏,单击触发器,然后单击创建触发器。
在创建触发器面板,填写相关信息,然后单击确定。
配置项
操作
本文示例
触发器类型
选择对象存储 OSS。
对象存储 OSS
名称
填写自定义的触发器名称。
oss-trigger
版本或别名
默认值为LATEST,如果您需要创建其他版本或别名的触发器,需先在函数详情页的版本或别名下拉列表选择该版本。关于版本和别名的简介,请参见管理版本和管理别名。
LATEST
Bucket 名称
选择已创建的OSS Bucket。
testbucket
文件前缀
输入要匹配的文件名称的前缀。建议您配置文件前缀和后缀,避免触发事件嵌套循环触发引起额外费用。此外,一个Bucket的不同触发器如果指定了相同的事件类型,则前缀和后缀不能重复。详细信息,请参见原生OSS触发器触发规则。
重要文件前缀不能以
/
开头,否则会导致OSS触发器无法被触发。source
文件后缀
输入要匹配的文件名称的后缀。强烈建议您配置前缀和后缀,避免触发事件嵌套循环触发引起额外费用。另外,一个Bucket的不同触发器如果指定了相同的事件类型,则前缀和后缀不能重复。详细信息,请参见OSS触发器触发规则。
png
触发事件
选择一个或多个触发事件。关于对象存储OSS的事件类型,请参见OSS事件定义。
本示例选择oss:ObjectCreated:PutObject。
oss:ObjectCreated:PutObject
,oss:ObjectCreated:PostObject
,oss:ObjectCreated:CompleteMultipartUpload
角色名称
选择AliyunOSSEventNotificationRole。
说明如果您第一次创建该类型的触发器,则需要在单击确定后,在弹出的对话框中选择立即授权。
AliyunOSSEventNotificationRole
创建完成后,在触发器名称列表中显示已创建的触发器。如需对创建的触发器进行修改或删除,具体操作,请参见触发器管理。
步骤二:配置函数入口参数
OSS事件源会以event的形式作为输入参数传递给函数,您可以手动将event传给函数模拟触发事件。
在函数配置页面的代码页签,单击测试函数右侧的图标,从下拉列表中,选择配置测试参数。
在配置测试参数面板,选择创建新测试事件或编辑已有测试事件,填写事件名称和事件内容,然后单击确定。
说明event内容请根据创建触发器时的信息进行配置,同时需要确保配置的Bucket中存在指定的文件(本文示例中是
source/a.png
文件),否则会无法触发函数执行,或者函数执行会失败。event是函数计算的入口参数,当指定的OSS Bucket发生对象创建或对象删除事件时,会将事件数据以JSON格式发送给绑定的函数。具体格式如下所示。
{ "events": [ { "eventName": "ObjectCreated:PutObject", "eventSource": "acs:oss", "eventTime": "2022-08-13T06:45:43.000Z", "eventVersion": "1.0", "oss": { "bucket": { "arn": "acs:oss:cn-hangzhou:123456789:testbucket", "name": "testbucket", "ownerIdentity": "164901546557****" }, "object": { "deltaSize": 122539, "eTag": "688A7BF4F233DC9C88A80BF985AB****", "key": "source/a.png", "size": 122539 }, "ossSchemaVersion": "1.0", "ruleId": "9adac8e253828f4f7c0466d941fa3db81161****" }, "region": "cn-hangzhou", "requestParameters": { "sourceIPAddress": "140.205.XX.XX" }, "responseElements": { "requestId": "58F9FF2D3DF792092E12044C" }, "userIdentity": { "principalId": "164901546557****" } } ] }
event参数中不同属性字段的解释如下表所示。
参数
类型
示例值
描述
eventName
String
ObjectCreated:PutObject
事件类型。
eventSource
String
acs:oss
事件源,固定为
acs:oss
。eventTime
String
2022-08-13T06:45:43.000Z
事件产生的时间。使用ISO-8601标准时间格式。
eventVersion
String
1.0
事件协议的版本。
oss
Map
OSS事件内容。
bucket
Map
bucket参数内容。
name
String
testbucket
Bucket的名称。
arn
String
acs:oss:cn-hangzhou:123456789:testbucket
Bucket的唯一标识符。
ownerIdentity
String
164901546557****
创建Bucket的用户ID。
object
Map
object参数内容。
size
Int
122539
object的大小。单位:Byte。
deltaSize
Int
122539
object的大小变化量。单位:Byte。
如果新增一个文件,此参数的值表示文件大小。
如果同名覆盖一个文件,此参数的值表示新文件与旧文件的大小差值。
eTag
String
688A7BF4F233DC9C88A80BF985AB****
Object的标签。
key
String
source/a.png
Object的名称。
ossSchemaVersion
String
1.0
OSS模式的版本号。
ruleId
String
9adac8e253828f4f7c0466d941fa3db81161****
事件匹配的规则ID。
region
String
cn-hangzhou
Bucket所在的地域。
requestParameters
Map
请求参数。
sourceIPAddress
String
140.205.XX.XX
请求的源IP地址。
responseElements
Map
响应元素。
requestId
String
58F9FF2D3DF792092E12044C
请求对应的Request ID。
userIdentity
Map
用户属性。
principalId
String
164901546557****
请求发起者的阿里云账号ID。
步骤三:编写函数代码并测试
OSS触发器创建完成后,您可以开始编写函数代码并测试,以验证代码的正确性。在实际操作过程中,发生OSS事件时,函数会自动被触发执行。
代码中一定要避免循环触发。一个典型的循环触发场景是OSS的某个Bucket上传文件事件触发函数执行,此函数执行完成后又生成了一个或多个文件再写回到OSS的Bucket里,这个写入动作又触发了函数执行,形成了链状循环。更多信息,请参见原生OSS触发器触发规则。
在函数配置页面的代码页签,在代码编辑器中编写代码,然后单击部署代码。
支持在线编辑代码的运行环境的示例代码如下。
说明如果您要在您的函数中读写OSS资源,建议使用OSS内网服务地址进行访问,避免使用公网访问,产生公网费用。关于OSS内网服务地址的格式,请参见访问域名和数据中心。
"use strict"; /* 本代码样例主要实现以下功能: * 1. 从event中解析出OSS事件触发相关信息。 * 2. 根据以上获取的信息,初始化OSS客户端。 * 3. 将源图片resize后持久化到OSS bucket下指定的目标图片路径,从而实现图片备份。 This code sample mainly implements the following functions: * 1. Parse the OSS event trigger related information from the event. * 2. According to the above information, initialize the OSS client. * 3. Resize the source image and then store the processed image into the same bucket's copy folder to backup the image. */ const OSS = require("ali-oss"); exports.handler = async function(event, context, callback) { console.log("The content in context entity is: \n"); console.dir(context); const {accessKeyId, accessKeySecret, securityToken} = context.credentials; const events = JSON.parse(event.toString()).events; console.log("The content in event entity is: \n"); console.dir(events); let objectName = events[0].oss.object.key; let region = events[0].region; let bucketName = events[0].oss.bucket.name; // 连接目标OSS。 // Connect to the target OSS const client = new OSS({ region: region, accessKeyId: accessKeyId, accessKeySecret: accessKeySecret, stsToken: securityToken, bucket: bucketName, endpoint: "https://oss-" + region + "-internal.aliyuncs.com" }); console.log("The client entity is: \n"); console.dir(events); const targetImage = objectName.replace("source/", "processed/") // 将图片缩放为固定宽高128 px。 const processStr = "image/resize,m_fixed,w_128,h_128" // 将源图片resize后再存储到目标图片路径。 const result = await client.processObjectSave( objectName, targetImage, processStr, bucketName ); console.log(result.res.status); callback(null, "done"); }
""" 本代码样例主要实现以下功能: * 从event中解析出OSS事件触发相关信息。 * 根据以上获取的信息,初始化OSS bucket客户端。 * 将源图片resize后持久化到OSS bucket下指定的目标图片路径,从而实现图片备份。 This sample code is mainly doing the following things: * Get OSS processing related information from event. * Initiate OSS client with target bucket. * Resize the source image and then store the processed image into the same bucket's copy folder to backup the image. """ # -*- coding: utf-8 -*- import oss2, json import base64 def handler(event, context): # 可以通过context.credentials获取密钥信息。 # Access keys can be fetched through context.credentials print("The content in context entity is: \n") print(context) creds = context.credentials # 设置权鉴,供OSS sdk使用。 # Setup auth, required by OSS sdk. auth = oss2.StsAuth( creds.access_key_id, creds.access_key_secret, creds.security_token) print("The content in event entity is: \n") print(event) # Load event content. oss_raw_data = json.loads(event) # Get oss event related parameters passed by oss trigger. oss_info_map = oss_raw_data['events'][0]['oss'] # Get oss bucket name. bucket_name = oss_info_map['bucket']['name'] # Set oss service endpoint. endpoint = 'oss-' + oss_raw_data['events'][0]['region'] + '-internal.aliyuncs.com' # Initiate oss client. bucket = oss2.Bucket(auth, endpoint, bucket_name) object_name = oss_info_map['object']['key'] # Download original image from oss bucket. remote_stream = bucket.get_object(object_name) if not remote_stream: print(f'{object_name} does not exist in bucket {bucket_name}') return # Processed images will be saved to processed/ processed_path = object_name.replace('source/', 'processed/') # 将图片缩放为固定宽高128 px。 style = 'image/resize,m_fixed,w_128,h_128' # 指定处理后图片名称。如果图片不在Bucket根目录,需携带文件完整访问路径,例如exampledir/example.jpg。 process = "{0}|sys/saveas,o_{1},b_{2}".format(style, oss2.compat.to_string(base64.urlsafe_b64encode(oss2.compat.to_bytes(processed_path))), oss2.compat.to_string(base64.urlsafe_b64encode(oss2.compat.to_bytes(bucket_name)))) result = bucket.process_object(object_name, process) print(result)
/*本代码样例主要实现以下功能: * 1. 从request中解析出 endpoint,bucket,object。 * 2. 根据以上获取的信息,初始化OSS客户端。 * 3. 将源图片resize后持久化到OSS bucket下指定的目标图片路径,从而实现图片备份。 * *This code sample mainly implements the following functions: * 1. Parse out endpoint, bucket, object from request. * 2. According to the information obtained above, initialize the OSS client. * 3. Resize the source image and then store the processed image into the same bucket's copy folder to backup the image. */ <?php use RingCentral\Psr7\Response; use OSS\OssClient; use OSS\Core\OssException; function base64url_encode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } function handler($event, $context) { $event = json_decode($event, $assoc = true); /* 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。 建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。 本示例以从上下文中获取AccessKey/AccessSecretKey为例。 */ $accessKeyId = $context["credentials"]["accessKeyId"]; $accessKeySecret = $context["credentials"]["accessKeySecret"]; $securityToken = $context["credentials"]["securityToken"]; $evt = $event['events']{0}; $bucketName = $evt['oss']['bucket']['name']; $endpoint = 'oss-' . $evt['region'] . '-internal.aliyuncs.com'; $objectName = $evt['oss']['object']['key']; $targetObject = str_replace("source/", "processed/", $objectName); try { // 连接OSS。 // Connect to OSS. $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken); // 将图片缩放为固定宽高128px。 $style = "image/resize,m_fixed,w_128,h_128"; $process = $style. '|sys/saveas'. ',o_'.base64url_encode($targetObject). ',b_'.base64url_encode($bucketName); // 将图片 Resize 后保存到目标文件中。 $result = $ossClient->processObject($bucketName, $objectName, $process); // 打印处理结果。 print($result); } catch (OssException $e) { print_r(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); } print(__FUNCTION__ . ": OK" . "\n"); return $targetObject; }
不支持在线编辑代码的运行环境的示例代码如下。
单击测试函数。
执行完成后,您可以在代码页签的上方查看执行结果。
常见问题
相关文档
如果您想了解可以配置的OSS事件类型,请参见OSS事件定义。
如果您需要对创建的触发器进行修改或删除,具体操作请参见更新触发器配置。
如果您需要在一个Bucket内关联10个以上的OSS触发器,请参见配置EventBridge类别的OSS触发器。
触发器相关问题
如果您希望查看函数的执行触发了哪个事件,可以手动在代码逻辑中打印事件类型日志,具体请参见日志记录。
如果您希望在函数中调用另一个函数,可以使用API调用指定函数或使用函数工作流编排函数。如果调用的函数需要执行耗时操作且均为异步调用,可以配置异步调用目标服务。具体请参见函数可以相互调用吗?和配置异步调用目标服务。