--- title: "Configure the Event function" url: https://docs.catalyst.zoho.com/en/tutorials/invoice-notifier/java/configure-function/ description: "Create an Event Driven Architecture to automate invoice updates from Zoho Books to Zoho Cliq using Event Functions and Catalyst Signals." last_updated: 2025-11-19T15:07:41Z service: All Services type: tutorial related_links: - name: "Event Functions" url: /en/serverless/help/functions/event-functions/ - name: "Functions Directory Structure" url: /en/cli/v1/project-directory-structure/functions-directory --- # Configure the Event Function Let us now configure the event function `Cliq_Notifier`, which automatically sends a message to a Zoho Cliq channel. This message will include the invoice details of new customers who have successfully completed their payment. The function will be executed when it is triggered by Catalyst Signals. The [functions directory](https://docs.catalyst.zoho.com/en/cli/v1/project-directory-structure/functions-directory), `functions/Cliq_Notifier` contains: - The `CliqNotifier.java` main function file - The `catalyst-config.json` configuration file - Java library files in the `lib` folder - `.classpath` and `.project` dependency files You will be adding code in `CliqNotifier.java` file. > **Note:** Please go through the code in this section to make sure you fully understand it. You can directly copy the code below and paste it in `CliqNotifier.java` located in the `functions/Cliq_Notifier` directory and save the file. **CliqNotifier.java** ```java import java.util.logging.Level; import java.util.logging.Logger; import java.util.Arrays; import java.io.IOException; import org.json.JSONObject; import org.json.JSONArray; import org.json.JSONException; import com.catalyst.Context; import com.catalyst.event.EVENT_STATUS; import com.catalyst.event.EventRequest; import com.catalyst.event.CatalystEventHandler; import com.zc.auth.connectors.ZCConnection; import okhttp3.OkHttpClient; import okhttp3.MediaType; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class CliqNotifier implements CatalystEventHandler { private static final Logger LOGGER = Logger.getLogger(CliqNotifier.class.getName()); private static final String ZBOOKSDOMAIN = "{{YOUR_ZBOOKS_DOMAIN}}"; //Enter your ZohoBooks Domain based on your region private static final String ZBOOKSORG = "{{YOUR_ZBOOKS_ORGANIZATION_ID}}"; //Enter your ZohoBooks Organization Id private static final String ZCLIQDOMAIN = "{{YOUR_ZCLIQ_DOMAIN}}"; //Enter your ZohoCliq Domain based on your region private static final String ZCLIQ_CHANNEL_UNIQUE_NAME = "{{YOUR_CHANNEL_UNIQUE_NAME}}"; //Enter the unique name of the channel where updates should be posted private static final String ZCLIQ_BOT_UNIQUE_NAME = "{{YOUR_BOT_UNIQUE_NAME}}"; //Enter the unique name of the bot that will post the messages private static final String ZACCOUNTSDOMAIN = "{{YOUR_ZACCOUNTS_DOMAIN}}"; //Enter your ZohoAccounts Domain based on your region @Override public EVENT_STATUS handleEvent(EventRequest event, Context context) throws Exception { try { JSONArray data = extractInvoiceData(event); JSONArray rows = transformInvoiceData(data); JSONObject requestBody = prepareCliqRequest(rows); String accessToken = getAccessToken(); sendToCliq(requestBody, accessToken); LOGGER.log(Level.INFO, "Message pushed to channel successfully"); return EVENT_STATUS.SUCCESS; } catch (Exception e) { LOGGER.log(Level.SEVERE, "An unexpected error occurred: ", e); return EVENT_STATUS.FAILURE; } } private JSONArray extractInvoiceData(EventRequest event) throws JSONException { JSONObject payload = (JSONObject) event.getRawData(); JSONArray data = payload.getJSONArray("data"); JSONArray rows = new JSONArray(); for (int i = 0; i < data.length(); i++) { JSONArray invoices = data.getJSONArray(i); for (int j = 0; j < invoices.length(); j++) { rows.put(invoices.getJSONObject(j)); } } return rows; } private JSONArray transformInvoiceData(JSONArray rows) throws JSONException { for (int i = 0; i < rows.length(); i++) { JSONObject row = rows.getJSONObject(i); String invoiceId = row.optString("Invoice Id"); row.put("Link", "https://" + ZBOOKSDOMAIN + "/app/" + ZBOOKSORG + "#/invoices/" + invoiceId); row.remove("Invoice Id"); } return rows; } private JSONObject prepareCliqRequest(JSONArray rows) throws JSONException { JSONArray headers = new JSONArray(Arrays.asList( "Customer", "Invoice Number", "Amount", "Paid On", "Link" )); JSONObject tableData = new JSONObject() .put("headers", headers) .put("rows", rows); JSONObject slide = new JSONObject() .put("type", "table") .put("data", tableData); return new JSONObject() .put("text", "Here are the invoices marked as Paid in the last hour:") .put("slides", new JSONArray().put(slide)); } @SuppressWarnings("unchecked") private String getAccessToken() throws Exception { org.json.simple.JSONObject authConfig = new org.json.simple.JSONObject(); org.json.simple.JSONObject connectorConfig = new org.json.simple.JSONObject(); authConfig.put("client_id", "{{YOUR_CLIENT_ID}}"); //Enter your Client ID authConfig.put("client_secret", "{{YOUR_CLIENT_SECRET}}"); //Enter your Client Secret authConfig.put("auth_url", "https://" + ZACCOUNTSDOMAIN + "/oauth/v2/auth"); authConfig.put("refresh_url", "https://" + ZACCOUNTSDOMAIN + "/oauth/v2/token"); authConfig.put("refresh_token", "{{YOUR_REFRESH_TOKEN}}"); //Enter your Refresh Token connectorConfig.put("CliqConnector", authConfig); return ZCConnection.getInstance(connectorConfig).getConnector("CliqConnector").getAccessToken(); } private void sendToCliq(JSONObject payload, String accessToken) throws IOException { String cliqUrl = "https://" + ZCLIQDOMAIN + "/api/v2/channelsbyname/" + ZCLIQ_CHANNEL_UNIQUE_NAME + "/message?bot_unique_name=" + ZCLIQ_BOT_UNIQUE_NAME; Request request = new Request.Builder() .url(cliqUrl) .addHeader("Authorization", "Zoho-oauthtoken " + accessToken) .addHeader("Content-Type", "application/json") .post(RequestBody.create(MediaType.parse("application/json"), payload.toString())) .build(); try (Response response = new OkHttpClient().newCall(request).execute()) { if (!response.isSuccessful()) { throw new IOException("Unexpected response from Cliq API: " + response.body().string()); } } } } ``` > **Note:** After you copy and paste the code into your function file, make sure to update the following placeholders with actual values, as indicated by the inline comments: - **Zoho Books Domain (line 27)**: Enter the domain corresponding to your [**Zoho Books**](https://www.zoho.com/in/books/) organization, based on your region. Example: books.zoho.com, books.zoho.eu, or books.zoho.in - **Zoho Books Organization ID (line 28)**: Provide the unique Organization ID of your Zoho Books account. - **Zoho Cliq Domain (line 30)**: Specify the domain of your [Zoho Cliq](https://www.zoho.com/cliq/) organization, based on your region. Example: cliq.zoho.com, cliq.zoho.eu - **Unique Name of your Zoho Cliq Channel (line 31)**: Enter the unique name of the [Zoho Cliq channel](https://help.zoho.com/portal/en/kb/zoho-cliq/user-guides/channels) where the paid invoice updates should be posted. - **Unique Name of your Zoho Cliq Bot (line 32)**: Provide the unique name of the [Zoho Cliq bot](https://www.zoho.com/cliq/help/platform/bots.html) that has been added to the above channel. - **Zoho Accounts Domain (line 34)**: Mention the [Zoho Accounts](https://www.accounts.zoho.com/) domain used to log into Catalyst, Zoho Books, and Zoho Cliq. Example: accounts.zoho.com, accounts.zoho.in - **Client ID (line 109)**: Paste the Client ID obtained during client registration in [Step 4](https://docs.catalyst.zoho.com/en/tutorials/invoice-notifier/nodejs/register-client/). - **Cient Secret (line 110)**: Paste the corresponding Client Secret generated in [Step 4](https://docs.catalyst.zoho.com/en/tutorials/invoice-notifier/java/register-client/). - **Refresh Token (line 113)**: Provide the Refresh Token you generated in [Step 5](https://docs.catalyst.zoho.com/en/tutorials/invoice-notifier/java/refresh-token/) using your API client tool. The Event function is now configured.