Skip to content

Commit

Permalink
Send Email to employees
Browse files Browse the repository at this point in the history
  • Loading branch information
docwho2 committed Nov 29, 2023
1 parent 675bf3f commit cf9a8d1
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 23 deletions.
6 changes: 6 additions & 0 deletions ChatGPT/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
<artifactId>sns</artifactId>
</dependency>

<!-- Send Email Messages -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ses</artifactId>
</dependency>

<!-- ChatGPT -->
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public ChatGPTSessionState(String phoneNumber, LexInputMode inputMode) {
// Mode specific prompting
switch (inputMode) {
case TEXT -> {
sb.append("I am interacting via SMS. Please keep answers very short and concise, preferably under 180 characters. Do not use markdown in responses. ");
sb.append("I am interacting via SMS. Please keep answers very short and concise, preferably under 180 characters. ");
sb.append("To interact with an employee suggest the person call ").append(System.getenv("MAIN_NUMBER")).append(" and ask to speak to that person. ");
sb.append("Do not provide employee phone numbers.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.theokanning.openai.completion.chat.ChatFunction;
import com.theokanning.openai.service.FunctionExecutor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
Expand Down Expand Up @@ -42,7 +43,6 @@ public abstract class AbstractFunction<T> implements Cloneable {
@Setter(AccessLevel.PROTECTED)
private String callingNumber;


/**
* Define here since used by most the of the functions
*/
Expand All @@ -58,7 +58,7 @@ public abstract class AbstractFunction<T> implements Cloneable {
final var loc = System.getenv("SQUARE_LOCATION_ID");

squareEnabled = !((loc == null || loc.isBlank() || loc.equalsIgnoreCase("DISABLED")) || (key == null || key.isBlank() || loc.equalsIgnoreCase("DISABLED")));
System.out.println("Square Enabled check = " + squareEnabled);
log.debug("Square Enabled check = " + squareEnabled);
}

/**
Expand All @@ -73,20 +73,23 @@ public static void init() {
// Use Reflections to get all classes in the package
Reflections reflections = new Reflections(AbstractFunction.class.getPackage().getName());
final var allClasses = reflections.getSubTypesOf(AbstractFunction.class);


// Remove any further Abstract Classes
allClasses.removeIf(c -> Modifier.isAbstract(c.getModifiers()));

// Loop through each class and instantiate using the default constructor
for (var clazz : allClasses) {
try {
final var func = (AbstractFunction) clazz.getDeclaredConstructor().newInstance();
if (func.isEnabled()) {
System.out.println("Instantiated class: " + clazz.getName());
log.debug("Instantiated class: " + clazz.getName());
functions.add(func);
} else {
System.out.println("Class Disabled, Ignoring: " + clazz.getName());
log.debug("Class Disabled, Ignoring: " + clazz.getName());
}

} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
log.error("Error processing Function Classes",e);
}
}
inited = true;
Expand Down Expand Up @@ -125,7 +128,7 @@ public static FunctionExecutor getFunctionExecuter(LexV2Event lexRequest) {
}

} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
log.error("Error cloning Functions",ex);
}
});
return new FunctionExecutor(list.stream().map(f -> f.getChatFunction()).toList());
Expand Down Expand Up @@ -171,13 +174,12 @@ private ChatFunction getChatFunction() {
.executor(getRequestClass(), getExecutor())
.build();
}



private static final Pattern US_E164_PATTERN = Pattern.compile("^\\+1[2-9]\\d{2}[2-9]\\d{6}$");

/**
* Is the given number a valid US Phone number
*
*
* @param number
* @return
*/
Expand All @@ -187,7 +189,6 @@ protected static boolean isValidUSE164Number(String number) {
}
return US_E164_PATTERN.matcher(number).matches();
}


/**
* Override and return false to disable a particular function
Expand Down
86 changes: 86 additions & 0 deletions ChatGPT/src/main/java/cloud/cleo/squareup/functions/SendEmail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package cloud.cleo.squareup.functions;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import java.util.function.Function;
import software.amazon.awssdk.services.ses.SesClient;

/**
* Send an Email message
*
* @author sjensen
* @param <Request>
*/
public class SendEmail<Request> extends AbstractFunction {

@Override
public String getName() {
return "send_email_message";
}

@Override
public String getDescription() {
return "Send Email message to an employee, use to relay information to an employee";
}

@Override
public Class getRequestClass() {
return Request.class;
}

/**
*
* @return
*/
@Override
public Function<Request, Object> getExecutor() {
return (var r) -> {

try {
final var ses = SesClient.create();
final var id = ses.sendEmail((email) -> {
email.destination(dest -> dest.toAddresses(r.employee_email))
.message((mesg) -> {
mesg.body((body) -> {
body.text(cont -> cont.data(r.message));
}).subject(cont -> cont.data(r.subject));
}).source("[email protected]");
});

log.info("Sent email to " + r.employee_email + " with id " + id);
log.info("Subject: " + r.subject);
log.info("Message: " + r.message);
return mapper.createObjectNode().put("status", "SUCCESS").put("message", "The email has been successfuly sent.");
} catch (Exception e) {
log.error("Unhandled Error", e);
return mapper.createObjectNode().put("status", "FAILED").put("message", "An error has occurred, the email could not be sent.");
}
};
}

private static class Request {

@JsonPropertyDescription("The employee email address")
@JsonProperty(required = true)
public String employee_email;

@JsonPropertyDescription("Subject for the email message")
@JsonProperty(required = true)
public String subject;

@JsonPropertyDescription("The message body to relay to the employee")
@JsonProperty(required = true)
public String message;
}

/**
* Square must be enabled or their won't be a way to get email addresses
*
* @return
*/
@Override
protected boolean isEnabled() {
return squareEnabled;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public Function<Request, Object> getExecutor() {
return mapper.createObjectNode().put("message", "No categories match the search query");
}
} catch (Exception ex) {
log.error("Unhandled Error",ex);
return mapper.createObjectNode().put("error_message", ex.getLocalizedMessage());
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package cloud.cleo.squareup.functions;

import com.fasterxml.jackson.databind.node.ObjectNode;
Expand Down Expand Up @@ -78,6 +74,7 @@ public Function<Request, Object> getExecutor() {

return json;
} catch (Exception ex) {
log.error("Unhandled Error",ex);
return mapper.createObjectNode().put("error_message", ex.getLocalizedMessage());
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public Function<Request, Object> getExecutor() {
return mapper.createObjectNode().put("message", "No items match the search query");
}
} catch (Exception ex) {
log.error("Unhandled Error",ex);
return mapper.createObjectNode().put("error_message", ex.getLocalizedMessage());
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package cloud.cleo.squareup.functions;

import com.fasterxml.jackson.annotation.JsonPropertyDescription;
Expand All @@ -14,7 +10,7 @@
import lombok.Data;

/**
* Return team members from Square API
* Return Employees (team members) from Square API
*
* @author sjensen
* @param <Request>
Expand All @@ -29,7 +25,7 @@ public String getName() {

@Override
public String getDescription() {
return "Return the Team members (employees) names and phone numbers for this store location, do not give the phone numbers to the callers or give out the whole list.";
return "Return the Emoloyee names and phone numbers for this store location, do not give the phone numbers to the callers or give out the whole list.";
}

@Override
Expand All @@ -54,6 +50,7 @@ public Function<Request, Object> getExecutor() {
.map(tm -> new Response(tm))
.toList();
} catch (Exception ex) {
log.error("Unhandled Error",ex);
return mapper.createObjectNode().put("error_message", ex.getLocalizedMessage());
}
};
Expand All @@ -66,13 +63,16 @@ private static class Response {
String first_name;
@JsonPropertyDescription("Employee Last Name")
String last_name;
@JsonPropertyDescription("Employee Phone number in E164 format, to be used for call transfers, do not reveal to caller")
@JsonPropertyDescription("Employee Phone number in E164 format, to be used for call transfers, do not reveal or privide this directly")
String phone_number;
@JsonPropertyDescription("Employee Email address, to be used to send messages, do not reveal or provide this directly")
String email;

public Response(TeamMember tm){
this.first_name = tm.getGivenName();
this.last_name = tm.getFamilyName();
this.phone_number = tm.getPhoneNumber();
this.email = tm.getEmailAddress();
}
}

Expand Down
2 changes: 2 additions & 0 deletions template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ Resources:
Action:
# Allow send of SMS messages via SNS
- sns:Publish
# Send Emails
- ses:SendEmail
Resource: '*'

ChatGPTLogGroup:
Expand Down

0 comments on commit cf9a8d1

Please sign in to comment.