← Back to list

Abandoning Scheduled Callback Calls in Amazon Connect

While managing an Amazon Connect instance for a call center, I recently ran into an interesting request:

Abhinav Chittora in AWS in Plain English · 2025-09-29 16:01 · 1 claps · 2.7 min read
#amazon-connect #aws #aws-lambda #call-center #callback-queue
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

Abandoning Scheduled Callback Calls in Amazon Connect

While managing an Amazon Connect instance for a call center, I recently ran into an interesting request:

Due to a false positive issue, 35 calls had been scheduled as callbacks, and the business wanted to abandon them.

Since Amazon Connect doesn’t provide an out-of-the-box option to selectively abandon scheduled callbacks, I decided to write a Lambda function to handle this task. The function searches for queued callback contacts and abandons them, while keeping the most recent ones intact.

The Approach

The Lambda function performs the following steps:

  1. Query queued callback contacts using SearchContactsCommand.
  2. Sort them by initiation time (newest first).
  3. Keep the most recent 5 contacts (just as a safeguard).
  4. Abandon the rest by invoking StopContactCommand.
  5. Return results in a structured format so you can review what was kept vs. abandoned.
const { ConnectClient, SearchContactsCommand, StopContactCommand } = require('@aws-sdk/client-connect');

const connect = new ConnectClient({});

exports.handler = async (event) => {
    const instanceId = process.env.INSTANCE_ID || event.instanceId;
    const queueId = process.env.QUEUE_ID || event.queueId;
    const action = event.action || 'list'; // 'list' or 'abandon'

    if (!instanceId) {
        return {
            statusCode: 400,
            body: JSON.stringify({ error: 'Instance ID required' })
        };
    }

    try {
        // Search for queued callback contacts in the last 2 hours
        const result = await connect.send(new SearchContactsCommand({
            InstanceId: instanceId,
            TimeRange: {
                Type: 'INITIATION_TIMESTAMP',
                StartTime: new Date(Date.now() - 2 * 60 * 60 * 1000),
                EndTime: new Date()
            },
            SearchCriteria: {
                InitiationMethods: ['CALLBACK'],
                Channels: ['VOICE'],
                QueueIds: [queueId],
                ContactStates: ['QUEUED']
            }
        }));

        const contacts = result.Contacts || [];

        // Sort by initiation time (newest first)
        const sortedContacts = contacts.sort((a, b) =>
            new Date(b.InitiationTimestamp) - new Date(a.InitiationTimestamp)
        );

        const latest5 = sortedContacts.slice(0, 5);
        const toAbandon = sortedContacts.slice(5);

        console.log(`Total queued contacts: ${contacts.length}`);
        console.log(`Keeping latest 5: ${latest5.map(c => c.Id)}`);
        console.log(`To abandon: ${toAbandon.length}`);

        // Prepare list for review
        const abandonList = toAbandon.map(contact => ({
            contactId: contact.Id,
            scheduledTime: contact.ScheduledTimestamp || contact.InitiationTimestamp,
            initiationTime: contact.InitiationTimestamp
        }));

        // Abandon if requested
        if (action === 'abandon' && toAbandon.length > 0) {
            const abandonResults = [];
            for (const contact of toAbandon) {
                try {
                    await connect.send(new StopContactCommand({
                        ContactId: contact.Id,
                        InstanceId: instanceId
                    }));
                    abandonResults.push({
                        contactId: contact.Id,
                        status: 'abandoned',
                        scheduledTime: contact.ScheduledTimestamp || contact.InitiationTimestamp
                    });
                } catch (error) {
                    abandonResults.push({
                        contactId: contact.Id,
                        status: 'failed',
                        error: error.message
                    });
                }
            }
            return {
                statusCode: 200,
                body: JSON.stringify({
                    abandonResults,
                    kept: latest5.length,
                    abandoned: abandonResults.length
                })
            };
        }

        // Default: list only
        return {
            statusCode: 200,
            body: JSON.stringify({
                totalContacts: contacts.length,
                keeping: latest5.map(c => ({ id: c.Id, time: c.InitiationTimestamp })),
                toAbandon: abandonList
            })
        };
    } catch (error) {
        console.error('Error:', error);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

Sample Test Events

You can test this Lambda using simple JSON payloads in the AWS Lambda console or via the AWS CLI.

List Mode (Preview Only)

This will only list the queued callback contacts and show which ones would be abandoned.

I use this function to list and abondon calls which are scheduled for callback.

{
  "instanceId": "your-connect-instance-id",
  "queueId": "your-callback-queue-id",
  "action": "list"
}

Abandon Mode (Execute)

This will actually stop (abandon) the extra queued callback contacts, keeping only the latest 5.

{
  "instanceId": "your-connect-instance-id",
  "queueId": "your-callback-queue-id",
  "action": "abandon"
}

Conclusion

This small Lambda function came in handy when we needed to clean up unintended callback contacts in Amazon Connect. It ensures control over which scheduled calls are abandoned, while retaining recent ones just in case they’re still relevant.

A message from our Founder

Hey, Sunil here. I wanted to take a moment to thank you for reading until the end and for being a part of this community.

Did you know that our team run these publications as a volunteer effort to over 3.5m monthly readers? We don’t receive any funding, we do this to support the community. ❤️

If you want to show some love, please take a moment to follow me on LinkedIn, TikTok, **Instagram. You can also subscribe to our [weekly newsletter](https://newsletter.plainenglish.io/)**.

And before you go, don’t forget to clap and follow the writer️!


메타데이터
post_id
0d42e4929997
slug
abandoning-scheduled-callback-calls-in-amazon-connect-0d42e4929997
url
https://aws.plainenglish.io/abandoning-scheduled-callback-calls-in-amazon-connect-0d42e4929997
canonical_url
https://aws.plainenglish.io/abandoning-scheduled-callback-calls-in-amazon-connect-0d42e4929997
author_url
https://medium.com/@bijolianabhi
status
ok
fetched_at
2026-08-06 08:14:01