Clock Punch Mock Connection

Implementation Steps

1 - Create Talkdesk users to sync.
2 - Create mock server using Postman.
3 - Create the mock Connection and respective Actions.
4 - Create an Automation to punch the clock upon login and logout.

Implementation

1 - Create Talkdesk users to sync

🚧

Please perform this action only in a sandbox account, not in a real production account.

To test Agent Sync, you need agents to synchronize and an API capable of providing information about these agents to the external system. In this example, you can see a simulated set of users with email addresses following the format user+<<n>>@talkdesk.com, where <<n>> represents the external ID of the user. This format is used solely to distinguish the mock email addresses.

1.1 - Within Talkdesk Workspace™, navigate to Admin (Figure 1 - 1) > Agents (Figure 1 - 2) and click Add New Agent (Figure 1 - 3).

Figure 1 - Add new agent

Figure 1 - Add new agent

1.2 - Provide the necessary details for the new Agent (Figure 2). Name and Email fields are mandatory.

Figure 2 - New agent details

Figure 2 - New agent details

1.3 - Scroll down and click Save (Figure 3 - 1).

Figure 3 - Click Save

Figure 3 - Click Save

2 - Create mock Server using Postman

2.1 - On Postman, click Import (Figure 4 - 1) to add the collection.

Figure 4 - Postman import

Figure 4 - Postman import

2.2 - Drag the Collection JSON file below or click the Choose the Files button (Figure 5 - 1).

