-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlambda_function.py
More file actions
157 lines (137 loc) · 7.27 KB
/
lambda_function.py
File metadata and controls
157 lines (137 loc) · 7.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from __future__ import print_function
import json
import boto3
import time
import urllib
import requests
import re
import mimetypes
import base64
import os
# Purpose: Accept email from SES (defined in SES rule), SES writes email to S3 Bucket, Lambda has a trigger on new objects being put in S3 bucket.
# Lambda function calls appropriate Zendesk instance and creates ticket with details from the email. Zendesk token is stored in KMS.
# Modification of: https://gist.github.com/ninajlu/d0b939ee34257fe2b21ae935321895d3 / https://medium.com/@ninajlu/using-aws-lambda-s3-to-automatically-create-zendesk-tickets-from-looker-scheduled-reports-816c45e2fbb3
# Import the email modules we'll need
from email import policy
from email.parser import Parser
# Get the service resource
s3 = boto3.client('s3')
tests3 = boto3.resource(u's3')
emailRegex = r"([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)"
nameRegex = r"(?:(\"?(?:.*)\"?)\s)?"
# insert_data function for creating a Zendesk ticket from the data
def insert_data(emailData):
#Set the Body of your Ticket
html_body = emailData.get_body(preferencelist=('html', 'plain')).get_content()
attachments = emailData.iter_attachments()
# print("html_body: ", html_body)
toEmail = re.search(emailRegex, emailData['to']).group(1)
# print("toEmail: ", toEmail)
# Create ticket in different zendesk instances based on which mailbox received message
if toEmail == 'myemail@mydomain.com':
brand_id = 01234567890123
zendesk_instance = 'myinstance1'
elif toEmail == 'myemail2@mydomain.com':
brand_id = 01234567890124
zendesk_instance = 'myinstance2'
elif toEmail == 'myemail3@mydomain.com':
brand_id = 01234567890125
zendesk_instance = 'myinstance3'
else:
brand_id = 01234567890126 # Catch-all
zendesk_instance = 'myinstance4'
subject = emailData['subject']
#is_public determines whether or not the comment will be internal to your organization or sent to a user.
is_public = True
# set tags to identify tickets created by this service
tags = list()
# tags.append('Email2APIService') # Append a tag to your tickets for identification purposes
requesterEmail = re.search(emailRegex, emailData['from']).group(1)
requesterName = re.search(nameRegex, emailData['from']).group(1)
if not requesterName: # set the requesterName to the requester email if there is no requester name
requesterName = requesterEmail
# Set the request parameters
headers = {'content-type': 'application/json'}
# Store the token credential as a Lambda environment variable
if zendesk_instance == 'myinstance1':
url = 'https://myinstance1.zendesk.com/api/v2/tickets.json'
user = 'myuser/token'
ENCRYPTED = os.environ['myinstance1_token']
# Decrypt code should run once and variables stored outside of the function
# handler so that these are decrypted once per container
DECRYPTED = boto3.client('kms').decrypt(
CiphertextBlob=base64.b64decode(ENCRYPTED),
EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')
else:
url = 'https://myinstance2.zendesk.com/api/v2/tickets.json'
user = 'myuser/token'
ENCRYPTED = os.environ['myinstance2_token']
# Decrypt code should run once and variables stored outside of the function
# handler so that these are decrypted once per container
DECRYPTED = boto3.client('kms').decrypt(
CiphertextBlob=base64.b64decode(ENCRYPTED),
EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')
# Upload Attachments
if attachments:
attach_upload = list()
for attachment in attachments:
# print("attachment: ", attachment)
attach_filename = attachment.get_filename()
attach_header = {'content-type': attachment.get_content_type()}
# print("attach_filename: ", attach_filename)
# print("attach_type: ", attach_header)
attachurl = 'https://' + zendesk_instance + '.zendesk.com/api/v2/uploads?filename=' + attach_filename
# print("attachurl: ", attachurl)
attachfile = attachment.get_content()
# print("attachfile: ", attachfile)
attach_response = requests.post(attachurl, data=attachfile, auth=(user, DECRYPTED), headers=attach_header)
attach_response_json = json.loads(attach_response.text)
# print("attach_response: ", json.dumps(attach_response_json))
# print("upload token debug: ", attach_response_json['upload']['token'])
attach_upload.append(attach_response_json['upload']['token'])
# print("attach_upload list: ", attach_upload)
attach_data = {'ticket': {'brand_id': brand_id, 'subject': subject, 'tags': tags, 'is_public': is_public, 'comment': {'uploads': attach_upload, 'public': is_public, 'html_body': html_body}, 'requester': { 'name': requesterName, 'email': requesterEmail } }}
attach_payload = json.dumps(attach_data)
response = requests.post(url, data=attach_payload, auth=(user, DECRYPTED), headers=headers)
else:
data = {'ticket': {'brand_id': brand_id, 'subject': subject, 'tags': tags, 'is_public': is_public, 'comment': {'public': is_public, 'html_body': html_body}, 'requester': { 'name': requesterName, 'email': requesterEmail } }}
# Create a JSON payload
payload = json.dumps(data)
# Do the HTTP post request w/out attachments
response = requests.post(url, data=payload, auth=(user, DECRYPTED), headers=headers)
# Check for HTTP codes other than 201 (Created)
if response.status_code != 201:
print('Status:', response.status_code, 'Problem with the request. Exiting.')
exit()
# Report success
print('Successfully created the ticket.')
# lambda_handler is the main function in lambda function
def lambda_handler(event,context):
print("event: ", event)
source_bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
copy_source = {'Bucket':source_bucket , 'Key':key}
try:
bucket = tests3.Bucket(source_bucket)
obj = bucket.Object(key=key)
response = obj.get()
print("response from file object")
print(response)
# lines = response['Body'].read().decode('utf-8').splitlines(True)
emailBody = response['Body'].read().decode('utf-8')
# msg = BytesParser(policy=policy.default).parse(emailBody)
msg = Parser(policy=policy.default).parsestr(emailBody)
# print("msg details")
# print('To:', msg['to'])
# print('From:', msg['from'])
# print('Subject:', msg['subject'])
# print("emailBody: ", emailBody)
# print(emailBody)
insert_data(msg)
s3.delete_object(Bucket=source_bucket, Key=key) # Delete the object from S3 - comment this out if you want to keep it
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, source_bucket))
raise e