If you need to set multiple object prefixes and suffixes for an OSS trigger, or associate more than 10 triggers with a single OSS bucket, you can create an EventBridge-based OSS trigger to respond to events such as file uploads.
Usage notes
EventBridge OSS triggers are different from native OSS triggers. Note the following considerations.
A single bucket supports a maximum of 10 native OSS triggers. If you need to associate more than 10 triggers with a bucket, create an EventBridge-based OSS trigger.
NoteAs a best practice, avoid associating more than 10 triggers with a single bucket. If you need more triggers, consider creating a new bucket and its corresponding triggers.
You can create up to 50 EventBridge-based OSS triggers, which aligns with the resource limits of EventBridge. For more information, see Limitations.
For EventBridge-based OSS triggers, the combination of event type, object prefix, and object suffix does not need to be unique.
EventBridge-based OSS triggers support configuring multiple object prefixes and object suffixes. However, wildcard matching and regular expression matching are not supported for object prefixes and object suffixes.
The trigger takes about 30 seconds to become active. After this delay, OSS operations can trigger the function.
Use cases
You can configure an OSS trigger, setting the prefixes to source and test and the object suffixes to .rar and .zip in the trigger rule. When a compressed file is uploaded to the source or test directory in the specified OSS bucket and the object suffix is .rar or .zip, the function is automatically triggered. After the function is executed, the decompressed files are stored in another directory of the same bucket.
Prerequisites
EventBridge
Function Compute
Step 1: Create an EventBridge-based OSS trigger
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
On the function details page, click the Trigger tab and then click Create Trigger.
In the Trigger Type panel, select Object Storage Service (OSS) under Event triggers for Alibaba Cloud services for the Trigger Type parameter. Configure the other parameters and click OK.
Parameter
Actions
Example
Name
Enter a custom name for the trigger.
oss-trigger
Version or Alias
The default value is LATEST. If you want to create a trigger for a specific version or alias, you must first select the version or alias from the Version or Alias drop-down list on the function details page. For more information about versions and aliases, see Manage versions and Manage aliases.
LATEST
Bucket Name
Select an existing OSS bucket.
bucket-zh****
Object prefix
Enter the object prefix to match. Function Compute recommends configuring a prefix and a suffix to prevent recursive trigger invocations that can incur extra fees.
You can click + Add Object Prefix in the console to add multiple object prefixes.
ImportantAn object prefix cannot start with
/, or the OSS trigger cannot be triggered.source
test
Object suffix
Enter the object suffix to match. Function Compute recommends configuring a prefix and a suffix to prevent recursive trigger invocations that can incur extra fees.
In the console, you can click +Add Object Suffix to add multiple object suffixes.
png
Event type
Select one or more trigger events. For more information about the event types in Function Compute, see OSS event definitions.
oss:ObjectCreated:PutObject,oss:ObjectCreated:PostObject,oss:ObjectCreated:CompleteMultipartUploadEvent pattern content
This parameter is automatically populated after you specify the Object prefix, Object suffix, and Event type.
ImportantImportant: Modify the Event pattern content with caution. Incorrect modifications can cause the trigger to fail. Before modifying the pattern, ensure you understand its rules. For more information, see Event patterns.
{ "source":[ "acs.oss" ] }Invocation Method
Select the function invocation method. The default is synchronous invocation.
Sync Invocation: Function Compute triggers the function, waits for execution to complete, and then returns the result. This method is suitable for a wide range of use cases. For more information, see Synchronous invocations.
Async Invocation: Function Compute triggers the function and returns a response immediately. The function is executed at least once, but the execution result is not returned. This method is suitable for functions with long execution times. For more information, see Asynchronous invocations.
Sync Invocation
Trigger State
Specifies whether to enable the trigger immediately after it is created. By default, Enable trigger is selected.
N/A
Push format
Specifies the data format for the event passed as the function's input parameter.
CloudEvents: A specification that describes event data in a common format, including the event description and payload. It is designed to simplify event declaration and delivery across services and platforms.
Raw data: Delivers only the event payload and does not include other metadata from the CloudEvents format.
NoteUnlike EventBridge-based OSS triggers, the event parameter for a native OSS trigger supports only the OSS events template, which is the event format generated by Alibaba Cloud OSS.
CloudEvents
For information about advanced settings such as retry policies and dead-letter queues, see Advanced trigger features.
After the trigger is created, it is displayed on the Triggers tab. To modify or delete a trigger, see Trigger Management.
Step 2: Configure the function input parameters
EventBridge-based OSS triggers use the CloudEvents template to pass event data to functions as an input parameter. You can manually pass an event to the function to simulate a trigger event.
On the Code tab of the function details page, click the
icon next Test Function and select Configure Test Parameters from the drop-down list. In the Configure Test Parameters panel, on the Create New Test Event or Modify Existing Test Event tab, enter an event name and the event content, and then click OK.
The
eventis the input parameter for Function Compute. When a specified event occurs in the target OSS bucket, its data is passed to the function in JSON format. The following code shows an example of the event format.{ "datacontenttype": "application/json;charset=utf-8", "aliyunaccountid": "143199913****", "data": { "eventVersion": "1.0", "responseElements": { "requestId": "6364D216511B143733C5A67B" }, "eventSource": "acs:oss", "eventTime": "2023-11-04T08:49:26.000Z", "requestParameters": { "sourceIPAddress": "140.205.XX.XX" }, "eventName": "ObjectCreated:PutObject", "userIdentity": { "principalId": "143199913****" }, "region": "cn-hangzhou", "oss": { "bucket": { "name": "bucket-zh***", "arn": "acs:oss:cn-hangzhou:143199913****:bucket-zh***", "virtualBucket": "", "ownerIdentity": "143199913****" }, "ossSchemaVersion": "1.0", "object": { "size": 13, "objectMeta": { "mimeType": "text/plain" }, "deltaSize": 13, "eTag": "59CA0EFA9F5633CB0371BBC0355478D8", "key": "source/a.png" } } }, "subject": "acs:oss:cn-hangzhou:143199913****:bucket-zh***/source/a.png", "aliyunoriginalaccountid": "143199913****", "source": "acs.oss", "type": "oss:ObjectCreated:PutObject", "aliyunpublishtime": "203-11-04T08:49:26.745Z", "specversion": "1.0", "aliyuneventbusname": "default", "id": "6364D216511B143733C5A67B", "time": "2023-11-04T08:49:26Z", "aliyunregionid": "cn-hangzhou" }The following table describes the fields in the
eventparameter.Parameter
Type
Example value
Description
datacontenttype
String
application/json;charset=utf-8
The content type of the data parameter. The datacontenttype parameter supports only the application/json;charset=utf-8 format.
aliyunaccountid
String
143199913****
The ID of your Alibaba Cloud account. You can obtain your account ID from the References section of the Overview page in the Function Compute console.
data
{}
The content of the OSS event, which is a JSON object. CloudEvents encapsulate the original OSS event context within the data object.
subject
String
acs:oss:cn-hangzhou:143199913****:bucket-zh****/source/a.png
The subject of the event.
The format is
acs:oss:<region>:<your_account_id>:<your_bucket>. Replace<region>with the region that you selected when you created the function,<your_account_id>with your Alibaba Cloud account ID, and<your_bucket>with the name of a bucket that you have created in the same region.aliyunoriginalaccountid
String
143199913****
The ID of the Alibaba Cloud account that owns the event source.
source
String
acs.oss
Event source. For an OSS trigger, this is fixed to
acs.oss.type
String
oss:ObjectCreated:PutObject
The event type.
aliyunpublishtime
Timestamp
2023-11-04T08:49:26.745Z
The time when EventBridge received the event.
specversion
String
1.0
The version of the CloudEvents specification.
aliyuneventbusname
String
default
The name of the event bus that receives the event.
id
String
6364D216511B143733C5A67B
The event ID.
time
Timestamp
2023-11-04T08:49:26Z
The time when the event occurred at the source.
aliyunregionid
String
cn-hangzhou
The region where EventBridge received the event.
aliyunpublishaddr
String
140.205.XX.XX
The IP address of the server that received the event.
You need to modify the following fields in the
dataobject of theeventparameter based on your actual configuration.userIdentity.principalId: Set to your Alibaba Cloud account ID.region: Set to the region that you selected when you created the function.oss.bucket.name: Set this to the name of a bucket that you have created in the same region as the function.oss.bucket.arn: The format isacs:oss:<region>:<your_account_id>:<your_bucket>. You must replace<region>with the region where you created the function,<your_account_id>with your Alibaba Cloud account ID, and<your_bucket>with the name of an existing bucket in the same region.oss.bucket.ownerIdentity: Set to your Alibaba Cloud account ID.Set
object.keyto the path of an existing file in the target bucket.
ImportantWhen you simulate a trigger event by configuring the
eventparameter, ensure that the specified object (for example,source/a.png) exists in your bucket. Otherwise, the function invocation will fail.
Step 3: Write and test the function code
After you create the OSS trigger, you can write and test your function code to verify its correctness. When an actual OSS event occurs, the function is triggered automatically.
Warning: Avoid creating recursive invocations in your code to prevent unnecessary fees. Recursion occurs when a function, triggered by a file upload to an OSS bucket, writes a file back to the same bucket. This write operation re-triggers the function, creating a loop. For more information, see OSS trigger rules.
On the function details page, click the Code tab. Write your code in the code editor and then click Deploy.
The following sections provide preparations and sample code.
NoteIf your function needs to read from or write to OSS resources, use an internal OSS endpoint to avoid public network traffic charges. For more information about OSS endpoints, see Regions and endpoints.
/* Preparations: 1. Run the following commands in your terminal to install the package.json file and the jimp module for image processing. a. Run 'npm init' to create the package.json file. b. Run 'npm install jimp' to install the jimp module. 2. Make sure the function handler is set to index.handler. */ 'use strict'; console.log('Loading function ...'); var oss = require('ali-oss'); var fs = require('fs'); var jimp = require("jimp"); module.exports.handler = function (eventBuf, ctx, callback) { console.log('Received event:', eventBuf.toString()); var event = JSON.parse(eventBuf); var ossEvent = event.data; // The OSS region is prefixed with "oss-", for example, "oss-cn-shanghai". var ossRegion = "oss-" + ossEvent.region; // Create an OSS client. var client = new oss({ region: ossRegion, /* An AccessKey pair of an Alibaba Cloud account has permissions to access all APIs. We recommend that you use a RAM user to make API calls or perform routine O&M. Do not hardcode the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all your resources may be compromised. This example shows how to obtain the AccessKey ID and AccessKey secret from the context. */ accessKeyId: ctx.credentials.accessKeyId, accessKeySecret: ctx.credentials.accessKeySecret, stsToken: ctx.credentials.securityToken }); // Get the bucket name from the event. client.useBucket(ossEvent.oss.bucket.name); // The processed image is stored in the processed/ directory. var newKey = ossEvent.oss.object.key.replace("source/", "processed/"); var tmpFile = "/tmp/processed.png"; // Get the OSS object. console.log('Getting object: ', ossEvent.oss.object.key) client.get(ossEvent.oss.object.key).then(function (val) { // Read the OSS object content from the buffer. jimp.read(val.content, function (err, image) { if (err) { console.error("Failed to read image"); callback(err); return; } // Resize the image and save it to a temporary file. image.resize(128, 128).write(tmpFile, function (err) { if (err) { console.error("Failed to write image locally"); callback(err); return; } // Upload the processed file to the OSS bucket with a new key. console.log('Putting object: ', newKey); client.put(newKey, tmpFile).then(function (val) { console.log('Put object:', val); callback(null, val); return; }).catch(function (err) { console.error('Failed to put object: %j', err); callback(err); return }); }); }); }).catch(function (err) { console.error('Failed to get object: %j', err); callback(err); return }); };# Preparations: # 1. Make sure that the role configured for the function has permissions to access OSS. You can log on to the RAM console to grant the required permissions to the role. # 2. Make sure that the function handler is set to index.handler. # -*- coding: utf-8 -*- import oss2, json from wand.image import Image def handler(event, context): evt = json.loads(event) creds = context.credentials # Required by the OSS SDK. # An AccessKey pair of an Alibaba Cloud account has permissions to access all APIs. We recommend that you use a RAM user to make API calls or perform routine O&M. # Do not hardcode the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all your resources may be compromised. # This example shows how to obtain the AccessKey ID and AccessKey secret from the context. auth=oss2.StsAuth( creds.access_key_id, creds.access_key_secret, creds.security_token) evt = evt['data'] bucket_name = evt['oss']['bucket']['name'] endpoint = 'oss-' + evt['region'] + '-internal.aliyuncs.com' bucket = oss2.Bucket(auth, endpoint, bucket_name) objectName = evt['oss']['object']['key'] # Processed images are saved to the processed/ directory. newKey = objectName.replace("source/", "processed/") remote_stream = bucket.get_object(objectName) if not remote_stream: return remote_stream = remote_stream.read() with Image(blob=remote_stream) as img: with img.clone() as i: i.resize(128, 128) new_blob = i.make_blob() bucket.put_object(newKey, new_blob)/* Preparations: 1. Make sure that the role configured for the function has permissions to access OSS. You can log on to the RAM console to grant the required permissions to the role. 2. Make sure that the function handler is set to index.handler. */ <?php use OSS\OssClient; function handler($event, $context) { $event = json_decode($event, $assoc = true); /* An AccessKey pair of an Alibaba Cloud account has permissions to access all APIs. We recommend that you use a RAM user to make API calls or perform routine O&M. Do not hardcode the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all your resources may be compromised. This example shows how to obtain the AccessKey pair from the context. */ $accessKeyId = $context["credentials"]["accessKeyId"]; $accessKeySecret = $context["credentials"]["accessKeySecret"]; $securityToken = $context["credentials"]["securityToken"]; $evt = $event['data']; $bucketName = $evt['oss']['bucket']['name']; $endpoint = 'oss-' . $evt['region'] . '-internal.aliyuncs.com'; $objectName = $evt['oss']['object']['key']; $newKey = str_replace("source/", "processed/", $objectName); try { $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken); $content = $ossClient->getObject($bucketName , $objectName); if ($content == null || $content == "") { return; } $imagick = new Imagick(); $imagick->readImageBlob($content); $imagick->resizeImage(128, 128, Imagick::FILTER_LANCZOS, 1); $ossClient->putObject($bucketName, $newKey, $imagick->getImageBlob()); } catch (OssException $e) { print($e->getMessage()); } }/* Preparations: 1. Add the following dependencies to your pom.xml file. <dependencies> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-event</artifactId> <version>1.2.0</version> </dependency> </dependencies> 2. Make sure the function handler is set to example.App::handleRequest. */ package example; import java.io.*; import java.util.Map; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.fc.runtime.event.OSSEvent.Event; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; public class App implements StreamRequestHandler { private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); public static final class CloudEvent { public final String id; public final String source; public final String specversion; public final String type; public final String datacontenttype; public final String dataschema; public final String subject; public final String time; public final Map<String, ?> extensions; public final Event data; @JsonCreator public CloudEvent(@JsonProperty("id") String id, @JsonProperty("source") String source, @JsonProperty("specversion") String specversion, @JsonProperty("type") String type, @JsonProperty("datacontenttype") String datacontenttype, @JsonProperty("dataschema") String dataschema, @JsonProperty("subject") String subject, @JsonProperty("time") String time, @JsonProperty("extensions") Map<String, ?> extensions, @JsonProperty("data") Event data) { this.id = id; this.source = source; this.specversion = specversion; this.type = type; this.datacontenttype = datacontenttype; this.dataschema = dataschema; this.subject = subject; this.time = time; this.extensions = extensions; this.data = data; } public String getId() { return this.id; } public String getSource() { return this.source; } public String getSpecversion() { return this.specversion; } public String getType() { return this.type; } public String getDatacontenttype() { return this.datacontenttype; } public String getDataschema() { return this.dataschema; } public String getSubject() { return this.subject; } public String getTime() { return this.time; } public Map<String, ?> getExtensions() { return this.extensions; } public Event getData() { return this.data; } } @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { CloudEvent cloudEvents = mapper.readValue(inputStream, new TypeReference<CloudEvent>() {}); Event ossEvent = cloudEvents.getData(); context.getLogger().info(String.format("received %s from %s @ %s", ossEvent.eventName, ossEvent.eventSource, ossEvent.region)); outputStream.write(String.format("received %s from %s @ %s", ossEvent.eventName, ossEvent.eventSource, ossEvent.region).getBytes()); outputStream.write(String.format("received bucket %s", ossEvent.oss.bucket.arn).getBytes()); outputStream.write(String.format("received object %s and it's size is %s", ossEvent.oss.object.key, ossEvent.oss.object.size).getBytes()); } }Click Test Function.
After the execution is complete, you can view the results at the top of the Code tab.
FAQ
References
For a list of configurable OSS event types, see OSS event definitions.
To modify or delete a trigger, see Update a trigger configuration.
Trigger issues:
To determine which event triggered the function execution, you can print the event type log in your code. For more information, see Log record.
To call another function from within a function, you can use an API to call the specified function or use CloudFlow to orchestrate functions. If the called function needs to perform time-consuming operations and all calls are asynchronous, you can configure a destination service for asynchronous invocations. For more information, see Can functions call each other? and Configure a destination for an asynchronous invocation.