subscribe an email address directly using the Mailman API

This commit is contained in:
ohsqueezy 2022-10-24 17:58:15 -04:00
parent f0e361e790
commit 8b22ef3db0
5 changed files with 208 additions and 81 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ bin/
include/
lib/python3.9/
pyvenv.cfg
lib/python*

@ -1 +1 @@
Subproject commit 72866bd11c07ae50ef4fbaae683200e6bb9007b5
Subproject commit ee9bdd7678402811f817fcaa7d35c1fdecd75cca

View File

@ -1,51 +0,0 @@
44857 0
49055 0
50925 0
52244 0
52476 0
52697 0
53843 0
54228 0
55784 0
56431 0
56841 0
57276 0
59877 0
59924 0
60226 0
60533 0
60592 0
60840 0
61002 0
61161 0
61886 0
62177 0
64400 0
66059 0
67432 0
68558 0
70106 0
70215 0
72014 0
73576 0
73582 0
73707 0
74811 0
76033 0
76297 0
77707 0
79626 0
73625 1
92223 1
100944 1
104210 1
107313 1
108885 1
112707 1
114058 1
118589 1
124901 1
78910 2
82296 2
82801 2
97958 2

View File

@ -368,9 +368,38 @@
<div id="calendar">
<p>
Check out Scrapeboard at an upcoming event!
Play Scrapeboard at an upcoming event!
<!-- Check back soon for upcoming events! -->
</p>
<div class="date upcoming">
<div class="day-of-week">
Thu - Sun
</div>
<div class="day">
Jan. 5 - 8
</div>
<div class="year">
2023
</div>
<div class="location">
<a href="https://super.magfest.org">MAGFest, Maryland</a>
</div>
</div>
<div class="date current">
<div class="day-of-week">
Sat
</div>
<div class="day">
Nov. 5
</div>
<div class="year">
2022
</div>
<div class="location">
<a href="https://www.play-nyc.com/">Play NYC</a>
</div>
</div>
<div class="date past">
<div class="day-of-week">
Sun
</div>
@ -464,29 +493,45 @@
</div>
<script>
function subscribe(email_address)
{
var request = new Request("https://scrape.nugget.fun/www/subscribe.php", {
method: "POST",
mode: "cors",
body: new URLSearchParams({"email": email_address}),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}});
fetch(request)
.then(response => response.json())
.then(result => {
console.log(result);
if (result.success)
{
var color = "green";
}
else
{
var color = "red";
}
document.querySelector("#mailing-list-join").innerHTML = "<span style='color: " + color + "'>" + result.message + "</span>";
});
}
</script>
<div id="mailing-list-join">
<span style="background: #ffa; border-radius: 5px; padding-left: 10px; padding-right: 10px;">
Join the announcements list
</div>
</span>
</div>
<script>
function subscribe()
{
var request = new Request("https://scrape.nugget.fun/www/subscribe.php", {
method: "GET",
headers: {
"Content-Type": "text/plain",
}});
fetch(request, {mode: "cors"}).then(data => { console.log(data.text()) });
}
</script>
<div id="mailing-list-form">
<input class="input" id="email-box" style="width: 50%" name="email" value="Your e-mail" onfocus="if(this.value=='Your e-mail') this.value='';"
onfocusout="if(this.value=='') this.value='Your e-mail';">
&nbsp;
<button class="input" style="cursor: pointer; background: #4f8; font-weight: bold" value="Join" onclick="subscribe();">Join</button>
<button class="input" style="cursor: pointer; background: #4f8; font-weight: bold" value="Join"
onclick="subscribe(document.querySelector('#mailing-list-form #email-box').value);">Join</button>
</div>
<div id="mailing-list-archives">

View File

