diff --git a/groupTasks/groups/jnx-mail-shx-textgenerator/email.html b/groupTasks/groups/jnx-mail-shx-textgenerator/email.html new file mode 100644 index 0000000..e5ee0ec --- /dev/null +++ b/groupTasks/groups/jnx-mail-shx-textgenerator/email.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + +
+ + + + + + +
+

{{salutation}}

+

{{text_1}}

+

{{text_2}}

+

{{text_3}}

+ {{ctaButton}} +
+

{{text_4}}

+

{{text_5}}

+

{{text_6}}

+

{{bestRegards}}

+
+ {{footer}} +
+ + + + \ No newline at end of file diff --git a/groupTasks/groups/jnx-mail-shx-textgenerator/email.txt b/groupTasks/groups/jnx-mail-shx-textgenerator/email.txt new file mode 100644 index 0000000..1406c9c --- /dev/null +++ b/groupTasks/groups/jnx-mail-shx-textgenerator/email.txt @@ -0,0 +1,22 @@ +{{salutation}} + +{{text_1}} + +{{text_2}} + +{{text_3}} + +{{ctaButton}}: +--- +{{CTA_Link}} +--- + +{{text_4}} + +{{text_5}} + +{{text_6}} + +{{bestRegards}} + +{{footer}} \ No newline at end of file diff --git a/groupTasks/groups/jnx-mail-shx-textgenerator/index.json b/groupTasks/groups/jnx-mail-shx-textgenerator/index.json new file mode 100644 index 0000000..74e4eeb --- /dev/null +++ b/groupTasks/groups/jnx-mail-shx-textgenerator/index.json @@ -0,0 +1,43 @@ +{ + "category": "Jannex", + "name": "Kaltakquise für Shinnex Textegenerator", + "globalInputs": [], + "tasks": [ + { + "name": "Gutscheincodes für Bestellung erstellen", + "onFinish": "next", + "undoPossible": false, + "repeatPossible": true, + "scriptPath": "script.py", + "parameters": [ + { + "parameterName": "websiteURL", + "type": "text", + "displayName": "URL der Webseite" + }, + { + "parameterName": "companyName", + "type": "text", + "displayName": "Firmenname" + }, + { + "parameterName": "customerEmail", + "type": "text", + "displayName": "E-Mail vom Kunden", + "required": false + }, + { + "parameterName": "customerName", + "type": "text", + "displayName": "Vorname vom Kunden" + }, + { + "parameterName": "language", + "type": "select", + "displayName": "Sprache", + "options": ["de", "en"] + } + ] + } + ] +} diff --git a/groupTasks/groups/jnx-mail-shx-textgenerator/lang.json b/groupTasks/groups/jnx-mail-shx-textgenerator/lang.json new file mode 100644 index 0000000..a4425dd --- /dev/null +++ b/groupTasks/groups/jnx-mail-shx-textgenerator/lang.json @@ -0,0 +1,26 @@ +{ + "de": { + "subject": "Aw: Textgenerator", + "salutation": "Hey {{customerName}},", + "text_1": "ich hoffe, bei euch im Shop läuft alles rund!", + "text_2": "Wir haben ein Tool entwickelt, das euch eine Menge Zeit sparen könnte: einen Textschild-Generator, der direkt farbige .3mf-Dateien erstellt. Mit diesem Generator könnt ihr problemlos alle Unicode-Zeichen und Emojis darstellen.", + "text_3": "Ihr könnt den Generator kostenlos auf unserer Webseite testen und die generierten Modelle herunterladen. Probiert es einfach aus und lasst uns wissen, wie ihr es findet ;)", + "text_4": "Falls ihr interessiert seid, das Tool auch kommerziell zu nutzen, bieten wir dementsperechend auch eine Lösung an.", + "text_5": "Habt ihr noch Fragen dazu? Meldet euch einfach bei mir!", + "text_6": "Freue mich auf eure Rückmeldung.", + "ctaButton": "Generator ansehen", + "bestRegards": "Mit freundlichen Grüßen\nJan Umbach" + }, + "en": { + "subject": "Re: Text generator", + "salutation": "Hey {{customerName}},", + "text_1": "I hope everything is going well in your shop!", + "text_2": "We have developed a tool that could save you a lot of time: a text sign generator that creates colored .3mf files directly. With this generator, you can easily display all Unicode characters and emojis.", + "text_3": "You can test the generator for free on our website and download the generated models. Just give it a try and let us know what you think ;)", + "text_4": "If you are interested in using the tool commercially, we also offer a corresponding solution.", + "text_5": "Do you have any questions about this? Just contact me!", + "text_6": "Looking forward to your feedback.", + "ctaButton": "View generator", + "bestRegards": "Best regards\nJan Umbach" + } +} diff --git a/groupTasks/groups/jnx-mail-shx-textgenerator/requirements.txt b/groupTasks/groups/jnx-mail-shx-textgenerator/requirements.txt new file mode 100644 index 0000000..baee381 --- /dev/null +++ b/groupTasks/groups/jnx-mail-shx-textgenerator/requirements.txt @@ -0,0 +1,5 @@ +requests==2.31.0 +reportlab==4.1.0 +pdfkit==1.0.0 +qrcode==7.4.2 +PyPDF2==3.0.1 \ No newline at end of file diff --git a/groupTasks/groups/jnx-mail-shx-textgenerator/script.py b/groupTasks/groups/jnx-mail-shx-textgenerator/script.py new file mode 100644 index 0000000..ff09bb9 --- /dev/null +++ b/groupTasks/groups/jnx-mail-shx-textgenerator/script.py @@ -0,0 +1,277 @@ +import requests +import sys +import json +import subprocess +import sys +import os +import string +import random + +import smtplib +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText + +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))) + +STATIC_PATH = "" + +from libs.utils import utils + +# MAIN + +# load data from secrets +secrets = utils.get_secrets() + +crm_endpoint_url = secrets['admin_dashboard']['url'] + "/api/v1/crm" + +headers = { + "X-Api-Key": secrets["admin_dashboard"]["x_api_key"], + "Content-Type": "application/json" +} + +json_object = json.loads(sys.argv[1]) + +customerEmail = json_object["customerEmail"] +customerName = json_object["customerName"] +language = json_object["language"] +companyName = json_object["companyName"] +websiteURL = json_object["websiteURL"] + +if (companyName is None + or customerName is None + or language is None + or websiteURL is None): + print("Missing required parameters") + sys.exit(1) + +if(customerEmail is not None): + customerEmail = customerEmail["value"] + customerEmail = customerEmail.replace(" ", "") + if(customerEmail == ""): + customerEmail = None +customerName = customerName["value"] +companyName = companyName["value"] +language = language["value"] +websiteURL = websiteURL["value"] + + +def CreateCrmCustomer(): + response = requests.post( + url=f"{crm_endpoint_url}/customer/create", + headers=headers, + json={ + "FirstName": customerName, + "Company": companyName, + "Email": customerEmail, + "Website": websiteURL, + "LeadOrigin": "Kaltakquise Email/Contact added by GroupTask", + "DealPhase": 5, + }) + + print(f"CreateCrmCustomer response status code {response.status_code}") + + if response.status_code != 200: + print(f"CreateCrmCustomer req error {response.status_code}") + sys.exit(1) + + return response.json()["Id"] + + + +def CheckIfCrmCustomerExists(): + print(f"Checking if customer exists: {customerEmail}") + + response = requests.post( + url=f"{crm_endpoint_url}/customer", + headers=headers, + json={"Email": customerEmail} # Hier json verwenden, um JSON-Daten zu senden + ) + + print("CheckIfCrmCustomerExists response status code", response.status_code) + + if response.status_code != 200: + print(f"CheckIfCrmCustomerExists req error {response.status_code}") + sys.exit(1) + + customerId = "" + # only on first purchase we show the third voucher + + if response.json() == []: + print("Customer not found") + customerId = CreateCrmCustomer() + + else: + print("Error: Customer already exists") + sys.exit(1) + + if len(response.json()) > 1: + print("Multiple customers found. Don't know which one to use") + sys.exit(1) + + customerId = response.json()[0]["Id"] + + return customerId + + +def CreateCrmActivityLink(customerId, linkName, linkUrl): + print(f"Creating CRM activity link for customer {customerId}") + + _linkName = f"JNX: SHX-Akquise {linkName}" + + response = requests.post( + url=f"{crm_endpoint_url}/links", + headers=headers, + json={ + "CustomerId": customerId, + "Name": _linkName, + "Url": linkUrl + }) + + print(f"CreateCrmActivityLink response status code {response.status_code} for {type}") + + if response.status_code != 200: + print(f"CreateCrmActivityLink req error {response.status_code}") + sys.exit(1) + + response = requests.get( + url=f"{crm_endpoint_url}/customer/view/{customerId}", + headers=headers, + ) + + print(f"GetCustomerActivityLinks response status code {response.status_code}") + + if response.status_code != 200: + print(f"GetCustomerActivityLinks req error {response.status_code}") + sys.exit(1) + + data = response.json()["Links"] + + if len(data) == 0: + print("No links found") + sys.exit(1) + + # sort data by creation date + + data = sorted(data, key=lambda x: x["CreatedAt"], reverse=True) + + # find the first link that has a name that starts with "Shopify Order #orderId - price € Gutschein" + + createdLink = None + + for link in data: + if link["Name"].startswith(_linkName): + createdLink = link + break + + + if(createdLink is None): + print(f"Link with name '{_linkName}' not found") + sys.exit(1) + + return secrets["admin_dashboard"]["qr_code_url"] + createdLink['Id'] + + + +def sendMail(): + secrets = utils.get_secrets()["email"] + + # extract the email parameters + auth_email = secrets["auth_email"] + from_email_name = "Jan Umbach"#secrets["from_email_name"] + from_email = "kontakt@jannex.de"#secrets["from_email"] + password = secrets["password"] + + # extract the smtp parameters + smtp_server = secrets["smtp_server"] + smtp_port = secrets["smtp_port"] + + receiver_email = customerEmail + + # create the email multipart message + msg = MIMEMultipart("alternative") + msg["From"] = f"{from_email_name} <{from_email}>" + msg["To"] = receiver_email + + + + + # load html content from file + with open(f"{STATIC_PATH}email.txt", "r") as file: + text = file.read() + + with open(f"{STATIC_PATH}email.html", "r") as file: + html = file.read() + + with open(f"{STATIC_PATH}lang.json", "r") as file: + languageJson = json.load(file) + + + msg["Subject"] = languageJson[language]["subject"] + + # replace placeholders with actual values + + # loop through all keys in the language json and replace the placeholders in the html file + for key in languageJson[language]: + value = languageJson[language][key] + + value = value.replace("{{customerName}}", customerName) + + html = html.replace(f"{{{{{key}}}}}", value.replace("\n", "
")) + text = text.replace(f"{{{{{key}}}}}", value) + + unsubscribe_link = utils.generate_unsubscribe_link(customerId) + + # add link to list-unsubscribe-header + msg["List-Unsubscribe"] = f"<{unsubscribe_link}>" + + html = html.replace("{{footer}}", utils.get_email_footer_html(language, unsubscribe_link)) + text = text.replace("{{footer}}", utils.get_email_footer_text(language, unsubscribe_link)) + + html = html.replace("{{topImageSrc}}", CreateCrmActivityLink(customerId, "EMail Opened", "https://jannex.de/unsubscribed/public/shinnex-generator-preview.png")) + + html = html.replace("{{CTA_Link}}", CreateCrmActivityLink(customerId, "CTA Clicked (html)", "https://shinnex.de/products/personalisiertes-namensschild?variant=49403793572180")) + text = text.replace("{{CTA_Link}}", CreateCrmActivityLink(customerId, "CTA Clicked (text)", "https://shinnex.de/products/personalisiertes-namensschild?variant=49403793572180")) + + print(f"Sending email to {receiver_email}") + print("------") + print(text) + print("------") + + if(customerEmail is None): + print("Email not sent because no email address was provided") + return + + + # add text and html part to the email + part1 = MIMEText(text, "plain", "utf-8") + part2 = MIMEText(html, "html", "utf-8") + + # Attach the text and html part to the email + msg.attach(part1) + msg.attach(part2) + + # connect to the smtp server and send the email + try: + with smtplib.SMTP_SSL(smtp_server, smtp_port) as server: + server.login(auth_email, password) + server.sendmail(from_email, receiver_email, msg.as_string()) + + print(f"Email sent to {receiver_email}") + except Exception as e: + print(f"Error sending email: {e}") + sys.exit(1) + + +if __name__ == "__main__": + utils.move_files_back_from_old_files() + + if(customerEmail is not None): + customerId = CheckIfCrmCustomerExists() + else: + customerId = CreateCrmCustomer() + + sendMail() + + + + utils.clear_workspace(["email.html", "email.txt", "lang.json"]) \ No newline at end of file diff --git a/groupTasks/groups/shx-order-voucher-code-activated/script.py b/groupTasks/groups/shx-order-voucher-code-activated/script.py index 5ad4eed..bf281c9 100644 --- a/groupTasks/groups/shx-order-voucher-code-activated/script.py +++ b/groupTasks/groups/shx-order-voucher-code-activated/script.py @@ -1,6 +1,5 @@ import json import sys -import yaml import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText diff --git a/groupTasks/groupsData/jnx-email-template/footer.html b/groupTasks/groupsData/jnx-email-template/footer.html new file mode 100644 index 0000000..47fbabd --- /dev/null +++ b/groupTasks/groupsData/jnx-email-template/footer.html @@ -0,0 +1,14 @@ + + + + + + +
+

