4. Detailed explanation of the Chatbot node
Last updated
Last updated
Start flow
1.1. Introduction: The Start node is used to initiate a flow, and users can set conditions for it. 1.2. Properties
AntCRM Account: The account that allows management of AntCRM.
Flow name: The display name for the start node.
Page: The platform selected to use the start node.
Types of conditions
Contains Keyword: Only messages need to contain the keyword.
Condition: “..ab..” -> Accepts all messages containing the characters "ab."
Contains All:
Condition: “ab” -> Accepts messages containing "ab."
Message is a Command:
Condition: “/command” -> Accepts messages that start with “/…”
Message is a Command and a Starting Word:
Condition: “/start” -> Accepts messages starting with the command "/start."
After setting up the rules:
End flow
2.1 Introduction
Used to end the flow session.
2.2 Properties
Select the Ant CRM account to be used.
2.3 Redirect flow.
2.4 Introduction
Redirect the current flow's work to a new flow.
2.5 Attributes
Name of the flow to redirect to: Select the starting node of the flow you want to redirect to (start a different flow)
Messages
4.1 Introduction
Set up the message sent from the bot to the user.
4.2 Attributes
Node name: The display name of the output notification on the flow.
Content: The content of the message sent.
Add version: Add another version of the content of the sent message. We can send multiple text messages.
Comment
This node is responsible for automatically responding to user comments. This helps the bot interact and reply quickly to users on social media platforms like Facebook, Instagram, or Twitter.
Images, sound, documents and video
These nodes function similarly (for Facebook and WhatsApp). This node automatically sends images, audio, videos, and documents to users. This helps the bot present information in a more visual and engaging way.
This node provides interactive nodes for users, allowing them to easily interact and choose from different options (only applicable for Facebook and WhatsApp).
Node button
This node provides interactive nodes for users, allowing them to easily interact and choose from different options (only applicable to Facebook and WhatsApp)
Quick replies
This node provides quick replies for users, helping them respond quickly without having to type again.
Message Template
This node automatically sends predefined templates, helping to provide specific information or automatically perform certain actions.
Actions
This node performs specific actions, such as redirecting to an agent when necessary
Menu List
Introduction
Allows the creation of a menu of selectable nodes. The selectable nodes consist of two types: open a URL link or navigate to another node.
Attributes
Template type: Select Menu list to start.
Add button: Add an option to the node.
Choose button type: Choose the type for the node. If selecting URL, add the web link to open the website you want to redirect to.
If selecting post back, only add the display name of the node.
When selecting a node, it will navigate to a node corresponding to that node.
Debug
12.1 Introduction
Displays the selected notification attributes in the debug sidebar tab and runtime log options. By default, the node shows msg.payload, but it can be configured to display any attribute, such as the full message or the result of a JSONata expression.
The debug sidebar provides a structured view of the messages sent, making it easier to understand their structure.
JavaScript objects and arrays can be collapsed or expanded on demand. Buffer objects can be displayed as raw data or as a string if possible.
Next to each message, the debug sidebar includes information about the time the message was received, the node that sent the message, and the message type. Clicking on the source node ID will display that node in the workspace.
The node can be used to enable or disable the output. It's recommended to disable or delete any unused Debug nodes.
This node can also be configured to send all messages to the runtime log or send a short (32-character) message to the status text in the debug node.
12.2 Attributes
Output: Select the output content of the debug node.
To: Choose the display area for the output content.
Name: Set the display name for the debug node.
Function
Introduction A JavaScript function to run based on the messages received by the node. Messages are passed in as a JavaScript object named msg. By convention, it will have a msg.payload property containing the message content. The function is expected to return a message object (or multiple message objects), but it can optionally return nothing to pause a flow. The On Start tab contains code that will run whenever the node is started. The On Stop tab contains code that will run when the node stops. If the On Start code returns a Promise object, the node will not start processing messages until the promise is resolved.
Sending Messages
The function can return messages that it wants to pass to the next nodes in the flow, or it can call node.send(message)
.
Messages that can be returned/sent:
A single message object - sent to nodes connected to the first output.
An array of message objects - sent to nodes connected to the corresponding output.
Note: The setup code is executed during node initialization. Therefore, if node.send
is called in the setup tab, the next nodes may not receive the message.
If any element of the array is a message array, multiple messages will be sent to the corresponding output.
If null
is returned, whether on its own or as an array element, no message will be sent.
Logging and Error Handling: To log any information or report errors, the following functions are available:
node.log("Log message")
node.warn("Warning")
node.error("Error")
The Catch node can also be used for error handling. To call the Catch node, pass the message as the second argument to node.error
:
node.error("Error", msg);
Accessing Node Information The following properties are available to access information about the node:
node.id
- the node's id
node.name
- the node's name
node.outputCount
- the number of output flows of the node
Using Environment Variables
Environment variables can be accessed using env.get("MY_ENV_VAR")
.
Introduction
The node function is used to assist in message processing. After processing, the message will be returned.
Attributes
Name: Set the display name for the function node.
On message: Program the methods and algorithms you want to process and return the message.
Change
Introduction
Set, change, delete, or move message properties, flow context, or global context.
The node can specify multiple rules that will be applied in the order they are defined.
Attributes Available operations are:
Set: Set a property. The value can have different types or be fetched from the message or existing context properties.
Change: Search and replace parts of a property. If regular expressions are enabled, the "replace with" property can include capture groups, e.g., $1. The replacement will only change the type if there is a complete match.
Delete: Delete a property.
Move: Move or rename a property.
Type "expression": Uses expression language and JSONata query language
Introduction
Used to perform transformations on msg, flow, and global variables.
Attributes Variable
Msg: A variable that is deployed within a small flow.
Flow: A variable that can be used anywhere within the flow.
Global: A variable that can be used everywhere.
Transformation Magic
Set: Set the content for the variable.
Change: Change the content of the variable.
Delete: Delete the content of the variable.
Move: Move the content of this variable to another variable.
Http in
Introduction
Creates an HTTP endpoint to create a web service.
Attributes Outputs
payload For GET requests, it contains an object of any query string parameters. Conversely, it contains the content of the HTTP request.
req: object An HTTP request object. This object contains several properties that provide information about the request.
body: The content of the upcoming request. The format will depend on the request.
headers: An object containing the HTTP request headers.
query: An object containing any query string parameters.
params: An object containing any route parameters.
cookies: An object containing cookies for the request.
files: If enabled in the node, an object containing any files uploaded as part of a POST request.
res: object An HTTP response object. This property should not be used directly; the HTTP response node handles how to respond to the request. This property should be tied to the message sent to the response node.
The node will listen on a configured path for requests of a specific type. The path can be fully specified, such as /user
, or include named parameters that accept any value, such as /user/:name
. When using named parameters, their actual values in a request can be accessed in msg.req.params
.
For requests with content, such as POST or PUT, the content of the request is provided as msg.payload
.
If the content type of the request can be determined, the content will be parsed into an appropriate type. For example, application/json
will be parsed into its JavaScript object representation.
Note: This node does not send any response to the request. The flow must include an HTTP response node to complete the request.
Introduction
Sends a response back to the requests received from the HTTP Input node.
Attributes Inputs
payload: string The body of the response.
statusCode: number If set, this code will be used as the response status code. Default: 200.
headers: object If set, provides HTTP headers to include in the response.
cookies: object If set, can be used to set or delete cookies. The status code and headers can also be set in the node itself. If a property is set in the node, it cannot be overridden by the corresponding message property.
Cookie Handling The cookie property must be an object of name/value pairs. The value can be a string to set the cookie value with default options or an object with options. The following example sets two cookies: one cookie called "name" with the value "nick," and another called "session" with the value "1234" and an expiration time set to 15 minutes.
Valid options include:
domain - (String) the domain for the cookie
expires - (Date) the expiration date in GMT. If not specified or set to 0, it creates a session cookie.
maxAge - (String) the expiration date relative to the current time in milliseconds
path - (String) the path for the cookie. Default is /
value - (String) the value used for the cookie
To delete a cookie, set its value to null
.
Http request
Introduction
Sends an HTTP request and returns a response.
Attributes Inputs
url: string If not configured in the node, this optional property sets the URL for the request.
method: string If not configured in the node, this optional property sets the HTTP method for the request. It must be one of the following: GET, PUT, POST, PATCH, or DELETE.
headers: object
Sets the HTTP headers for the request. NOTE: Any headers set in the node configuration will override matching headers in msg.headers
.
cookies: object If set, can be used to send cookies with the request.
payload Sent as the content of the request.
rejectUnauthorized If set to false, it allows sending requests to HTTPS websites with self-signed certificates.
followRedirects If set to false, it prevents redirects (HTTP 301). Default is true.
requestTimeout
If set to a positive number in milliseconds, it overrides the global httpRequestTimeout
setting.
Outputs
payload: string | object | buffer The body of the response. The node can be configured to return the body as a string, attempt to parse it as a JSON string, or return it as a binary buffer.
statusCode: number The response status code or error code if the request could not be completed.
headers: object An object containing the response headers.
responseUrl: string In the event of any redirects while processing the request, this property is the final redirected URL. Otherwise, it is the original request URL.
responseCookies: object If the response includes cookies, this property is an object of name/value pairs for each cookie.
redirectList: array
If the request was redirected one or more times, cumulative information will be added to this property. location
is the next redirect destination. cookie
is the cookie returned from the redirect source.
When configured in the node, the URL property can contain mustache-style tags. These allow the URL to be constructed using values from the incoming message. For example, if the URL is set to example.com/{{{topic}}}
, it will automatically insert the value of msg.topic
. Using {{{...}}}
prevents mustache from escaping characters like /
, &
, etc.
The node may optionally encode msg.payload
as query string parameters for a GET request, in which case msg.payload
must be an object.
Using Multiple HTTP Request Nodes
To use more than one of these nodes within the same flow, caution must be taken with the msg.headers
property. The first node will set this property with the response headers. Then, the next node will use those headers for its request — which is usually not ideal. If msg.headers
does not change between nodes, it will be ignored by the second node. To set custom headers, you must first clear msg.headers
or reset it to an empty object: {}
.
Cookie Handling
The cookies
property passed to the node must be an object of name/value pairs. The value can be a string to set the cookie value or an object with a single value
property.
Any cookies that are returned with the response will be passed back via the replyCookies
property.
Content Type Handling
If msg.payload
is an object, the node will automatically set the content type of the request to application/json
and encode the content accordingly.
To encode the request as form data, msg.headers["content-type"]
must be set to application/x-www-form-urlencoded
.
File Uploads
To perform a file upload, msg.headers["content-type"]
must be set to multipart/form-data
, and msg.payload
passed to the node must be an object structured as follows:
The values of KEY
, FILE_CONTENTS
, and FILENAME
should be set to the appropriate values
Switch
Introduction
This node is used to route messages based on the value of a property or their position in a sequence. When a message arrives, the node will evaluate each rule defined and forward the message to the corresponding output of any matching rule. Optionally, the node can be configured to stop evaluating further rules after finding a matching one.
Attributes Rules
Value-based Rule: This rule is evaluated based on the configured property of the message.
Sequence Rule: These can be used on message strings, such as rules created by the split node.
JSONata Expression Rule: You can provide a JSONata expression to evaluate the entire message, and the rule will match if the expression returns a true value.
Inverse Rule: This can be used to match if none of the previous rules match.
Important Notes
Strict Comparison: True/false and null rules perform strict type comparisons. They do not perform type conversion.
Empty and Non-empty Rules: These rules can be used to check the length of Strings, Arrays, and Buffers or the number of flow properties an object has. Neither of these rules will pass if the property being checked has a boolean, null, or undefined value.
Message String Handling: By default, the node does not modify the msg.parts
property of the messages as part of the sequence.
Message String Rebuilding: An option to rebuild the message string can be enabled, which will create a new message string for each matching rule. In this mode, the node will buffer the entire sequence before sending a new message. The runtime setting nodeMessageBufferMaxLength
can be used to limit the number of flow node messages to be stored in the buffer.
Variables
Variables are used to apply the rules on.
Msg: The variable is only deployed within a specific flow.
Flow: The variable can be used anywhere within the flow.
Global: The variable can be used globally.
Variable rules: The rules are evaluated based on the configured property of the variable.
Comparison Variable: A variable used for comparison with other variables, where the type of the variable can be selected
Add the conditions
Option
Check all rules: Check all conditions and then route accordingly. Stop after first match: Stop checking when the first correct condition is met
Range
Introduction
Maps a numerical value to another range.
Attributes
Input
payload: number The payload must be a number. Anything else will be attempted to be parsed into a number and rejected if it fails.
Outputs
payload: number The value mapped to the new range.
This node will scale the received value linearly. By default, the result is not constrained within the range defined in the node.
Scale and limit to target range: The result will never be outside the specified target range.
Scale and wrap to target range: The result will be wrapped within the target range.
Scale but clamp if outside input range: The result will be scaled, but any input outside the input range will be clamped.
Example: Input range 0 - 10 is mapped to 0 - 100.
Delay
20.1 Split
Introduction
Splits a message into a series of smaller messages.
Attributes
Inputs
payload: object | string | array | buffer
The behavior of the node is determined by the type of msg.payload
:
string/buffer: The message is split by a specified delimiter (default: ), a buffer string, or into fixed-length chunks.
array: The message is split into individual array elements or fixed-length arrays.
object: A message is created for each key-value pair in the object.
Outputs
parts: object
This property contains information about how the message was split from the original message. If passed to a join node, the sequence can be reassembled into a single message. It includes the following attributes:
id: Identifier for the message group.
index: Position in the group.
count: If known, the total number of messages in the group (see 'streaming mode' below).
type: Type of the message (string
, array
, object
, or buffer
).
ch: For a string or buffer, the data used to split the message as a string or byte array.
key: For an object, the key of the property from which this message was created. This node can be configured to copy this value to other message properties, such as msg.topic
.
len: The length of each message when split by fixed-length value.
This node makes it easy to create flows that perform actions on an entire string of messages, using a join node to combine them back into a single message.
It uses the msg.parts
attribute to track individual segments of a message.
Streaming Mode This node can also be used to adjust the flow of messages. For example, a serial device sending newline-terminated commands might send a message with a partial command at the end. In streaming mode, this node will split the message and send each complete segment as a separate message. If there is a partial segment at the end, the node will hold it and append it to the next message received.
In streaming mode, the node does not set the msg.parts.count
because it cannot predict how many messages will be in the flow. This means it cannot be used with the join node in automatic mode.
Join
Introduction
Joins a sequence of messages into a single message.
Attributes There are three available modes:
Automatic: When connected to a split node, it automatically joins messages to reverse the splitting process.
Manual: Joins the messages in various ways.
Reduce Sequence: Applies an expression to all messages in a sequence to reduce them into a single message.
Inputs
parts: object
To automatically join a sequence of messages, they must all have this property. The split node creates this property, but it can also be manually created. It contains the following attributes:
id: Identifier for the message group.
index: Position in the group.
count: Total number of messages in the group.
type: Type of the message (string, array, object, buffer).
ch: For a string or buffer, data used to split the message as a string or byte array.
key: For an object, the key of the property the message was created from.
len: The length of each message when split by fixed-length value.
complete
If set, the node will join the payload and then send the output message in its current state. If you don’t want to add the payload, you can remove it from msg
.
reset If set, the node will delete any partially completed messages and will not send them.
restartTimeout If set and the node has a configured timeout, that timeout will be restarted.
Automatic Mode Automatic mode uses the attributes of the incoming messages to determine how to join the sequence. This allows it to automatically reverse the actions of a split node.
Manual Mode When configured to join in manual mode, the node can join message sequences into various outcomes:
A string or buffer is created by concatenating the selected attribute of each message with a specified separator or buffer.
An array is created by adding each selected attribute or the entire message to the output array.
A key/value object is created by using the attribute of each message to define a key that stores the required value.
A merged object is created by merging the attributes of each message into a single object.
Other message properties are taken from the last message received before the result is sent.
You can set the number of flow messages to receive before creating an output message. For object outputs, once this number is reached, the node can be configured to send a message for each subsequent message received.
You can set a timeout to trigger sending a new message using whatever has been received so far. This timeout can be restarted by sending a message with the msg.restartTimeout
property.
If a message is received with the msg.complete
property set, the output message will be completed and sent.
If a message is received with the msg.reset
property set, the partially completed message will be deleted and not sent.
Reduce Sequence Mode When configured to join in reduce mode, an expression will be applied to each message in the sequence, and the results will accumulate to create a single message.
Initial value
The initial value for the accumulator ($A
).
Reduce expression The JSONata expression applied to each message in the sequence. The result is passed to the next expression call as the accumulated value. In the expression, the following special variables can be used:
$A
: The accumulated value.
$I
: The index of the message in the sequence.
$N
: The number of flow messages in the sequence.
Fix-up expression An optional JSONata expression applied after the reduce expression has been applied to all messages in the sequence. In the expression, the following special variables can be used:
$A
: The accumulated value.
$N
: The number of flow messages in the sequence.
By default, the reduce expression is applied in order from the first to the last message in the sequence. It can optionally be applied in reverse order.
$N
is the number of flow messages that have arrived — even if they are identical.
Example: The following settings, for a sequence of numeric values, will calculate the average:
Reduce expression: $A+payload
Initial value: 0
Fix-up expression: $A/$N
Storing Messages
This node will buffer messages internally to work across sequences. The runtime setting nodeMessageBufferMaxLength
can be used to limit how many messages the node will buffer.
Sort
Introduction A function to sort message properties or a sequence of messages.
Attributes When configured to sort a message property, the node will sort the array data pointed to by the specified message property. When configured to sort a sequence of messages, it will reorder the messages.
The sort order can be:
Ascending
Descending
For numbers, the numeric order can be specified via a checkbox.
The sort key can either be the element value or a JSONata expression used to sort the property value or message property, or it can sort the sequence of messages.
When sorting a sequence of messages, the node sorts based on the messages received to set msg.parts
. This property is created by the split node but can also be created manually. It contains the following attributes:
id: Identifier for the message group
index: Position within the group
count: Total number of messages in the group
Note:
This node stores messages internally for its operation. To prevent unwanted memory usage, you can specify the maximum number of flow messages to be retained. There is no inherent limit on the number of flow messages.
The nodeMessageBufferMaxLength property can be set in settings.js
.
Batch
Introduction This node creates a message sequence based on different rules.
Attributes There are three modes to create message sequences:
Number of Flow Messages
Groups messages into sequences with a specified length.
The overlap option specifies how many flow messages at the end of a sequence will be repeated when starting the next sequence.
Time Interval
Groups incoming messages within a specified time interval.
If no messages arrive during the time interval, the node can optionally send an empty message.
Concatenation Sequence
Creates a message sequence by concatenating incoming messages.
Each message must have the msg.topic
property and the msg.parts
property to define its order.
The node is configured with a list of topic values to define the concatenation order.
Storing Messages
This node buffers messages internally to work across sequences. The runtime setting nodeMessageBufferMaxLength
can be used to limit the number of flow node messages retained in the buffer.
If a message with the msg.reset
property is received, the messages in the buffer will be cleared and will not be sent.
Inject
Introduction This node injects messages into the flow either manually or on a schedule. The message payload can be of various types, including strings, JavaScript objects, or the current time.
Attributes Outputs
payload Various types of payloads are configurable for the message. The default payload is the timestamp in milliseconds since January 1, 1970.
topic An optional property that can be configured within the node.
How it works:
The Inject node starts a flow with a specific payload value. The default payload is the timestamp of the current time in milliseconds.
This node supports injecting various data types such as strings, numbers, booleans, JavaScript objects, or global/flow context values.
By default, the node is manually triggered by clicking the node in the editor. It can also be set to trigger periodically or on a scheduled basis.
It can also be configured to inject once whenever a flow starts.
Maximum Interval: The maximum interval that can be set is about 596 hours (24 days). However, for intervals greater than one day, it's recommended to use the "schedule" node, which can handle power outages and restarts.
Note:
The options "Interval between" and "At a specific time" use the standard cron system. This means that 20 minutes will be the next hour, 20 minutes later, and 40 minutes later—not at exactly 20 minutes. If you want to trigger every 20 minutes from now, use the "Interval" option.
Note: To add a new line in the string, you must use a Function or Template node to create the payload.
Complete
Introduction This node triggers a flow when another node completes the processing of a message.
Attributes If a node signals its runtime completion after processing a message, this node can be used to trigger a second flow.
Example: This can be useful when paired with a node that does not have an output, such as an email node, to continue the flow after an action is completed.
This node must be configured to handle events from specific nodes selected within the flow. Unlike the Catch node, it does not provide an "automatic 'handle all'" mode that applies to all nodes in the flow.
Catch
Introduction This node catches errors that are thrown by nodes within the same tab.
Attributes
Outputs
error.message String The error message.
error.source.id String The ID of the node that caused the error.
error.source.type String The type of the node that caused the error.
error.source.name String The name, if set, of the node that caused the error.
If a node throws an error while processing a message, the flow typically stops. This node can be used to detect those errors and handle them with a dedicated flow.
By default, this node will detect errors thrown by any node within the same tab. It can also be targeted at specific nodes or configured to detect only errors that were not caught by other targeted nodes.
When an error occurs, all matching Catch nodes will receive the notification.
If an error occurs in a subflow, it will be handled by any Catch node within that subflow. If none exist, the error will propagate to the parent tab where the subflow is active.
If the message already has an error property, it will be copied to _error
.
Status
Introduction This node reports status messages from other nodes within the same tab.
Attributes
Outputs
status.text String The text of the status message.
status.source.type String The type of the node reporting the status.
status.source.id String The ID of the node that reported the status.
status.source.name String The name, if set, of the node that reported the status.
This node does not create a payload.
By default, it reports the status for all nodes within the same workspace tab. It can be configured to selectively report the status for individual nodes.
Linked in
Introduction:
Create virtual links between flows.
Attributes:
This node can be connected to any outgoing link node that exists on any tab. Once connected, they act as if they are directly linked to each other.
The links between connected nodes are only displayed when a link node is selected.
If any links lead to other tabs, a virtual node will appear, and you can click on it to navigate to the appropriate tab.
Note: Links cannot be created when entering or exiting a sub flow.
Introduction: The Link Call node is used to invoke another flow via a link within a node and to handle the response. It allows the transfer of a message to a linked flow and waits for the response to proceed.
Attributes:
Inputs:
target (string): When the Link Type option is set to "dynamic target", set msg.target to the name of the link in the node you wish to call. This allows you to specify which flow or link to call dynamically.
Node Behavior: This node can be connected to a link in a node on any tab. The connected flow must end with a link-out node that is configured in 'return' mode.
When the node receives a message, it is forwarded to the linked flow. The node will then wait for a response, and if a response isn't received within the configured timeout (default 30 seconds), it will report an error via a Catch node.
With dynamic target, you can call a link by its name or ID.
Link Calls cannot target links in nodes inside sub-flows.
Introduction: The Link Out node creates an "virtual" connection between flows, allowing messages to be sent to another flow by linking them.
Attributes:
This node can be configured to send messages to all links in connected nodes or send responses back to the Link Call node that triggered the flow.
In 'send to all' mode, links will only be visible when the node is selected. Any wires leading to other tabs will show a virtual node you can click to navigate to the corresponding tab.
Introduction: The Comment node allows you to add comments to your flow for documentation purposes. This helps in keeping track of what each part of the flow does.
Get request
A GET request does not require initial input; simply send the request to the API and receive the response in the msg.payload
Post request
A POST request requires input data, which you can set through the function node.
After sending the payload and data, the request will appear in msg.payload
API Authorization
In the HTTP request node, select "Use authentication," then choose the type of authentication you want. After that, fill in the token and password.
Generative AI API'S
Enter the API URL into the HTTP Request node to integrate the API
API Response Status Code
The status code has been saved in msg.statusCode
200: Success
404: Failure
Conditions based on the API Response
Depending on msg.statusCode and the switch node, different actions can be set based on the API response.
Sample Example
Send image.
Name: Display name of the image button
URL: Path to the publicly available image
Delay 2s
Action: Setting action delay
Delay each message
Fixed delay
For: setting the lately time
Send message
Enter user information
Initialize some variables to input user information
First time": to confirm that the user is entering for the first time
If (first time == true)
Create: It means checking or notifying. This variable is used to navigate the flow of messages to inform the user of the information they need to enter, or to check validation and save the information.
Check value: to enter the input validation flow (authentication) of the user, then save it if valid. 'Notice' value: to input the notification message from the bot to the user, then change 'con' to 'check' to redirect to the 'check' flow
Create “name”: it refers to the name of the information you want the user to provide
name == “company”: Get company name
name == “name”: Get user name
name == “email”: Get email
The notify flow
After checking the information, let's guide it
After the notification is successful,
change 'con' to check the user's input and also wait until the user enters something.
Change 'first time' to false; if 'first time' is still true, the variables will be reset.
Check the flow
Check validation
Save
Check if the entered name contains any numbers, and if it does, notify the user and allow them to enter it again
Check if the entered email contains '@' and '.'; if not, notify the user and allow them to enter it again.
After successfully entering the email, change 'first time' to true to start a new flow
Send thank you message
Hand over service
After sending the message, move line to handover
Setting action button
Add "hand over"