{
	"info": {
		"_postman_id": "7680b95f-9e0a-438c-9e9a-b35abdf1f7c0",
		"name": "Time Punching Integration",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
		"_exporter_id": "15213801"
	},
	"item": [
		{
			"name": "users/formatted",
			"protocolProfileBehavior": {
				"disableBodyPruning": true
			},
			"request": {
				"method": "GET",
				"header": [],
				"body": {
					"mode": "raw",
					"raw": ""
				},
				"url": {
					"raw": "{{url}}/users/formatted?page=4",
					"host": [
						"{{url}}"
					],
					"path": [
						"users",
						"formatted"
					],
					"query": [
						{
							"key": "page",
							"value": "4"
						}
					]
				}
			},
			"response": [
				{
					"name": "page 1",
					"originalRequest": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": ""
						},
						"url": {
							"raw": "{{url}}/users/formatted?page=1",
							"host": [
								"{{url}}"
							],
							"path": [
								"users",
								"formatted"
							],
							"query": [
								{
									"key": "page",
									"value": "1"
								}
							]
						}
					},
					"code": 200,
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"count\": 5,\n    \"total\": 7,\n    \"users\": [\n        {\n            \"name\": \"Barbara Banh\",\n            \"id\": 1,\n            \"email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Steven Herrera\",\n            \"id\": 2,\n            \"email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Gregory Dearing\",\n            \"id\": 3,\n            \"email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Patty Raines\",\n            \"id\": 4,\n            \"email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Ricardo Smith\",\n            \"id\": 5,\n            \"email\": \"[email protected]\"\n        }\n    ]\n}"
				},
				{
					"name": "page 2",
					"originalRequest": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": ""
						},
						"url": {
							"raw": "{{url}}/users/formatted?page=2",
							"host": [
								"{{url}}"
							],
							"path": [
								"users",
								"formatted"
							],
							"query": [
								{
									"key": "page",
									"value": "2"
								}
							]
						}
					},
					"code": 200,
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n  \"count\": 2,\n  \"total\": 7,\n  \"users\": [\n     {\n        \"name\": \"Clarence Hull\",\n        \"id\": 6,\n        \"email\": \"[email protected]\"\n     } ,\n     {\n        \"name\": \"Donald MCants\",\n        \"id\": 7,\n        \"email\": \"[email protected]\"\n     } \n  ]\n}"
				},
				{
					"name": "no page",
					"originalRequest": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": ""
						},
						"url": {
							"raw": "{{url}}/users/formatted",
							"host": [
								"{{url}}"
							],
							"path": [
								"users",
								"formatted"
							]
						}
					},
					"status": "Bad Request",
					"code": 400,
					"_postman_previewlanguage": null,
					"header": null,
					"cookie": [],
					"body": "No page was specified."
				}
			]
		},
		{
			"name": "users/not-formatted",
			"protocolProfileBehavior": {
				"disableBodyPruning": true
			},
			"request": {
				"method": "GET",
				"header": [],
				"body": {
					"mode": "raw",
					"raw": ""
				},
				"url": {
					"raw": "{{url}}/users/not-formatted?page=4",
					"host": [
						"{{url}}"
					],
					"path": [
						"users",
						"not-formatted"
					],
					"query": [
						{
							"key": "page",
							"value": "4"
						}
					]
				}
			},
			"response": [
				{
					"name": "page 1",
					"originalRequest": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": ""
						},
						"url": {
							"raw": "{{url}}/users/not-formatted?page=1",
							"host": [
								"{{url}}"
							],
							"path": [
								"users",
								"not-formatted"
							],
							"query": [
								{
									"key": "page",
									"value": "1"
								}
							]
						}
					},
					"code": 200,
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"count\": 5,\n    \"total\": 7,\n    \"users\": [\n        {\n            \"name\": \"Barbara Banh\",\n            \"punch_clock_id\": 1,\n            \"punch_clock_email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Steven Herrera\",\n            \"punch_clock_id\": 2,\n            \"punch_clock_email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Gregory Dearing\",\n            \"punch_clock_id\": 3,\n            \"punch_clock_email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Patty Raines\",\n            \"punch_clock_id\": 4,\n            \"punch_clock_email\": \"[email protected]\"\n        },\n        {\n            \"name\": \"Ricardo Smith\",\n            \"punch_clock_id\": 5,\n            \"punch_clock_email\": \"[email protected]\"\n        }\n    ]\n}"
				},
				{
					"name": "page 2",
					"originalRequest": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": ""
						},
						"url": {
							"raw": "{{url}}/users/not-formatted?page=2",
							"host": [
								"{{url}}"
							],
							"path": [
								"users",
								"not-formatted"
							],
							"query": [
								{
									"key": "page",
									"value": "2"
								}
							]
						}
					},
					"code": 200,
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n  \"count\": 2,\n  \"total\": 7,\n  \"users\": [\n     {\n        \"name\": \"Clarence Hull\",\n        \"punch_clock_id\": 6,\n        \"punch_clock_email\": \"[email protected]\"\n     } ,\n     {\n        \"name\": \"Donald MCants\",\n        \"punch_clock_id\": 7,\n        \"punch_clock_email\": \"[email protected]\"\n     } \n  ]\n}"
				},
				{
					"name": "no page",
					"originalRequest": {
						"method": "GET",
						"header": [],
						"body": {
							"mode": "raw",
							"raw": ""
						},
						"url": {
							"raw": "{{url}}/users/formatted",
							"host": [
								"{{url}}"
							],
							"path": [
								"users",
								"formatted"
							]
						}
					},
					"status": "Bad Request",
					"code": 400,
					"_postman_previewlanguage": null,
					"header": null,
					"cookie": [],
					"body": "No page was specified."
				}
			]
		},
		{
			"name": "users/punch-clock",
			"request": {
				"method": "POST",
				"header": [],
				"url": {
					"raw": "{{url}}/user/1/punch-clock",
					"host": [
						"{{url}}"
					],
					"path": [
						"user",
						"1",
						"punch-clock"
					]
				}
			},
			"response": [
				{
					"name": "user 1",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/1/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"1",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Barbara Banh\",\n    \"check_in_time\": \"2023-08-11T08:10:09+00:00\"\n}"
				},
				{
					"name": "user 2",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/2/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"2",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Steven Herrera\",\n    \"check_in_time\": \"2023-08-15T13:10:09+00:00\"\n}"
				},
				{
					"name": "user 3",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/3/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"3",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Gregory Dearing\",\n    \"check_in_time\": \"2023-08-15T07:11:09+00:00\"\n}"
				},
				{
					"name": "user 4",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/4/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"4",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Patty Raines\",\n    \"check_in_time\": \"2023-08-15T08:10:13+00:00\"\n}"
				},
				{
					"name": "user 5",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/5/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"5",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Ricardo Smith\",\n    \"check_in_time\": \"2023-08-14T08:50:11+00:00\"\n}"
				},
				{
					"name": "user 6",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/6/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"6",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Clarence Hull\",\n    \"check_in_time\": \"2023-08-15T11:49:13+00:00\"\n}"
				},
				{
					"name": "user 7",
					"originalRequest": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{url}}/user/7/punch-clock",
							"host": [
								"{{url}}"
							],
							"path": [
								"user",
								"7",
								"punch-clock"
							]
						}
					},
					"_postman_previewlanguage": "json",
					"header": [
						{
							"key": "Content-Type",
							"value": "application/json",
							"name": "Content-Type",
							"description": "",
							"type": "text"
						}
					],
					"cookie": [],
					"body": "{\n    \"name\": \"Donald MCants\",\n    \"check_in_time\": \"2023-08-15T11:50:03+00:00\"\n}"
				}
			]
		}
	],
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"exec": [
					""
				]
			}
		},
		{
			"listen": "test",
			"script": {
				"type": "text/javascript",
				"exec": [
					""
				]
			}
		}
	],
	"variable": [
		{
			"key": "url",
			"value": "https://9d938bc2-1087-4271-90d5-5b20584df6fd.mock.pstmn.io"
		}
	]
}
Figure 5 - Collection JSON file

