Lesson 3: Fire an Event
Fire Event
Once you set up the app and register the event provider, now you can make user click invoke
button as fire event, this lesson will walk through the code in publish-event
template, test it on the UI with "invoke" button and see the success response (in this lession using webhook)
You can choose to use this template code at /actions/publish-events/index.js
or create your own code.
Within the newly created app, Firstly, set up package.json
with the lists of dependencies, version, etc.
Then manifest.yml
lists the declaration of serverless actions including name, source files, runtime kind, default params, annotations, and so on. In this lesson, we will choose to use this template to modify the code to our need.
Note: here put in the providerId
,apiKey
and eventCode
from lesson 2 in the manifest.yml
and orgId
,accessToken
can be passed through headers
Below is a sample app.config.yaml
Copied to your clipboardapplication:actions: actionsweb: web-srcruntimeManifest:packages:my-app:license: Apache-2.0actions:generic:function: actions/generic/index.jsweb: 'yes'runtime: 'nodejs:18'inputs:LOG_LEVEL: debugannotations:require-adobe-auth: truefinal: truepublish-events:function: actions/publish-events/index.jsweb: 'yes'runtime: 'nodejs:18'inputs:LOG_LEVEL: debugapiKey: <Your-SERVICE_API_KEY>providerId: <YOUR-PROVIDER_ID>eventCode: <YOUR-EVENT_CODE>annotations:final: true
Now let's start to take a deeper look the template code:
- Source code is at
actions/publish-events/index.js
- It is a web action
- The action will be run in the
nodejs:18
runtime container on I/O Runtime - It has some default params such as
LOG_LEVEL
, you can pass in yourparams
likeapiKey
,provideId
andeventCode
frommanifest.yml
Copied to your clipboardconst { Core, Events } = require('@adobe/aio-sdk')const uuid = require('uuid')const { CloudEvent } = require('cloudevents')const { errorResponse, getBearerToken, stringParameters, checkMissingRequestInputs } = require('../utils')// main function that will be executed by Adobe I/O Runtimeasync function main (params) {// create a Loggerconst logger = Core.Logger('main', { level: params.LOG_LEVEL || 'info' })try {// 'info' is the default level if not setlogger.info('Calling the main action')// log parameters, only if params.LOG_LEVEL === 'debug'logger.debug(stringParameters(params))// check for missing request input parameters and headersconst requiredParams = ['apiKey', 'providerId', 'eventCode', 'payload']const requiredHeaders = ['Authorization', 'x-gw-ims-org-id']const errorMessage = checkMissingRequestInputs(params, requiredParams, requiredHeaders)if (errorMessage) {// return and log client errorsreturn errorResponse(400, errorMessage, logger)}// extract the user Bearer token from the Authorization headerconst token = getBearerToken(params)// initialize the clientconst orgId = params.__ow_headers['x-gw-ims-org-id']const eventsClient = await Events.init(orgId, params.apiKey, token)// Create cloud event for the given payloadconst cloudEvent = createCloudEvent(params.providerId, params.eventCode, params.payload)// Publish to I/O Eventsconst published = await eventsClient.publishEvent(cloudEvent)let statusCode = 200if (published === 'OK') {logger.info('Published successfully to I/O Events')} else if (published === undefined) {logger.info('Published to I/O Events but there were not interested registrations')statusCode = 204}const response = {statusCode: statusCode,}// log the response status codelogger.info(`${response.statusCode}: successful request`)return response} catch (error) {// log any server errorslogger.error(error)// return with 500return errorResponse(500, 'server error', logger)}}function createCloudEvent(providerId, eventCode, payload) {let cloudevent = new CloudEvent({specversion: "1.0",source: 'urn:uuid:' + providerId,type: eventCode,id: uuid.v4(),data: payload,})return cloudevent;}exports.main = main
What happens here is that the action exposes a main
function, which accepts a list of params from the client. It checks the required params for using the cloudevents-sdk
.
You can run the App Builder app locally by execute the below command with AIO CLI:
Copied to your clipboardaio app run
This command will deploy the publish-event
action into I/O Runtime, and spins up a local instance for the UI. When the app is up and running, it can be seen at https://localhost:9080
. You should be able to see the UI of the app and it is also possible to access the app from ExC Shell: https://experience.adobe.com/?devMode=true#/apps/?localDevUrl=https://localhost:9080
. You might be asked to log in using your Adobe ID. When the website is opened, the UI is almost similar to what you see when deployed on localhost, except the ExC Shell on top of the UI.
Once you are satisfied with your app, you can deploy your app by run below command:
Copied to your clipboardaio app deploy
This command will deploy the app to your namespace, you will get the URL like
https://<Runtime-namespace>.adobeio-static.net/<project-name>-0.0.1/index.html
and you will see your deployed link in the terminal
Next, let's see how the web UI communicates with the backend. In web-src/src/components
we already provide a template of UI.
After you select the actions to publish-events
and then click the invoke
button, it will invoke the action. In the action, it will send out the event. When you invoke, you could also add actual params, in this example, we add {"payload": "you got a like"}
, in the webhook result, you will see the payload showed in {"data": "you got a like"}
.
Note: Here I use the webhook tool here to generate a webhook link and put this webhook to the console integration. You can use other webhook tool as discussed in lession 4.