How to Automate Leave Approvals with Lark AnyCross

0
4

How to Automate Leave Approvals with Lark AnyCross

Most leave processes break in the same place. The manager approves the request, the decision lands in a chat notification, and then somebody has to remember to open the spreadsheet and change a cell. When they forget, or type the wrong thing, the database and reality quietly drift apart.

This guide closes that loop. Lark Base holds the data, Lark Approval makes the decision, and AnyCross wires them together so the record updates itself the moment a manager taps Approve or Reject. Nobody touches the database by hand.

It is a long build, but every piece is configuration rather than code. Set aside an afternoon.

What You Are Building

Two AnyCross workflows do the work.

Workflow 1 fires when someone submits the leave form. It logs the request in Lark Base as Pending, notifies the manager, formats the data, creates a formal approval instance, then writes the approval’s unique ID back onto the Base record so the two systems are linked.

AnyCross workflow with webhook trigger, Lark Base, Lark Message, JSON Helper, Lark Approval and Lark Base nodes in sequence

Workflow 2 fires when the approval status changes. It uses that stored Approval ID to find the right record, then branches on the decision and writes Approve or Reject into the Status column.

AnyCross workflow with Lark Approval trigger, Lark Base search, and a branch splitting into approve and reject paths

Important: Use an administrator account throughout. Standard accounts hit permission walls at the Developer Console and Admin Console steps, and you will not be able to finish.

Part 1: Build the Lark Base

Create the table

Create a base and set up a table with these fields.

Leave request table header in Lark Base showing name, dates, reason, status, respondents and approval ID columns

  • No: Serial number for indexing.
  • Name: The employee requesting leave.
  • Leave start date and Leave end date: The leave period.
  • Reason: Why the leave is being taken.
  • Status: A single option field holding Pending, Approve or Reject.
  • Respondents: The applicant’s user profile, captured for identity verification.
  • Submitted on: Timestamp of the submission.
  • Approval ID: The code that links this record to its approval instance.

The Status options matter more than they look. Whatever you type here has to be matched character for character later in AnyCross.

Status field options list in Lark Base showing Approve, Reject and Pending

 

Create the form

Add a form view collecting Name, Leave start date, Leave end date and Reason. This is what employees actually see.

Leave Request Form in Lark Base with name, start date, end date and reason fields above a submit button

Add the Base workflow

The base needs to tell AnyCross when a request arrives. Create a workflow with two nodes.

Two-node Lark Base workflow with a new record trigger followed by an HTTP request node

For the trigger, choose When a new record is added, select your table, and pick the Reason field. Then set two conditions: Reason is not empty, and Status is Pending.

Lark Base trigger configuration with Reason selected and conditions requiring Reason not empty and Status is Pending

For the second node, choose HTTP request:

  • Method: POST.
  • URL: your AnyCross webhook callback URL. You do not have this yet, so leave it blank and come back after Part 4.
  • Headers: Content-type set to application/json.
  • Request body: JSON format, mapping Name, start_date, end_date, Reason and Status to the record’s fields.
  • Response body: None.

HTTP request node in Lark Base configured as POST with JSON headers and a mapped request body

Note: The field names you use in the request body become the variable names in AnyCross. Keep them exactly as shown and the rest of the guide will line up.

Part 2: Create the Custom App

AnyCross needs an app identity to act on your behalf. Skip this part if you already have a suitable custom app.

Go to the Lark Developer platform, open the Developer Console, and click Create Custom App.

Lark Developer platform with the Developer Console link and Create Custom App button highlighted

Give it a name and description, pick an icon, then click Create.

Create custom app dialog in Lark with name, description and icon selection

On the app dashboard, click Create Version in the banner at the top.

Lark app dashboard with the Create Version button highlighted in the notification banner

Enter a version number such as 1.0.0, add update notes, and click Save.

Version details page in the Lark Developer Console with app version, update notes and save button

Submit the release request. Depending on your organisation’s policy this either goes to an administrator for review or clears immediately, after which you click Publish.

Version details page in Lark showing no approval required with the Publish button highlighted

Part 3: Create the Approval Form

In the Lark Admin Console, create a new approval.

Set the name to Leave Request and make it visible to everyone under Basic Info.

Basic Info tab of a Lark approval with the name set to Leave Request and visibility set to all

Under Form Design, drag in widgets for Name, Start Date, End Date and Reason. You can add more, but every widget you add here must have a matching field in your Lark Base.

