diff --git a/onsite_helper.py b/onsite_helper.py new file mode 100644 index 0000000..68fc510 --- /dev/null +++ b/onsite_helper.py @@ -0,0 +1,110 @@ +import os +import json +import boto3 +import logging +import requests +from openai import OpenAI +import azure.functions as func +from twilio.rest import Client + +#------------------------------------# +# Load environment variables +#------------------------------------# +SEC_PIN = os.environ["SECURITY_PIN"] + +#------------------------------------# +# Twilio Client +#------------------------------------# +CLIENT = Client() + +#------------------------------------# +# Initialize SQS client +#------------------------------------# +sqs = boto3.client('sqs') +queue_url = os.environ["AMAZON_QUEUE_ENDPOINT"] + +def save_sms_to_sqs(sender, message, date_sent=None): + """ + Save SMS message details into SQS queue. + """ + try: + message_body = { + 'sender': sender, + 'message': message, + 'date_sent': date_sent if date_sent else datetime.utcnow().isoformat() + } + response = sqs.send_message( + QueueUrl=queue_url, + MessageBody=json.dumps(message_body) + ) + return f"Message from {sender} saved successfully." + except Exception as e: + logging.error(f"Error saving message to SQS: {e}") + return f"Error saving message. {e}" + +#------------------------------------# +# Security check +#------------------------------------# +def process_incoming_message(PIN, incoming_message, send_to, send_from): + """ + Generate a reply based on the incoming message. + + Parameters + ---------- + PIN : str + Security PIN + incoming_message : str + Incoming message from Twilio + + Returns + ------- + message : str + Reply message + """ + if incoming_message.strip() == PIN: + return """Welcome to the new internal Hess Services SMS AI service. + - I can lookup general information about jobs, parts, sales orders, + - among others. + - Text 'about' to see this message again""" + else: + messages = CLIENT.messages.list(from_=send_to, to=send_from) + sent_pin = False + for message in messages: + if message.body.strip() == PIN: + sent_pin = True + if sent_pin: + follow_up_reply = get_follow_up_text(send_to=send_to, + send_from=send_from, + incoming_message=incoming_message) + return follow_up_reply + else: + return f"Please provide security PIN to continue." + +#------------------------------------# +# Follow up text +#------------------------------------# +def get_follow_up_text(send_to, send_from, incoming_message): + """Send follow up text + + Parameters + ---------- + send_to : str + Phone number to send text to + send_from : str + Phone number to send text from + incoming_message : str + Incoming message from Twilio + + Returns + ------- + message : str + Response from the AI to the user + """ + if incoming_message == 'about': + return """Welcome to the new Luis AI reminder assistant. + - I can schedule calls and text reminders for you. + - I can answer any questions, within reason. + - Text 'about' to see this message again""" + else: + result = save_sms_to_sqs(send_to, incoming_message) + return 'Processing reply...' diff --git a/requirements.txt b/requirements.txt index 1259cbd..7fe8182 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ azure-functions==1.17.0 twilio==8.10.2 openai==1.3.2 sentry-sdk +boto3==1.26.149 \ No newline at end of file diff --git a/sms-helper/__init__.py b/sms-helper/__init__.py index 373f703..bf15f62 100644 --- a/sms-helper/__init__.py +++ b/sms-helper/__init__.py @@ -3,8 +3,8 @@ import sentry_sdk import azure.functions as func # import __app__.helper as helper -# Use alternative helper to send less messages -import __app__.alternative_helper as alternative_helper +# import __app__.alternative_helper as alternative_helper +import __app__.onsite_helper as onsite_helper from sentry_sdk.integrations.serverless import serverless_function #------------------------------------# @@ -27,7 +27,9 @@ def main(req: func.HttpRequest) -> func.HttpResponse: send_from = req.params["To"] incoming_message = req.params["Body"].lower().strip() - # Reply to the user based on the incoming message + #--------------------------------------------------------------------------# + # Uncomment for use with helper.py + #--------------------------------------------------------------------------# # helper.process_incoming_message(os.environ["SECURITY_PIN"], # send_to, # send_from, @@ -38,12 +40,26 @@ def main(req: func.HttpRequest) -> func.HttpResponse: # ) #--------------------------------------------------------------------------# - # To reduce the number of messages you could use the 'alternative_helper' - # This one returns the response message as the HttpResponse. + # Uncomment for use with alternative_helper.py + # Reduces the number of messages send, returns the response message + # as the HttpResponse. + #--------------------------------------------------------------------------# + # pin = alternative_helper.SEC_PIN + # res = alternative_helper.process_incoming_message(PIN=pin, + # incoming_message=incoming_message, + # send_to=send_to, + # send_from=send_from) + # return func.HttpResponse(res, status_code=200) + + #--------------------------------------------------------------------------# + # Uncomment for use with onsite_helper.py + # This saves messages to AWS database, and then the messages are + # processed internally at HSI. This way we can reply with internal + # info + use local AI models + secure databases. #--------------------------------------------------------------------------# - pin = alternative_helper.SEC_PIN - res = alternative_helper.process_incoming_message(PIN=pin, + pin = onsite_helper.SEC_PIN + res = onsite_helper.process_incoming_message(PIN=pin, incoming_message=incoming_message, send_to=send_to, send_from=send_from) - return func.HttpResponse(res, status_code=200) + return func.HttpResponse(res, status_code=200) \ No newline at end of file