In this post, I’ll guide you through the creation of a secure customer support system leveraging various AWS services, integrated with Slack for streamlined communication. This architecture effectively manages support tickets while ensuring data security and efficient workflow.
Project Overview
The system facilitates customer ticket creation and management through a robust backend, utilizing the following components:
- Ticket Creation: Customers initiate support requests via a user-friendly interface, which sends the data to AWS API Gateway.
- Data Storage: Upon receiving the request, API Gateway triggers a Lambda function that processes the ticket information and stores it in DynamoDB.
- Notifications: An SNS (Simple Notification Service) notification is dispatched to alert support agents of the new ticket, ensuring they can respond promptly.
- Ticket Retrieval: Support agents can retrieve tickets by sending a request to another API Gateway endpoint. This request invokes a Lambda function that fetches ticket details from DynamoDB using the ticket ID.
- Customer Messaging: To communicate with customers, another Lambda function is invoked, sending messages through Slack's API.
- Ticket Closure: When the status of a ticket changes to "closed," a Lambda function triggers to transfer the ticket data from DynamoDB to S3 and to an archival DynamoDB table.
Step-by-Step Implementation
1. Create DynamoDB for Ticket Storage
a. Set Up a New Table
- In the AWS Management Console, navigate to DynamoDB and select “Create table.”
- Configure:
- Table Name: SupportTickets
- Primary Key: TicketID (String)
- Capacity: Keep default settings for initial testing.
- Save the table.
b. Add Attributes
Consider adding these fields:
- CustomerName (String)
- IssueDescription (String)
- Status (String) - Default: "Open"
1.1 Create an Archival DynamoDB Table
Repeat the above steps to create another table:
- Table Name: ArchivedTickets
- Primary Key: TicketID (String)
Note: Enable DynamoDB Streams on both tables. This feature provides a real-time data stream of item-level changes in a DynamoDB table. This feature is beneficial for tracking changes to your customer support tickets
2. Configure Amazon SNS for Notifications
a. Create a New Topic
- Go to SNS in the AWS Console.
- Select “Create topic” and name it SupportTicketNotifications.
b. Subscribe Agents
- Open SupportTicketNotifications.
- Create a subscription for each agent using Email/SMS and input their details.
3. Create AWS Lambda Functions
This function handles incoming ticket creation requests. It processes the ticket information, stores it in DynamoDB, and sends a notification through SNS to inform relevant parties of the new ticket.
a. Function Setup
- Navigate to Lambda in the AWS Console.
- Create New Function: Click "Create function."
- Configuration:
- Name: CreateTicket
- Runtime: Python (or Node.js)
- Permissions: Create a new role with Lambda permissions.
- Save: Click “Create.”
b. Code the CreateTicket Function
- Replace the default code with this:
import json
import boto3
from uuid import uuid4
dynamodb = boto3.resource('dynamodb')
sns = boto3.client('sns')
table = dynamodb.Table('SupportTickets')
def lambda_handler(event, context):
body = json.loads(event['body'])
ticket_id = str(uuid4())
response = table.put_item(
Item={
'TicketID': ticket_id,
'CustomerName': body['customerName'],
'IssueDescription': body['issueDescription'],
'Status': 'Open'
}
)
message = f"New ticket created: {ticket_id} - {body['customerName']}"
sns.publish(TopicArn='arn:aws:sns:eu-north-1:533267368463:SupportTicketNotifications', Message=message)
return {
'statusCode': 201,
'body': json.dumps({'TicketID': ticket_id})
}
Note
Make sure to select and attach the required policy to the Lambda execution role to ensure it has the necessary permissions for your function's operations.
3.1 Create Another AWS Lambda Functions for retrieve
messages
- Create a new function called GetTicket by following the same steps used to set up the Lambda function for creating a ticket.
This function retrieves ticket details based on the ticket ID provided by the support agent. It queries the DynamoDB table to fetch and return the ticket information.
c. Code the GetTicket Function
import json
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('SupportTickets')
def lambda_handler(event, context):
ticket_id = event['pathParameters']['ticketId']
response = table.get_item(Key={'TicketID': ticket_id})
item = response.get('Item')
if item:
return {
'statusCode': 200,
'body': json.dumps(item)
}
else:
return {
'statusCode': 404,
'body': json.dumps({'error': 'Ticket not found'})
}
Note
Make sure to select and attach the required policy to the Lambda execution role to ensure it has the necessary permissions for your function's operations.
4. Slack Integration for Real-Time Messaging
Step 1: Set Up Incoming Webhook in Slack
- Visit Slack API and sign in.
- Create a new app and enable Incoming Webhooks.
- Generate a Webhook URL to use within Lambda for message sending.
Step 2 Create Another Lambda function for sendmessage
This function sends real-time messages to the designated Slack channel, facilitating communication with customers. It ensures that updates or responses related to the ticket are communicated promptly.
c. Code the sendmessage function Function
import json
import requests
import os
def lambda_handler(event, context):
# Extract the message from the API Gateway event body
try:
message = json.loads(event['body']).get('text', 'Default message to Slack')
except json.JSONDecodeError:
message = 'Default message to Slack'
# Define Slack webhook URL from environment variable
slack_webhook_url = os.environ['SLACK_WEBHOOK_URL']
# Prepare the payload to send to Slack
slack_payload = {
'text': message
}
# Send the message to Slack
response = requests.post(slack_webhook_url, json=slack_payload)
# Check for success or error in the Slack response
if response.status_code == 200:
return {
'statusCode': 200,
'body': json.dumps('Message sent to Slack successfully!')
}
else:
return {
'statusCode': 500,
'body': json.dumps(f'Failed to send message to Slack: {response.text}')
}
Note
Ensure that you use environment variables to securely store this information. You can utilize Secrets Manager for added security. Additionally, install the Requests library locally and create a ZIP file for deployment.
5. Set Up API Gateway
a. Create API
- Open API Gateway in the AWS Console.
- New API: Select "Create API."
- Type: Choose "HTTP API."
- API Name: CustomerSupportAPI
- Save: Click “Create.”
b. Define Endpoints
- Create Ticket Endpoint:
- Path: /createticket
- Method: POST
- Integration: Connect to a Lambda function for createticket
- Retrieve Ticket Endpoint:
- Path: /tickets/{ticketId}
- Method: GET
- Integration: Connect to another Lambda function for retrieving details.
- Send Message Endpoint:
- Path: /sendmessage
- Method: post
- Integration: Connect to another Lambda function for sending messages.
6. Set Up Amazon S3 for Document Storage
a. Create S3 Bucket
- Open S3 in AWS Console.
- New Bucket: Click “Create bucket.”
- Name: support-documents
- Region: Same as other resources
- Save: Click “Create.”
b. Set Permissions
- Adjust S3 bucket policy to allow Lambda function access.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::533267368463:role/service-role/ArchiveClosedTickets-role-qbc73yay"
},
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::support-ticket-archive/*"
}
]
}
7 Create the final lambda function for ArchiveClosedTickets
This function is triggered when a ticket status changes to closed. It archives the ticket by moving it from the DynamoDB table to an S3 bucket and updating the archived tickets table.
code for this lambda
import json
import boto3
import datetime
import logging
# Set up logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
s3 = boto3.client('s3')
dynamodb = boto3.resource('dynamodb')
archive_table = dynamodb.Table('ArchivedTickets')
archive_bucket = 'support-ticket-archive'
tickets_table = dynamodb.Table('SupportTickets')
def lambda_handler(event, context):
for record in event['Records']:
if record['eventName'] == 'MODIFY':
new_image = record['dynamodb']['NewImage']
old_image = record['dynamodb']['OldImage']
if new_image['Status']['S'] == 'closed' and old_image['Status']['S'] != 'closed':
ticket_id = new_image['TicketID']['S']
# Log ticket ID
logger.info(f'Processing ticket: {ticket_id}')
# Create JSON object for the archived ticket
ticket_data = {
'TicketID': ticket_id,
'CustomerName': new_image.get('CustomerName', {}).get('S', 'Unknown'),
'IssueDescription': new_image.get('IssueDescription', {}).get('S', 'No description'),
'Status': new_image['Status']['S'],
'Comments': new_image.get('Comments', {}).get('S', ''),
}
# Define file path in S3
file_name = f"{ticket_id}.json"
# Upload JSON to S3
s3.put_object(
Bucket=archive_bucket,
Key=file_name,
Body=json.dumps(ticket_data)
)
# Get S3 URL
s3_url = f"s3://{archive_bucket}/{file_name}"
# Save archive metadata to DynamoDB
archive_table.put_item(
Item={
'TicketID': ticket_id,
'DateArchived': datetime.datetime.utcnow().isoformat(),
'S3URL': s3_url
}
)
# Log before deletion
logger.info(f'Deleting ticket from SupportTickets: {ticket_id}')
# Delete the original ticket from DynamoDB
response = tickets_table.delete_item(
Key={
'TicketID': ticket_id
}
)
# Log the response from the delete operation
logger.info(f'Delete response: {response}')
return {'status': 'success'}
Test All Components
Test createticket lambda function
-Create test event
Test the GetTicket Lambda Function
- Create a test event to validate the code functionality. ###Test archiveticket lambda
test api from postman
Conclusion
In conclusion, the Secure Customer Support System leveraging AWS services and Slack provides a robust framework for managing customer inquiries and enhancing communication. By integrating API Gateway, Lambda functions, DynamoDB, SNS, and S3, we have created a scalable and efficient solution that ensures real-time responses and secure handling of customer data. The system's architecture allows for easy ticket creation, retrieval, and closure while facilitating seamless interactions with customers via Slack. This project not only streamlines support operations but also highlights the potential of cloud technologies in delivering high-quality customer service. As businesses increasingly seek to enhance their customer support capabilities, adopting such innovative solutions will be crucial in meeting customer expectations and driving satisfaction.