Form Design tab in Lark approval with name, start date, end date and reason widgets on the form preview

Under Process Design, select the approval node and set the approver. For a live deployment choose Manager. For testing on your own account, choose Requester so the request comes back to you.

Process Design tab in Lark approval with the approval node selected and approver options displayed

Find your approval definition code

You will need this shortly. Open the approval in the Admin Console and look at the browser address bar. The definitionCode parameter at the end of the URL is the value to copy.

Browser address bar showing a Lark approval admin URL with the definitionCode parameter highlighted

Part 4: AnyCross Workflow 1, the Approval Request

Node 1: Webhook trigger

Go to Integration, create a workflow called Approval Request, and select Webhook Trigger.

Create workflow dialog in AnyCross with the workflow named Approval Request and Webhook Trigger selected

On the Trigger tab, choose Asynchronous URL trigger.

Webhook trigger configuration in AnyCross with Asynchronous URL trigger selected

Switch to Settings, copy the Callback URL, and set the request body type to JSON. Paste that URL into the HTTP request node you left blank in Part 1.

Settings tab of an AnyCross webhook trigger with the callback URL copy button and JSON request body type

Important: Note the Authentication method and IP allowlist fields on this screen. By default the endpoint is unauthenticated, which means anyone holding the URL can post data into your base. Treat the callback URL as a secret, and consider adding an IP allowlist before you go live.

Node 2: Lark Base, search records

Add a Lark Base node and choose Search records.

Action list for the Lark Base connector in AnyCross with Search records selected

On the Auth tab, click + Create authentication.

Auth tab in an AnyCross node with the Create authentication option highlighted below existing connections

Name the connection, choose the Enhanced authentication version, set the type to Lark Tenant Authorization, pick the custom app you published in Part 2, then click Create and Connect.

Create authentication dialog in AnyCross with Enhanced version and Lark Tenant Authorization selected

On the Input tab, configure:

  • Base and Table id: your leave request base and table.
  • User ID categories: open_id.
  • Page size: 1.
  • Sorting conditions: field name No, descending order true. This grabs the newest record.
  • Filter: Status is Pending.

Input configuration for the AnyCross search records node with sorting by No descending and a Pending status filter

Tip: The filter value has to match your Base field option exactly. “Pending” and “pending” are different strings as far as this node is concerned.

Node 3: Lark Message, notify the manager (optional)

This node is not required for the loop to work, but it is what makes the system usable day to day.

Add a Lark Message node and choose Send common message.

Lark Message action list in AnyCross with Send common message selected

On the Auth tab, select the authentication you just created.

Auth tab of the Lark Message node in AnyCross with a connected authentication selected

In the Input configuration, write your message content and set the Receiver ID to the manager. Include a record link built from the record_id variable so the manager can jump straight to the entry.

Message content field in AnyCross combining request details with a record link and the record ID variable

The record_id variable comes from the search records node’s output.

Selecting the record ID variable from the Lark Base node output inside an AnyCross message field

Node 4: JSON Helper

The approval connector expects the form data in a specific shape. Add a JSON Helper node and choose JSON Parse.

JSON Helper action list in AnyCross with JSON Parse selected

Paste your payload into the JSON String field.

JSON String input field in the AnyCross JSON Helper node containing a widget ID payload

[
  {
    "id": "widget17688764968610001",
    "type": "input",
    "value": "{{webhook-trigger-1.body.Name}}"
  },
  {
    "id": "widget17688921455010001",
    "type": "date",
    "value": "{{webhook-trigger-1.body.start_date}}T00:00:00+08:00"
  },
  {
    "id": "widget17688921469730001",
    "type": "date",
    "value": "{{webhook-trigger-1.body.end_date}}T00:00:00+08:00"
  },
  {
    "id": "widget17688765169960001",
    "type": "input",
    "value": "{{webhook-trigger-1.body.Reason}}"
  }
]

Each object maps one approval form widget to one value from the webhook. Replace the widget IDs with your own, and note the timezone suffix on the date fields. Without T00:00:00+08:00 the approval system will reject the date.

Node 5: Lark Approval, create instance

Add a Lark Approval node and choose Create approval instance.

Lark Approval action list in AnyCross with Create approval instance selected

On the Input tab, paste your Approval definition code from Part 3 and set the Unique open ID of user to the applicant.

Input tab of the Lark Approval node in AnyCross with approval definition code and user open ID fields

