[Majordomo] synchroniseren mailinglijsten met DB

Technische problemen? Hier kun jij jouw vragen stellen!
Forumregels
Check eerst onze helpsectie (https://www.antagonist.nl/help) voordat je hier een vraag stelt. Voor de meeste vragen hebben we uitgebreide handleidingen met uitleg.
Plaats reactie
markjansen.nl
Berichten: 6
Lid geworden op: 29 jul 2018, 10:35

[Majordomo] synchroniseren mailinglijsten met DB

Bericht door markjansen.nl » 05 sep 2020, 16:01

Wellicht is deze vraag al eens gesteld, maar zoekend op 'majordomo' kon ik het in ieder geval niet vinden (het aantal topics daarover is verrassend laag en ook oud).

De vraag is eigenlijk heel simpel: hoe synchroniseer ik de mailinglijsten op een eenvoudige manier met een andere administratie (zoals een MySQL-database)?

Wanneer ik zelf wat Google vind ik eigenlijk niet echt de ideale oplossing (of zie ik iets over het hoofd?).

Ik heb nu een scriptje geschreven dat met een cron-jon wordt aangeroepen en vervolgens iedere nacht mutaties in de database checkt, om vervolgens een mailtje te genereren met daarin achter elkaar allerlei subscribe en unsubscribe commando's en dan dit mailtje te sturen aan majordomo@.... Maar dat is natuurlijk een heel bewerkelijk proces. Het voelt een beetje als "back to the 90's" met deze bundeling tekstcommando's in een mailtje.

Uit het feit dat in DIrectadmin de mailinglijsten via een webinterface beheerd kunnen worden, volgt al dat het handiger kan. Ik vermoed echter dat hier op de achtergrond meespeelt dat Directadmin toegang heeft tot bestanden waartoe de FTP-user geen toegang heeft (???). Of zijn er bestanden op de server met de subscriptions die ik zelf kan aanroepen met een script en eventueel muteren?

Wat is nu de handige / aanbevolen route?

Gebruikersavatar
Joris de Leeuw
Antagonist staff
Berichten: 1293
Lid geworden op: 13 feb 2016, 20:15

Re: [Majordomo] synchroniseren mailinglijsten met DB

Bericht door Joris de Leeuw » 07 sep 2020, 14:29

Majordomo heeft hier geen gemakkelijke optie voor en mijn verwachting is dat die er ook niet komt. Zoals je zelf al aangeeft stamt Majordomo uit de jaren 90 en is er sindsdien eigenlijk niets aan veranderd. De makers zijn namelijk gestopt met onderhoud al voor langere tijd.

Al heb je zo te lezen al een redelijke oplossing kan je ook nog overwegen met de DirectAdmin API de mailinglijst aan te sturen. Al ben ik niet bekend of iemand dat is gelukt zou dat in theorie wel moeten kunnen: https://www.directadmin.com/api.php

Daarnaast kan je eventueel een andere mailingsysteem op basis van PHP zelf in je hostingpakket zetten die iets moderner in elkaar zit.
Met vriendelijke groet,

Joris de Leeuw
Antagonist staff

markjansen.nl
Berichten: 6
Lid geworden op: 29 jul 2018, 10:35

Re: [Majordomo] synchroniseren mailinglijsten met DB

Bericht door markjansen.nl » 13 feb 2021, 15:49

Joris de Leeuw schreef:
07 sep 2020, 14:29
Majordomo heeft hier geen gemakkelijke optie voor en mijn verwachting is dat die er ook niet komt. Zoals je zelf al aangeeft stamt Majordomo uit de jaren 90 en is er sindsdien eigenlijk niets aan veranderd. De makers zijn namelijk gestopt met onderhoud al voor langere tijd.

Al heb je zo te lezen al een redelijke oplossing kan je ook nog overwegen met de DirectAdmin API de mailinglijst aan te sturen. Al ben ik niet bekend of iemand dat is gelukt zou dat in theorie wel moeten kunnen: https://www.directadmin.com/api.php
Beetje verlate reactie mijnerzijds.

De koppeling tussen database en mailinglijst via mailtjes aan majordomo@.... bleek in de praktijk toch wat te bewerkelijk. Die voorziening was niet stabiel.

Je opmerking over de API heeft me aan het denken gezet en dit heb ik werkend gekregen. Ik zal voor het gemak van andere die hier ook mee worstelen de code delen, dat scheelt een hoop gepuzzel voor de rest. Dit ook omdat die API verrassend beperkt gedocumenteerd blijkt te zijn en er (in mijn beleving althans) weinig voorbeelden te vinden zijn.
Daarnaast kan je eventueel een andere mailingsysteem op basis van PHP zelf in je hostingpakket zetten die iets moderner in elkaar zit.
Deze laatste opmerking kan ik alleen lastig plaatsen. We zijn juist recent er tegenaan gelopen dat ons eigen nieuwsbriefsysteem tegen de maillimiet aanliep. En toen kregen we ook nog te lezen dat mailen eigenlijk ook niet via eigen scripts zou moeten, maar dat we partijen als Mailchimp moeten verkennen. Maar goed... dat laat onverlet dat de tip om eens naar de API te kijken erg nuttig was.

markjansen.nl
Berichten: 6
Lid geworden op: 29 jul 2018, 10:35

Re: [Majordomo] synchroniseren mailinglijsten met DB

Bericht door markjansen.nl » 13 feb 2021, 16:00

Onderstaande is gebaseerd op de class te vinden op https://github.com/likecyber/php-directadmin-api

De aannames die voor mij gelden bij het schrijven (dan snap je de code wellicht beter):
  • er is een database met leden, de adresgegevens staan in de tabel adresgegevens;
  • leden kunnen lid zijn in een bepaald datumbereik, dat is opgeslagen in de tabel lidmaatschapsduur;
  • leden kunnen bovendien een of meer functies hebben met een datumbereik, dat is opgeslagen in de tabel functie_aan_lid;
  • per functie kan er een mailinglist zijn,dat vind je terug in de tabel Functie_aan_mailinglijst
Het script doet vervolgens in de kern weinig meer dan de delta zoeken tussen de huidige adressen op de mailinglist en de huidige adressen in de ledendatabase. Die delta bestaat in twee smaken:
  1. te veel op de lijst (dus niet langer lid of van adres gewijzigd) ==> wordt verwijderd
  2. te weinig op de lijst (dus nieuw lid of van adres gewijzigd) ==> wordt toegevoegd
Dit vervolgens 's nachts draaien via een cron-job en je bent er.

Doe er je voordeel mee.

Ps. Codesuggesties zijn welkom. Ik kan best een beetje programmeren, maar de lezer wellicht wel beter.

Code: Selecteer alles

<?php

/*
Script om via directadmin interface mailinglijsten te syncroniseren

*/

//verbindingsgegevens database
require_once ("../ledendatabase/variables.inc.php");

//functies en instellingen koppelingen directadmin
require_once("./directadmin.class/directadmin.class.php");
require_once("./directadmin.class/variables.inc.php");


//verbinding database leggen
$db= new mysqli($dbhost, $dbuser, $dbpassword, $database);
if($db->connect_errno > 0){
    die('Unable to connect to database [' . $db->connect_error . ']');
}

//verbinding directadmin
$da = new DirectAdmin("https://$da_host:2222", "$da_user", "$da_pwd");


//ALLE MOGELIJKE MAILINGLIJSTEN OPVRAGEN
$query = "SELECT * FROM Functie_aan_mailinglijst;";

if(!$result = $db->query($query)){
	die('There was an error running the query $query  [' . $db->error . ']');
}
if(mysqli_num_rows($result) <> 0) {
	//resultaat in een array stoppen
	$lijsten_array = array();

	while($row = $result->fetch_assoc()) {		
		$lijsten_array[$row["FunctieID"]]=$row["Mailinglist_naam"];
		
	}
}


foreach ($lijsten_array as $FunctieID => $lijstnaam) {
	
	$querytekst = "SELECT * FROM adresgegevens 
		JOIN `Functie_aan_mailinglijst` FL ON FL.FunctieID = $FunctieID 
		WHERE adresgegevens.LidID IN ( SELECT LidID FROM lidmaatschapsduur WHERE ((`Aanvang` <= CURRENT_DATE AND `Aanvang` <> '0000-00-00' ) AND ( `Einde` = '0000-00-00' OR `Einde` > CURRENT_DATE))  AND `lidtype` = 'lid') ";
		
	if ($FunctieID > 0) { 
		$querytekst .= " AND 
		adresgegevens.LidID IN (SELECT LidID FROM `functie_aan_lid` WHERE FunctieID = FL.FunctieID AND 
	
		((`functie_aan_lid`.`Begindatum` <= NOW() AND `functie_aan_lid`.`Begindatum` <> '0000-00-00' ) AND ( `functie_aan_lid`.`Einddatum` = '0000-00-00' OR `functie_aan_lid`.`Einddatum` > NOW())));";
	}
	
	//query uitvoeren
	if(!$result_sql = $db->query($querytekst)){
		die('There was an error running the query $query  [' . $db->error . ']');
	}	

	//variabelen resetten
	unset($mailadressen_in_db_temp);
	$mailadressen_in_db_temp = array();
	
	
	if(mysqli_num_rows($result_sql) <> 0) {

	while($row = $result_sql->fetch_assoc()) {
		$Emailadres = $row["Emailadres"];
		$Emailadres2 = $row["Emailadres2"];
		$Mailinglist_naam = $row["Mailinglist_naam"];

		if (strlen($Emailadres) > 3) {
			$mailadressen_in_db_temp[] = $Emailadres;
		
		}
		if (strlen($Emailadres2) > 3) {
			$mailadressen_in_db_temp[] = $Emailadres2;
			
		}
		
		}
	}		
	
	//totale mailadressen voor deze functie in array opslaan
	$mailadressen_in_db[$FunctieID] = $mailadressen_in_db_temp;
	
	//gegevens directadmin opvragen voor deze lijst
	$result_da = $da->query("CMD_API_EMAIL_LIST", array(
		"domain" => $domain,
		"action" => "view",
		"name" => "$lijstnaam"		
		), "POST");


	if (!$da->error) {
		$mailadressen_op_lijst[$FunctieID] = $result_da;
		
	} else {
		die("Error!");
	}
					
	
	//verschillenanalyse
	
	$te_veel_op_lijst[$FunctieID] = array_diff($mailadressen_op_lijst[$FunctieID], $mailadressen_in_db[$FunctieID]);

	$te_weinig_op_lijst[$FunctieID] = array_diff($mailadressen_in_db[$FunctieID],$mailadressen_op_lijst[$FunctieID]);
		
}


foreach ($te_weinig_op_lijst as $FunctieID => $mailadressen) {
	
	foreach ($mailadressen as $key => $adres) {
		
		$lijstnaam = $lijsten_array[$FunctieID];
		
		$result = $da->query("CMD_API_EMAIL_LIST", array(
			"domain" => $domain,
			"action" => "add",
			"name" => "$lijstnaam",
			"type" => "list",
			"email" => "$adres"	
			), "POST");


		if ($da->error) {
			die("Error!");
		}

	}
}


foreach ($te_veel_op_lijst as $FunctieID => $mailadressen) {
	
	foreach ($mailadressen as $key => $adres) {
		
		$lijstnaam = $lijsten_array[$FunctieID];
		
		
		$result = $da->query("CMD_API_EMAIL_LIST", array(
			"domain" => $domain,
			"action" => "delete_subscriber",
			"name" => "$lijstnaam",
			"type" => "list",
			"select0" => "$adres"	
		), "POST");
		

		if ($da->error) {
			die("Error!");
		}

	}
}

/*
print_r($te_veel_op_lijst);

echo "\n\n";
print_r($te_weinig_op_lijst);

*/


?>

Plaats reactie