### Is there an existing issue for this?

- [X] I have searched the existing issues

### Enhancement description

Currently, I'm using Localstack to test locally a lambda function that takes s3`ObjectRestore:Completed` notifications as inputs and it would be really great to have support for these events.

I know that right now as a workaround I can invoke the lambda function manually using a payload with the same shape that s3 uses, but it's better to have the process run as close as it would run in AWS.

Thanks for creating and maintaining localstack, it's really great!

### 🧑‍💻 Implementation

Not sure, but happy to help if you can give me some pointers.

### Anything else?

_No response_
self, lifecycle_rules: LifecycleRules, moto_object, object_tags
    ) -> Expiration:
        """
        This method will check if the key matches a Lifecycle filter, and return the serializer header if that's
        the case. We're caching it because it can change depending on the set rules on the bucket.
        We can't use `lru_cache` as the parameters needs to be hashable
        :param lifecycle_rules: the bucket LifecycleRules
        :param moto_object: FakeKey from moto
        :param object_tags: the object tags
        :return: the Expiration header if there's a rule matching
        """
        if cached_exp := self._expiration_cache.get(moto_object.bucket_name, {}).get(
            moto_object.name
        ):
            return cached_exp
        if lifecycle_rule := get_lifecycle_rule_from_object(
            lifecycle_rules, moto_object, object_tags
        ):
            expiration_header = serialize_expiration_header(
                lifecycle_rule["ID"],
                lifecycle_rule["Expiration"],
                moto_object.last_modified,
            )
            self._expiration_cache[moto_object.bucket_name][moto_object.name] = expiration_header
            return expiration_header
    @handler("CreateBucket", expand=False)
    def create_bucket(