{{rechtstext}} +

+

{{impressum}}

+

{{unsubscribe_text}}

+
\ No newline at end of file diff --git a/groupTasks/groupsData/jnx-email-template/footer.txt b/groupTasks/groupsData/jnx-email-template/footer.txt new file mode 100644 index 0000000..9e59c5b --- /dev/null +++ b/groupTasks/groupsData/jnx-email-template/footer.txt @@ -0,0 +1,6 @@ +{{rechtstext}} + +{{impressum}} + +{{unsubscribe_text}} +{{unsubscribeLink}} \ No newline at end of file diff --git a/groupTasks/groupsData/jnx-email-template/lang.json b/groupTasks/groupsData/jnx-email-template/lang.json new file mode 100644 index 0000000..2213e71 --- /dev/null +++ b/groupTasks/groupsData/jnx-email-template/lang.json @@ -0,0 +1,14 @@ +{ + "de": { + "rechtstext": "Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte Informationen. Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrtümlich erhalten haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser Mail ist nicht gestattet.", + "impressum": "Impressum:\nJan Umbach, Tannenwäldchen 20, DE-34212 Melsungen", + "unsubscribe_text": "Wenn Sie keine weiteren E-Mails von uns erhalten möchten, klicken Sie bitte {{unsubscribe_text_button}}.", + "unsubscribe_text_button": "hier" + }, + "en": { + "rechtstext": "This email contains confidential and/or proprietary information. If you are not the intended recipient or have received this email in error, please notify the sender immediately and destroy this email. Unauthorized copying and unauthorized distribution of this email is prohibited.", + "impressum": "Imprint:\nJan Umbach, Tannenwäldchen 20, DE-34212 Melsungen", + "unsubscribe_text": "If you do not want to receive any more emails from us, please click {{unsubscribe_text_button}}.", + "unsubscribe_text_button": "here" + } +} diff --git a/groupTasks/libs/utils/__pycache__/utils.cpython-39.pyc b/groupTasks/libs/utils/__pycache__/utils.cpython-39.pyc index d433062..41ad5c5 100644 Binary files a/groupTasks/libs/utils/__pycache__/utils.cpython-39.pyc and b/groupTasks/libs/utils/__pycache__/utils.cpython-39.pyc differ diff --git a/groupTasks/libs/utils/utils.py b/groupTasks/libs/utils/utils.py index 571a1e7..f424305 100644 --- a/groupTasks/libs/utils/utils.py +++ b/groupTasks/libs/utils/utils.py @@ -201,3 +201,132 @@ def create_shopify_discount_code(shopify_discount_code_price_rule_name): print(f"Created discount code: {generated_discount_code}. Retries: {retries}") return generated_discount_code + +def get_email_footer_html(language, unsubscribe_link): + languageJson = None + + with open("../../groupsData/jnx-email-template/lang.json", "r") as file: + languageJson = json.load(file) + + with open("../../groupsData/jnx-email-template/footer.html", "r") as file: + content = file.read() + + def replace_unsubscribe_text_button(content): + return content.replace("{{unsubscribe_text_button}}", f"{languageJson[language]['unsubscribe_text_button']}") + + # loop through all keys in the language json and replace the placeholders in the html file + for key in languageJson[language]: + if(key == "unsubscribe_text_button"): + content = replace_unsubscribe_text_button(content) + else: + value = languageJson[language][key] + value = value.replace("\n", "
") + content = content.replace(f"{{{{{key}}}}}", value) + + + content = replace_unsubscribe_text_button(content) + content = content.replace("{{unsubscribeLink}}", unsubscribe_link) + + return content + +def get_email_footer_text(language, unsubscribe_link): + languageJson = None + + + + with open("../../groupsData/jnx-email-template/lang.json", "r") as file: + languageJson = json.load(file) + + with open("../../groupsData/jnx-email-template/footer.txt", "r") as file: + content = file.read() + + # loop through all keys in the language json and replace the placeholders in the html file + for key in languageJson[language]: + content = content.replace(f"{{{{{key}}}}}", languageJson[language][key]) + + content = content.replace("{{unsubscribe_text_button}}", languageJson[language]['unsubscribe_text_button']) + content = content.replace("{{unsubscribeLink}}", unsubscribe_link) + + return content + + +def generate_unsubscribe_link(customerId): + print(f"Using CRM unsubscribe link for customer {customerId}") + + _linkName = f"JNX: ⛔️⛔️⛔️ WARN - E-Mail unsubscribed ⛔️⛔️⛔️" + _secrets = get_secrets() + crm_endpoint_url = _secrets['admin_dashboard']['url'] + "/api/v1/crm" + + headers = { + "X-Api-Key": _secrets["admin_dashboard"]["x_api_key"], + "Content-Type": "application/json" + } + + def get_link(): + response = requests.get( + url=f"{crm_endpoint_url}/customer/view/{customerId}", + headers=headers, + ) + + print(f"GetCustomerActivityLinks response status code {response.status_code}") + + if response.status_code != 200: + print(f"GetCustomerActivityLinks req error {response.status_code}") + sys.exit(1) + + data = response.json()["Links"] + + if len(data) == 0: + print("No links found") + return None + + # sort data by creation date + + data = sorted(data, key=lambda x: x["CreatedAt"], reverse=True) + + # find the first link that has a name that starts with "Shopify Order #orderId - price € Gutschein" + + createdLink = None + + for link in data: + if link["Name"].startswith(_linkName): + createdLink = link + break + + + if(createdLink is None): + print(f"Unsubscribe link not found, creating new one") + return None + + return _secrets["admin_dashboard"]["qr_code_url"] + createdLink['Id'] + + link = get_link() + + if(link is not None): + print(f"Using existing unsubscribe link for customer {customerId}") + return link + + print(f"Creating CRM unsubscribe link for customer {customerId}") + + response = requests.post( + url=f"{crm_endpoint_url}/links", + headers=headers, + json={ + "CustomerId": customerId, + "Name": _linkName, + "Url": "https://jannex.de/unsubscribed" + }) + + print(f"CreateCrmActivityLink response status code {response.status_code} for {type}") + + if response.status_code != 200: + print(f"CreateCrmActivityLink req error {response.status_code}") + sys.exit(1) + + link = get_link() + + if(link is None): + print("Error creating unsubscribe link") + sys.exit(1) + + return link \ No newline at end of file diff --git a/main b/main index d21f9e6..8c552bb 100755 Binary files a/main and b/main differ diff --git a/modules/utils/globals.go b/modules/utils/globals.go index 3ced78b..24ac04f 100644 --- a/modules/utils/globals.go +++ b/modules/utils/globals.go @@ -18,7 +18,7 @@ const ( MaxRoleDescription = 80 MaxEquipmentDocumentationTitleLength = "60" MaxEquipmentDocumentationNoteLength = 2000 - MaxNoficationTitleLength = "255" + MaxNoficationTitleLength = "4096" MinUserApiKeyNameLength = 2 MaxUserApiKeyNameLength = 30