This page shows you how to create and deploy an event receiver service. The
target service receives HTTP requests containing the event in the
CloudEvents format.
Event providers (sources) can provide the following event types:
Your receiver service should send an HTTP 2xx
response to signal a successful event receipt to the router. The router treats
all other HTTP responses as delivery failures and will resend the event.
These libraries are open source and make it easier to transform your
HTTP request into a language-idiomatic CloudEvents object.
Sample receiver source code
Cloud Audit Logs
The sample code shows you how to read Cloud Storage events using
Cloud Audit Logs in a service deployed to Cloud Run.
Python
@app.route("/",methods=["POST"])defindex():# Create a CloudEvent object from the incoming requestevent=from_http(request.headers,request.data)# Gets the GCS bucket name from the CloudEvent# Example: "storage.googleapis.com/projects/_/buckets/my-bucket"bucket=event.get("subject")print(f"Detected change in Cloud Storage bucket: {bucket}")return(f"Detected change in Cloud Storage bucket: {bucket}",200)
Java
importio.cloudevents.CloudEvent;importio.cloudevents.rw.CloudEventRWException;importio.cloudevents.spring.http.CloudEventHttpUtils;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpStatus;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestHeader;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassEventController{@RequestMapping(value="/",method=RequestMethod.POST,consumes="application/json")publicResponseEntity<String>receiveMessage(@RequestBodyStringbody,@RequestHeaderHttpHeadersheaders){CloudEventevent;try{event=CloudEventHttpUtils.fromHttp(headers).withData(headers.getContentType().toString(),body.getBytes()).build();}catch(CloudEventRWExceptione){returnnewResponseEntity<>(e.getMessage(),HttpStatus.BAD_REQUEST);}StringceSubject=event.getSubject();Stringmsg="Detected change in Cloud Storage bucket: "+ceSubject;System.out.println(msg);returnnewResponseEntity<>(msg,HttpStatus.OK);}}
Node.js
constexpress=require('express');constapp=express();app.use(express.json());app.post('/',(req,res)=>{if(!req.header('ce-subject')){returnres.status(400).send('Bad Request: missing required header: ce-subject');}console.log(`Detected change in Cloud Storage bucket: ${req.header('ce-subject')}`);returnres.status(200).send(`Detected change in Cloud Storage bucket: ${req.header('ce-subject')}`);});module.exports=app;
Go
// Processes CloudEvents containing Cloud Audit Logs for Cloud Storagepackagemainimport("fmt""log""net/http""os"cloudevent"github.com/cloudevents/sdk-go/v2")// HelloEventsStorage receives and processes a Cloud Audit Log event with Cloud Storage data.funcHelloEventsStorage(whttp.ResponseWriter,r*http.Request){ifr.Method!=http.MethodPost{http.Error(w,"Expected HTTP POST request with CloudEvent payload",http.StatusMethodNotAllowed)return}event,err:=cloudevent.NewEventFromHTTPRequest(r)iferr!=nil{log.Printf("cloudevent.NewEventFromHTTPRequest: %v",err)http.Error(w,"Failed to create CloudEvent from request.",http.StatusBadRequest)return}s:=fmt.Sprintf("Detected change in Cloud Storage bucket: %s",event.Subject())fmt.Fprintln(w,s)}
importcom.example.cloudrun.eventpojos.PubSubBody;importjava.util.Base64;importjava.util.Map;importorg.apache.commons.lang3.StringUtils;importorg.springframework.http.HttpStatus;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestHeader;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassEventController{@RequestMapping(value="/",method=RequestMethod.POST)publicResponseEntity<String>receiveMessage(@RequestBodyPubSubBodybody,@RequestHeaderMap<String,String>headers){// Get PubSub message from request body.PubSubBody.PubSubMessagemessage=body.getMessage();if(message==null){Stringmsg="No Pub/Sub message received.";System.out.println(msg);returnnewResponseEntity<>(msg,HttpStatus.BAD_REQUEST);}Stringdata=message.getData();if(data==null||data.isEmpty()){Stringmsg="Invalid Pub/Sub message format.";System.out.println(msg);returnnewResponseEntity<>(msg,HttpStatus.BAD_REQUEST);}Stringname=!StringUtils.isEmpty(data)?newString(Base64.getDecoder().decode(data)):"World";StringceId=headers.getOrDefault("ce-id","");Stringmsg=String.format("Hello, %s! ID: %s",name,ceId);System.out.println(msg);returnnewResponseEntity<>(msg,HttpStatus.OK);}}
Node.js
constexpress=require('express');const{toMessagePublishedData,}=require('@google/events/cloud/pubsub/v1/MessagePublishedData');constapp=express();app.use(express.json());app.post('/',(req,res)=>{if(!req.body){consterrorMessage='no Pub/Sub message received';res.status(400).send(`Bad Request: ${errorMessage}`);console.log(`Bad Request: ${errorMessage}`);return;}if(!req.body.message){consterrorMessage='invalid Pub/Sub message format';res.status(400).send(`Bad Request: ${errorMessage}`);console.log(`Bad Request: ${errorMessage}`);return;}// Cast to MessagePublishedEvent for IDE autocompletionconstpubSubMessage=toMessagePublishedData(req.body);constname=pubSubMessage.message && pubSubMessage.message.data?Buffer.from(pubSubMessage.message.data,'base64').toString().trim():'World';constresult=`Hello, ${name}! ID: ${req.get('ce-id')||''}`;console.log(result);res.send(result);});module.exports=app;
Go
// Sample pubsub is a Cloud Run service which handles Pub/Sub messages.packagemainimport("encoding/json""fmt""log""net/http""os")// PubSubMessage is the payload of a Pub/Sub event.// See the documentation for more details:// https://cloud.google.com/pubsub/docs/reference/rest/v1/PubsubMessagetypePubSubMessagestruct{Messagestruct{Data[]byte`json:"data,omitempty"`IDstring`json:"id"`}`json:"message"`Subscriptionstring`json:"subscription"`}// HelloEventsPubSub receives and processes a Pub/Sub push message.funcHelloEventsPubSub(whttp.ResponseWriter,r*http.Request){varePubSubMessageiferr:=json.NewDecoder(r.Body).Decode(&e);err!=nil{http.Error(w,"Bad HTTP Request",http.StatusBadRequest)log.Printf("Bad HTTP Request: %v",http.StatusBadRequest)return}name:=string(e.Message.Data)ifname==""{name="World"}s:=fmt.Sprintf("Hello, %s! ID: %s",name,string(r.Header.Get("Ce-Id")))log.Printf(s)fmt.Fprintln(w,s)}
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-03-27 UTC."],[[["This page provides instructions on creating and deploying an event receiver service that can receive HTTP requests containing events in the CloudEvents format."],["Event providers can deliver events directly from a Google Cloud source or through Cloud Audit Logs."],["A successful event receipt is signaled by the receiver service sending an HTTP `2xx` response to the router, while any other response is treated as a failure."],["The CloudEvents SDK library, available in multiple languages, helps transform HTTP requests into language-specific CloudEvents objects."],["Sample code is provided for handling events from Cloud Storage via Cloud Audit Logs and Pub/Sub in services deployed to Cloud Run, with examples in Python, Java, Node.js, Go, and C#."]]],[]]