Basic contact page
This commit is contained in:
@@ -2,16 +2,61 @@
|
||||
|
||||
from index import app
|
||||
from os import environ
|
||||
from flask import request, redirect, render_template
|
||||
from flask import request, render_template
|
||||
from requests import post, get
|
||||
from uuid import uuid4
|
||||
from textwrap import dedent
|
||||
|
||||
def validate_turnstile(response: str, ip: str) -> bool:
|
||||
turnstile_secret = environ['TURNSTILE_SECRET']
|
||||
cf_response = post(
|
||||
url='https://challenges.cloudflare.com/turnstile/v0/siteverify',
|
||||
data={
|
||||
'secret': turnstile_secret,
|
||||
'response': response,
|
||||
'remoteip': ip,
|
||||
'idempotency_key': uuid4()
|
||||
}
|
||||
).json()
|
||||
|
||||
return cf_response.get('success', False)
|
||||
|
||||
def send_to_discord(form: dict) -> bool:
|
||||
try:
|
||||
discord_hook = environ['DISCORD_WEBHOOK']
|
||||
except:
|
||||
return False
|
||||
discord_msg = dedent(
|
||||
f'''
|
||||
__**New Contact Form Response**__
|
||||
|
||||
**From:** {form.get('name')} <{form.get('email')}>
|
||||
|
||||
''')
|
||||
if form.get("message") == '':
|
||||
discord_msg += '*No Message*'
|
||||
else:
|
||||
discord_msg += f'>>> {form.get("message")}'
|
||||
discord_response = post(
|
||||
url=discord_hook,
|
||||
data={
|
||||
'username': form.get('name'),
|
||||
'content': discord_msg
|
||||
}
|
||||
).status_code
|
||||
|
||||
if discord_response == 204:
|
||||
return True
|
||||
return False
|
||||
|
||||
@app.route('/contact/', methods=('GET', 'POST'))
|
||||
def contact():
|
||||
if request.method == 'POST':
|
||||
discord_hook = environ['DISCORD_WEBHOOK']
|
||||
print(discord_hook)
|
||||
print(request.form)
|
||||
return redirect('/contact/')
|
||||
if not validate_turnstile(request.form['cf-turnstile-response'], request.remote_addr):
|
||||
return render_template('contact.html', error=True, user_message='You appear to be a robot.')
|
||||
send_result = send_to_discord(request.form)
|
||||
if send_result:
|
||||
return render_template('contact.html', user_message='Your message has been sent!')
|
||||
return render_template('contact.html', error=True, user_message='An error occurred.')
|
||||
else:
|
||||
return render_template('contact.html')
|
||||
|
@@ -3,3 +3,4 @@ flask-markdown>=0.3
|
||||
markdown>=3.4.1
|
||||
beautifulsoup4>=4.11.1
|
||||
python-frontmatter>=1.1.0
|
||||
requests>=2.32.3
|
||||
|
@@ -54,4 +54,9 @@
|
||||
width: fit-content;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
#logo-container{
|
||||
position: absolute;
|
||||
height: 25vh;
|
||||
}
|
||||
}
|
@@ -30,6 +30,7 @@ footer{
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#logo{
|
||||
@@ -167,4 +168,39 @@ a{
|
||||
|
||||
.article-category:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#contact-main{
|
||||
padding: 20px 10px 0 10px;
|
||||
min-height: 65vh;
|
||||
}
|
||||
|
||||
#contact-main>h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
input, textarea{
|
||||
display: block;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #4c4c4c;
|
||||
border-radius: 10px;
|
||||
border:none;
|
||||
color: white;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label{
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.cf-turnstile{
|
||||
width: fit-content;
|
||||
padding: 10px 0 10px 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#contact-error{
|
||||
color: red;
|
||||
}
|
@@ -1,16 +1,20 @@
|
||||
{% include 'header.html' %}
|
||||
<main>
|
||||
<main id="contact-main">
|
||||
<h2>Contact Me</h2>
|
||||
<p>Got a question or want to talk about something on this site? Drop me a message below:</p>
|
||||
|
||||
<form action="#" method="post">
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" name="name">
|
||||
<input type="text" name="name" required>
|
||||
<label for="email">Email Address:</label>
|
||||
<input type="email" name="email">
|
||||
<input type="email" name="email" required>
|
||||
<label for="message">Message:</label>
|
||||
<textarea name="message"></textarea>
|
||||
<textarea name="message" rows="10"></textarea>
|
||||
<div class="cf-turnstile" data-sitekey="0x4AAAAAAA45FeR26JuvqKy7"></div>
|
||||
<input type="submit" name="submit" value="Submit">
|
||||
</form>
|
||||
{% if user_message is not none %}
|
||||
<p id="{{ 'contact-error' if error else 'contact-message' }}">{{ user_message }}</p>
|
||||
{% endif %}
|
||||
</main>
|
||||
{% include 'footer.html' %}
|
@@ -12,12 +12,14 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<script src="/static/js/filter_projects.js"></script>
|
||||
<script src="/static/js/update_copyright.js"></script>
|
||||
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav id="top-nav">
|
||||
<a href="/">About</a>
|
||||
<a href="/projects/">Projects</a>
|
||||
<a href="/contact/">Contact</a>
|
||||
</nav>
|
||||
<div id="logo-container">
|
||||
<div id="logo">
|
||||
|
Reference in New Issue
Block a user