Then fill the JSON array, control value field. This is the same payload as the JSON Helper step, but written as a concatenated expression rather than plain JSON.

JSON array control value field in AnyCross combining widget IDs with webhook variables

"[{\"id\":\"widget17688764968610001\",\"type\":\"input\",\"value\":\""+_("$.webhook-trigger-1.body.Name")+"\"},{\"id\":\"widget17688921455010001\",\"type\":\"date\",\"value\":\""+_("$.webhook-trigger-1.body.start_date")+"T00:00:00+08:00"+"\"},{\"id\":\"widget17688921469730001\",\"type\":\"date\",\"value\":\""+_("$.webhook-trigger-1.body.end_date")+"T00:00:00+08:00"+"\"},{\"id\":\"widget17688765169960001\",\"type\":\"input\",\"value\":\""+_("$.webhook-trigger-1.body.Reason")+"\"}]"

Node 6: Lark Base, update record

The final node closes the link between the two systems. Add a Lark Base node and choose Update a record.

Lark Base action list in AnyCross with Update a record selected

Select your Base and Table, then map Record ID to the record_id variable from the search step.

Mapping the record ID variable from the search node into the update record node in AnyCross

Under Fields, map the Approval ID column to the instance_code variable produced by the approval node.

Mapping the approval instance code variable into the Approval ID field of a Lark Base record

Update record input in AnyCross with the Approval ID field mapped to the instance code variable

Important: This step is what makes Workflow 2 possible. Without the instance code stored on the record, the second workflow has no way to find which row a decision belongs to.

Click Done, then Publish.

Finding Widget IDs and open_id

Two values in Part 4 come from outside the AnyCross interface.

Widget IDs

Every field on a Lark approval form has an internal widget ID, in the format widget followed by a long number. These are specific to your form, so the IDs in the sample payload above will not work in your build.

The reliable way to retrieve them is the approval definition API. Call Get approval definition with your approval definition code, and the response returns the form structure with each widget’s ID and type. You can run this from the API Explorer in the Developer Console without writing any code, using the custom app you published in Part 2.

Note: Map every widget in the order the fields appear on your approval form, and match the type value to the widget type. An input widget declared as a date, or the reverse, will fail silently.

The user’s open_id

An open_id looks like ou_ followed by a long hexadecimal string, and identifies one user within one organisation.

The easiest route is inside AnyCross itself. In the Lark Message node you configured in Node 3, the Receiver ID field lets you pick a person by name and resolves them to their open_id automatically, with Receiver ID type showing open_id underneath. Selecting a person there and reading back the resolved value avoids looking it up manually.

If you need it outside that context, the Developer Console’s API Explorer can return a user’s open_id from their email address or phone number.

Part 5: AnyCross Workflow 2, the Approval Status

Node 1: Lark Approval trigger

Create a second workflow called Approval Status and select Lark Approval as the trigger application.

Create workflow dialog in AnyCross with Lark Approval chosen as the trigger application

Choose the Approval instance status changed event.

Trigger event list in AnyCross with Approval instance status changed selected

On the Settings tab, paste your approval definition code and set Accept Instance Status to PENDING, APPROVED and REJECTED so the workflow catches every stage.

Settings tab of the Lark Approval trigger in AnyCross with definition code and accepted instance statuses

Node 2: Lark Base, search records

Add a Lark Base node with the Search records action. Select your Base and Table, then set the filter so Approval ID equals the instance_code variable from the trigger.

Filter configuration in AnyCross matching the Approval ID field to the instance code variable

This is the reverse of what Workflow 1 did. Workflow 1 wrote the instance code onto the record; Workflow 2 uses it to find the record again.

Node 3: Branch

Add a Branch node. Branches are mutually exclusive and evaluated left to right.

Branch action selection in AnyCross showing Branch and Broadcasting options

Create two conditions: one named If Approve where the value equals APPROVED, and one named If Reject where it equals REJECTED.

Branch conditions in AnyCross with an If Approve path for APPROVED and an If Reject path for REJECTED

For each condition, set the left value to the status variable from the approval trigger and the right value to the literal text.

Operator condition dialog in AnyCross with the approval status variable set to equal APPROVED

The status variable sits under the event message body in the trigger’s output.

Variable picker in AnyCross showing the approval status field within the event message body

Important: APPROVED and REJECTED must be in capitals. Lark sends the status in upper case, and a lower-case comparison will never match, so the workflow silently does nothing.