@ -1,20 +1,152 @@
<?php
# [subscribe.php]
#
# Subscribe an email address to a Mailman3 mailing list. The email address is taken from the query string, and
# the mailing list can be set to the variable below.
#
# Used the documentation at [https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/model/docs/subscriptions.html]
/* [subscribe.php]
*
* Subscribe an email address to a Mailman3 mailing list. The email address is taken from the request, and
* the mailing list and API credentials are set below.
*
* Mailman3 API subscription documentation:
*
* [https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/rest/docs/membership.html#joining-a-mailing-list]
*/
$MAILING_LIST = "sandbox-list@nugget.fun";
const MAILING_LIST_ID = "scrapeboard-list.nugget.fun";
const API_USER = "restadmin";
const API_TOKEN = "GgzPdbc0rvvsWkHIhmGtjtbv0rmDlz0Y4zBjQv+kEjl6HvSS";
const API_HOST = "http://localhost:8001";
const API_VERSION = "3.1";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:8001/3.1/system/versions");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "restadmin:GgzPdbc0rvvsWkHIhmGtjtbv0rmDlz0Y4zBjQv+kEjl6HvSS");
echo curl_exec($ch);
curl_close($ch);
/* Submit an API request to mailman using cURL with the above settings
*
* @param request request part of the URL to submit to mailman, see Mailman3 for possible requests
* @param method either "GET" or "POST"
* @param post_data array of post parameters to pass with the request URL
* @return array of reponse parameters decoded from JSON, along with response["success"] and response["message"]
*/
function submit_request_to_mailman($request, $method = "GET", $post_data = array())
{
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => API_HOST. "/" . API_VERSION . "/" . $request,
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => API_USER . ":" . API_TOKEN,
/* Return the response from curl_exec as a string instead or outputting it directly */
CURLOPT_RETURNTRANSFER => true
));
/* Use HTTP POST method if requested, application/x-www-form-urlencoded */
if ($method == "POST")
{
curl_setopt($ch, CURLOPT_POST, true);
/* Include any post data in the request, using http_build_query to post as application/x-www-form-urlencoded */
if ($post_data)
{
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
}
}
/* Define a response array that contains the success state and a message that will be filled in the case of an error */
$response = array("success" => false, "message" => "");
$result = curl_exec($ch);
if ($result !== false)
{
/* Make sure the appropriate response for GET or POST was received */
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($method == "POST" && $http_status != 201 || $method == "GET" && $http_status != 200)
{
$response["message"] = "[" . curl_getinfo($ch, CURLINFO_HTTP_CODE) . "]";
if ($result != "")
{
$result = json_decode($result, true);
if (array_key_exists("title", $result))
{
$response["message"] .= " " . $result["title"];
}
if (array_key_exists("description", $result))
{
$response["message"] .= " " . $result["description"];
}
}
}
else
{
/* Merge the response from Mailman3 into the existing response array */
$response["success"] = true;
if ($result != "")
{
$response = array_merge($response, json_decode($result, true));
}
}
}
else
{
$response["message"] = "cURL error: " . curl_error($ch);
}
curl_close($ch);
return $response;
}
/* Start a response array that will be output as JSON and get the log directory */
$response = submit_request_to_mailman("system/configuration/paths.debian");
if ($response["success"])
{
/* Use the mailman-web log since www-data has write permission and record the input */
$log_directory = $response["log_dir"];
$log_path = $log_directory . "/web/mailman-web.log";
file_put_contents(
$log_path, "[" . date(DATE_RFC2822) . "] Processing subscription request with input " . json_encode($_POST) . "\n", FILE_APPEND);
if (array_key_exists("email", $_POST))
{
/* Use Data Filtering to validate that a valid email address was submitted
* [https://www.php.net/manual/en/filter.examples.sanitization.php]
*
* If an invalid email was submitted, print an error message and exit
*/
$sanitized_email = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL);
$response["email"] = $sanitized_email;
if (!filter_var($sanitized_email, FILTER_VALIDATE_EMAIL))
{
$response["success"] = false;
$response["message"] = $_POST["email"] . " (sanitized to $sanitized_email) is not a valid email address";
}
else
{
/* Skip the verification, confirmation, and approval emails, and subscribe the submitted address */
$subscription_response = submit_request_to_mailman(
"members", "POST", array(
'list_id' => MAILING_LIST_ID,
'subscriber' => $sanitized_email,
'pre_verified' => true,
'pre_confirmed' => true,
'pre_approved' => true));
if ($subscription_response["success"])
{
$response["success"] = true;
$response["message"] = "Added $sanitized_email to " . MAILING_LIST_ID;
}
else
{
/* Merge in the API request response, which will contain the error information */
$response = array_merge($response, $subscription_response);
}
}
}
else
{
$response["success"] = false;
$response["message"] = "No email address to subscribe was provided";
}
}
/* Log the response internally, set the JSON output header, and output JSON for the client */
file_put_contents($log_path, "[" . date(DATE_RFC2822) . "] Final response is " . json_encode($response) . "\n", FILE_APPEND);
header("Content-Type: application/json");
echo json_encode($response);
?>