Figure 5 - Collection JSON file

2.3 - Click Import (Figure 6 - 1).

Figure 6 - Click Import

Figure 6 - Click Import

👍

Once completed, the collection import will be marked as finished (Figure 7 - 1).

2.4 - Right-click the newly imported collection (Figure 7 - 2) and select the Mock collection option (Figure 7 - 3).

Figure 7 - Newly imported collection

Figure 7 - Newly imported collection

2.5 - Locate the URL (Figure 8 - 1) within the collection's Variables section (Figure 8 - 2). This will be the URL used in the mock Connection.

Figure 8 - URL

Figure 8 - URL

2.6 - Modify the mock response emails.

2.6.1 - Within the users/formatted(Figure 9 - 1) and users/not-formatted(Figure 9 - 2) endpoints, you will discover two user pages (Figure 9 - 3). These pages contain the names and email addresses of mock users. The mock email addresses follow the format [email protected]. You must update these values (Figure 9 - 4) to align with the mock agents you created in step 1.

Figure 10 - Endpoints

Figure 10 - Endpoints

🚧

Ensure the emails match the actual users for proper Agent Sync functionality.

3 - Create the mock connection and respective Actions

3.1 - Navigate to Builder (Figure 11 - 1) > Integrations (Figure 11 - 2) and select Add integration (Figure 11 - 3).

Figure 11 - Mock Connection and Respective Actions

Figure 11 - Mock Connection and Respective Actions

3.2 - Click Add integration (Figure 12 - 1) under Custom Integration (Figure 12 - 2).

Figure 12 - Add integration

Figure 12 - Add integration

3.3 - Fill in all the Connection fields (Figure 13).

3.3.1 - Enter the Name (Figure 13 - 1) and Description (Figure 13 - 2) - mandatory fields.

3.3.2 - Set your server URL as the base path for the Connection (Figure 13 - 3) - mandatory field. Add the base path of your API – if you've created a mock API using Postman as suggested, you can find this under the collection Variables, as explained in step 2.5.

3.3.3 - Choose an Authentication type from the dropdown menu (Figure 13 - 4) - mandatory field.

3.3.4 - After completing all the fields, click Save (Figure 13 - 5).

Figure 13 - Connection information

Figure 13 - Connection information

3.4 - Create the Get users (formatted) Action.

📘

Two different Actions are being created to fetch users:

  • One is formatted according to what is expected for Talkdesk Agent Sync.
  • The other will require some mapping for the Agent Sync component to process it.

In this step, it will be detailed how to create an Action for the mock endpoint that sends the users in Talkdesk format (without the need for further mapping).

3.4.1 - In the Integrations menu (Figure 14 - 1), navigate to the Actions tab (Figure 14 - 2) and select the Add action button (Figure 14 - 3). This action will open a panel for configuration (Figure 15).

Figure 14 - Actions tab

Figure 14 - Actions tab

3.4.1.1 - Complete the Action details (Figure 15 and 16):

  • Enter the Name (Figure 15 - 1) and Description (Figure 15 - 2) of the Action (mandatory fields).
  • Specify the relative path (Figure 15 - 3). If you are following the mock collection provided in step 2, the endpoint’s relative path is /users/formatted?page={{page}}. Here, Page is a parameter that indicates which page of users you are currently fetching.
Figure 15 - Action details

Figure 15 - Action details

3.4.1.2 - Leave the input schema (Figure 16 - 1) empty.

3.4.1.3 - Complete the output schema (Figure 16 - 2).

Figure 16 - Inputs and outputs

Figure 16 - Inputs and outputs

The mock API has the following output schema:

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://example.com/object1691513385.json",
  "title": "Root",
  "type": "object",
  "required": [
    "count",
    "total",
    "users"
  ],
  "properties": {
    "count": {
      "$id": "#root/count",
      "title": "Count",
      "type": "integer",
      "default": 0
    },
    "total": {
      "$id": "#root/total",
      "title": "Total",
      "type": "integer",
      "default": 0
    },
    "users": {
      "$id": "#root/users",
      "title": "Users",
      "type": "array",
      "default": [],
      "items": {
        "$id": "#root/users/items",
        "title": "Items",
        "type": "object",
        "required": [
          "name",
          "id",
          "email"
        ],
        "properties": {
          "name": {
            "$id": "#root/users/items/name",
            "title": "Name",
            "type": "string",
            "default": ""
          },
          "id": {
            "$id": "#root/users/items/id",
            "title": "Id",
            "type": "integer",
            "default": 0
          },
          "email": {
            "$id": "#root/users/items/email",
            "title": "Email",
            "type": "string",
            "default": ""
          }
        }
      }
    }
  }
}

