{"slug": "streamlining-gladly-task-creation-with-apex-code", "title": "Streamlining Gladly Task Creation with Apex Code", "summary": "A developer built an Apex integration with Gladly's task API to automate follow-up task creation from Salesforce. The wrapper class pattern keeps the code maintainable when handling nested JSON objects, and error handling is built in from the start to prevent production issues. The integration ensures tasks are automatically created, assigned, and linked to customer profiles without manual intervention.", "body_md": "**Gladly tasks are more than to-do items** - they're structured, assignable, customer-linked follow-up actions with due dates and comments. Understanding that model is what makes the API integration actually useful rather than just functional.\n\n**The wrapper class pattern isn't ceremony**. It's how you keep your Apex code maintainable when the request body has nested objects and your integration needs to evolve over time without breaking everything that calls it.\n\n**Error handling in API integrations** is the part everyone writes last and regrets skipping first. Build it in from the start - your future self will appreciate it during the first production incident.\n\nIf you've worked with customer service platforms long enough, you know the problem this integration solves.\n\nAn appointment gets rescheduled in Salesforce. Somewhere, a Gladly agent needs to know about it, follow up with the customer, and close the loop. Without automation, that's a manual step - someone has to remember to create the task, fill in the right details, assign it correctly. Sometimes they do. Sometimes they don't. Sometimes they do it three days later when the customer has already called back twice.\n\nApex plus Gladly's task API closes that gap. The follow-up task gets created automatically, assigned correctly, with the right due date and customer context - without anyone having to remember to do it.\n\nThat's what this guide walks through. Not a theoretical overview of what's possible, but the actual code pattern that makes it work.\n\nBefore writing any code, it's worth understanding what a Gladly task actually is - because it's not just a generic to-do item.\n\nA task in Gladly is customer-specific. It lives on a customer's timeline alongside their conversations, emails, and other interactions. It has a body describing what needs to happen, a due date, an assignee (an inbox, a specific agent, or both), and it supports comments. When you create a task through the API, Gladly either attaches it to an existing customer profile or creates a new one if the customer doesn't exist yet.\n\nThat last part matters for the integration. You're not just creating abstract tasks - you're creating follow-up work that lives in the context of a real customer relationship. The API reflects that, which is why the request body requires customer identification alongside the task details.\n\nUnderstanding this model upfront saves a lot of confusion when you're looking at the request schema and wondering why customer identification is required when \"you just want to create a task.\n\nGladly exposes a POST endpoint for task creation. The request hits the tasks API, carries a JSON body with everything Gladly needs to create and assign the task, and returns a response you can use for error handling and confirmation.\n\nHere's how to build this in Apex, step by step.\n\n```\n{\n  \"id\": \"pOVVdzweSumI4bFxjlT8LA\",\n  \"assignee\": {\n    \"inboxId\": \"NFpDZtfqhk2pI6fjaVDlFf\",\n    \"agentId\": \"zGaHXjD4SR-moMR9LbULDa\"\n  },\n  \"body\": \"Create task to reschedule appointment\",\n  \"dueAt\": \"2020-03-15T06:13:00.125Z\",\n  \"customer\": {\n    \"emailAddress\": \"michelle.smith@example.org\",\n    \"mobilePhone\": \"+16505551987\"\n  }\n}\nid\nString &lt;= 50 characters\nSpecifies the id of the task\nassignee \n    required\nobject (Assignee)\nInbox and agent assignee for a task\nbody\n   required\nstring &lt;= 10000 characters\nText to describe what task to complete. Constrained HTML Rich Content is supported.\ndueAt\n   required\nstring &lt;RFC3339&gt;\nTime when the task will be due. This must be set to a time in the future.\nCustomer\n   required\nobject (Customer Specification)\nSpecifies the customer a task belongs to. You must provide exactly one of the values.\npublic class TaskWrapper {\n        public String id;\n        public AssigneeWrapper assignee;\n        public String body;\n        public DateTime dueAt;\n        public CustomerWrapper customer;\n\n        public TaskWrapper(String id, AssigneeWrapper assignee, String body, DateTime dueAt, CustomerWrapper customer) {\n            this.id = id;\n            this.assignee = assignee;\n            this.body = body;\n            this.dueAt = dueAt;\n            this.customer = customer;\n        }\n    }\n\n    public class CustomerWrapper {\n        public String emailAddress;\n\n        public CustomerWrapper(String email) {\n            this.emailAddress = email;\n        }\n    }\n\n    public class AssigneeWrapper {\n        public String inboxId;\n        public String agentId;\n\n        public AssigneeWrapper(String inboxId) {\n            this.inboxId = inboxId;\n        }\n        public AssigneeWrapper(String inboxId, String agentId) {\n            this.inboxId = inboxId;\n            this.agentId = agentId;\n        }\n    }\npublic static void createTaskToRescheduleAppointment(String customerEmail, String previousDate, String newDate) {\n        String taskBody =\n             '&lt;strong&gt;Appointment Rescheduled:&lt;/strong&gt; &lt;br&gt;Your appointment has been rescheduled to ' +\n             newDate +\n             ' from &lt;strong&gt;' +\n             previousDate+\n             '&lt;/strong&gt;.&lt;br/&gt;';\n\n         try {\n             // Implement logic to get the inbox ID according to your needs.\n             String inboxId = getInboxId();\n\n            AssigneeWrapper assignee = new AssigneeWrapper(inboxId);\n            CustomerWrapper customer = new CustomerWrapper(customerEmail);\n\n            // Either Create a method to get the dueAt date for the new task or use any value directly for the due date according to your requirement.\n             DateTime dueAt = getRescheduleDueDate();\n\n            TaskWrapper task = new TaskWrapper(null, assignee, taskBody, dueAt, customer);\n\n            createTask(task);\n         } catch (Exception e) {\n             // handle the catch block according to your requirement.\n         }\n     }\npublic static void createTask(TaskWrapper task) {\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (task != null) {\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createTaskOnGladly(task);\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;private static HttpResponse createTaskOnGladly(TaskWrapper gladlyTaskWrapper) {\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String requestBody = JSON.serialize(gladlyTaskWrapper);\n\n&nbsp;&nbsp;String GLADLY_ENDPOINT = '&lt;organization&gt;.gladly.com/api/v1/tasks';\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpRequest req = new HttpRequest();\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.setEndpoint(GLADLY_ENDPOINT);\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.setMethod('POST');\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.setHeader('Content-Type', 'application/json;charset=UTF-8');\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.setBody(requestBody);\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpResponse response = (new Http()).send(req);\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Get the status code of the API request and handle additional features\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (response.getStatusCode() == {Status Code to check}) {\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return response;\n\n&nbsp;&nbsp;&nbsp;&nbsp;}\n```\n\nWhat this integration actually buys you is reliability. Tasks get created when they should, with the right information, assigned to the right place - not when someone remembers to create them manually.\n\nThe wrapper class pattern keeps the code maintainable as requirements evolve. The method separation keeps concerns clean - one method builds the task, one sends it, and the calling code doesn't need to know about either. When Gladly changes something about its API, or your business rules around inbox assignment change, you know exactly where to go.\n\nThe real work after getting this running is the error handling and observability you build around it. What happens when the callout fails? What happens when Gladly returns an unexpected status? How will you know if tasks stop being created? Those questions are worth answering before you put this in production, not after.\n\nInnostax specializes in managed engineering teams and was founded in 2014, and is headquartered in Framingham, Massachusetts. We establish engineering teams with accountability as a priority for both startups and enterprises, helping them achieve consistent software velocity with no customer churn.", "url": "https://wpnews.pro/news/streamlining-gladly-task-creation-with-apex-code", "canonical_source": "https://dev.to/sahil_khurana_486f374ecf2/streamlining-gladly-task-creation-with-apex-code-c79", "published_at": "2026-06-29 05:13:00+00:00", "updated_at": "2026-06-29 05:26:57.739558+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Gladly", "Salesforce", "Apex"], "alternates": {"html": "https://wpnews.pro/news/streamlining-gladly-task-creation-with-apex-code", "markdown": "https://wpnews.pro/news/streamlining-gladly-task-creation-with-apex-code.md", "text": "https://wpnews.pro/news/streamlining-gladly-task-creation-with-apex-code.txt", "jsonld": "https://wpnews.pro/news/streamlining-gladly-task-creation-with-apex-code.jsonld"}}