Node 4: Update the record on each branch

On the If Approve branch, add a Lark Base Update a record node. Map Record ID to the record_id variable and set the Status field to Approve.

Update record node in AnyCross setting the Status field to Approve on the approve branch

Repeat on the If Reject branch, setting Status to Reject.

Update record node in AnyCross setting the Status field to Reject on the reject branch

Tip: Notice the asymmetry. The branch compares against APPROVED in capitals, because that is what Lark Approval sends. The value written into Base is Approve, because that is what your Status field option says. Getting these the wrong way round is the single most common reason this build fails.

Click Done, then Publish.

How It Works End to End

An employee fills in the form and submits.

Completed Leave Request Form in Lark with name, dates and reason entered before submission

Within seconds the record appears in Lark Base with a Pending status and an Approval ID already populated, confirming the approval instance was created and linked.

Lark Base record showing a pending leave request with an automatically generated approval ID

The bot notifies the approver with a link straight to the record.

Lark bot message announcing a new approval request with an embedded record link preview

The approver receives a card carrying the request details and Approve and Reject buttons.

Lark approval card with requester details beside the full approval record and decision buttons

Once they decide, the card updates and the requester gets a confirmation message.

Lark approval card marked Approved above a confirmation message sent to the requester

And the Base record updates itself. No admin, no retyping, no drift.

Lark Base leave record with the status column automatically changed to Approve

Common Reasons It Does Not Work

  • Nothing reaches AnyCross. Check the callback URL is pasted into the Base HTTP node, the method is POST, and the header is application/json.
  • The approval instance is not created. Widget IDs are wrong, or a date value is missing the T00:00:00+08:00 suffix.
  • The branch never fires. APPROVED or REJECTED is not in capitals.
  • The status does not update. The text written to Base does not exactly match a Status field option.
  • Search records returns nothing. The filter value does not match, or the record is not actually Pending.
  • Permission errors throughout. You are not on an administrator account, or the custom app was never published.

Practical Use Cases for SMEs and Startups

  • Leave and time off: The build above, with a balance field deducted on approval.
  • Purchase requisitions: Requests logged to Base, routed by amount, with the approved value written back for budget reporting.
  • Expense claims: Receipts attached at submission, status synced so finance sees only approved claims.
  • Client onboarding sign-off: Each stage approved by a different role, with the CRM record advancing automatically.
  • Asset requests: Equipment bookings approved by a manager and reflected instantly in an asset register.

Frequently Asked Questions (FAQ)

What is Lark AnyCross used for?

AnyCross is Lark’s integration platform. It connects Lark products and third-party services into automated workflows, so an event in one system can trigger actions in another without any code.

Why do I need two workflows instead of one?

They respond to different events. The first reacts to a form submission and creates the approval; the second reacts to the manager’s decision and updates the record. A single workflow cannot wait indefinitely for a human to make up their mind.

What is the Approval ID for?

It is the link between the two systems. Workflow 1 writes the approval instance code onto the Base record, and Workflow 2 searches on that code to find the right row when a decision arrives.

Do I need a custom app to use AnyCross with Lark Base?

Yes. The Lark connectors authenticate through a custom app using Lark Tenant Authorization, so you need one published in the Developer Console before the nodes can connect.

Where do I find the approval definition code?

Open the approval in the Lark Admin Console and read the definitionCode parameter from the end of the browser URL.

Why is my branch not matching the approval status?

Almost always capitalisation. Lark Approval sends APPROVED and REJECTED in upper case, so the branch condition has to use upper case too. Separately, the value you write into Base must match your Status field option exactly, which is usually not upper case.

Can I use a manager as the approver instead of the requester?

Yes, and you should in production. Set the approver to Manager in Process Design. Requester is only useful for testing the loop on a single account.

Closing the Loop

The value here is not any one node. It is that the decision and the record can no longer disagree, because no human sits between them. Build it once for leave, and the same pattern, form to Base to approval and back again, covers purchase requests, expense claims and every other approval your team runs on memory and goodwill.

Ready to Power Your Business with Lark?

Lark Base is just one part of an all-in-one platform that brings messaging, meetings, documents, approvals, and automations together for your entire team.

As the Platinum Partner for Lark in Malaysia, Exabytes offers tailored Lark plans, hands-on onboarding, and dedicated local support to help your team build automations like this one properly the first time.

Explore Lark plans with Exabytes today