3.4.1.4 - After configuring the Action, click Publish (Figure 15 - 4).

3.5 - Create the Get users (not formatted) Action

📘

Next, an Action will be created for the endpoint that returns users in a format requiring mapping by Connections Flows before processing by the Agent Sync component.

3.5.1 - Go back to the Actions tab and click the Add action button.

Figure 17 - Add action

Figure 17 - Add action

3.5.2 - Follow the steps on 3.4 but with an appropriate new name and description, the relative path:

  • Name: Get users (not formatted)
  • Relative path: /not-formatted?page={{page}}
  • Input schema: (leave empty)
{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://example.com/object1692117997.json",
  "title": "Root",
  "type": "object",
  "required": [
    "count",
    "total",
    "users"
  ],
  "properties": {
    "count": {
      "title": "Count",
      "type": "integer"
    },
    "total": {
      "title": "Total",
      "type": "integer"
    },
    "users": {
      "$id": "#root/users",
      "title": "Users",
      "type": "array",
      "default": [],
      "items": {
        "title": "Items",
        "type": "object",
        "required": [
          "name",
          "punch_clock_id",
          "punch_clock_email"
        ],
        "properties": {
          "name": {
            "title": "Name",
            "type": "string"
          },
          "punch_clock_id": {
            "title": "Id",
            "type": "integer"
          },
          "punch_clock_email": {
            "title": "Email",
            "type": "string"
          }
        }
      }
    }
  }
}

3.5.3 - Once you're finished with the Action configuration, click Publish (Figure 15 - 4).

3.6 - Create the Punch Clock Action

📘

The last Action to be created is for registering logins and logouts from a particular user.

3.6.2 - Go to the Actions tab (Figure 18 - 1), and click the Add action (Figure 18 - 2) button.

Figure 18 - Add action

Figure 18 - Add action

3.6.3 - Follow the same steps described in 3.4, but now use these values:

  • Name: Punch clock
  • Relative path: /user/{{user_id}}/punch-clock
  • Input schema: (leave empty)
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Generated schema for Root",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "type": "string"
    },
    "check_in_time": {
      "title": "Check-in Time",
      "type": "string"
    }
  },
  "required": [
    "name",
    "check_in_time"
  ]
}

3.7 - After publishing (Figure 15 - 4) this Action, your Actions tab must list all three actions and appear like this (Figure 19):

Figure 19 - Actions list

Figure 19 - Actions list

4 - Create an Automation to Punch the Clock Upon Login and Logout

Finally, you need to ensure that you have an Automation that will utilize the External ID for "punching the clock," which means recording login and logout times.

4.1 - Go to the Automations tab (Figure 20 - 1) and click the Create automation button (Figure 20 - 1)

4.1.1 - A panel with the Automation configuration fields will appear (Figure 21).

Figure 20 - Create automation

Figure 20 - Create automation

4.2 - Complete the configuration fields

4.2.1 - Provide information in the mandatory Automation Name field (Figure 21 - 1).

4.2.2 - When selecting the trigger, follow these steps:

  • In: choose Talkdesk as the source system of the event (Figure 21 - 2).
  • When: select the event an agent logs in (Figure 21 - 3).
  • Then: opt for Punch clock (Figure 21 - 4). This configuration ensures the automation is triggered whenever an agent logs in.
Figure 21 - Automation details

Figure 21 - Automation details

4.3 - Configure the Action

4.3.1 - To configure the action, drag the Punch Clock Integration Agent External ID (Figure 22 - 1) to the User ID field (Figure 22 - 2).

👍

This will display a variable of the type {{agent.connection_<<connection_id>>.external_id}}, where <<connection_id>> is the ID of the integration with the system for which the external ID is valid (in this case, your mock Punch Clock connection).

Figure 22 - Configure the action

Figure 22 - Configure the action

4.3.2 - Once you've completed the configuration, click Publish (Figure 15 - 4).

👍

Create an Automation for Logging Out

While not necessary for this demonstration, you have the option to create a second Automation that invokes the Punch Clock Action upon logout. You can follow similar steps to those described before, with the difference being that you will select the event an agent logs out as the Automation trigger (Figure 21 - 3).

📘

Troubleshooting

If you have questions or technical issues, please open a ticket using this form.