Looks the umbrella list option is working. I figured out how to add nonmembers. 
 Here's the setup I tested with (names / domains changed):

=====
list-all members
  list-0...@example.com
  list-0...@example.com

list-all nonmembers with moderation_action = Action.defer
  sitead...@example.com

=====
list-admin members
  admin.u...@example.com

list-admin nonmembers with moderation_action = Action.defer
  admin.u...@example.com
  list-all-boun...@example.com
  list-0000-boun...@example.com
  list-0001-boun...@example.com
  ... (every notification list)


=====
list-0000 members
  list-ad...@example.com
  some.b...@gmail.com

list-0000 nonmembers with moderation_action = Action.defer
  admin.u...@example.com
  list-all-boun...@example.com

When sending to the list-all list, the email gets sent to each of the member 
lists adn subsequently the list-admin list. I did not see duplicates sent to 
the admin list even though the list-admin list was included twice (one for each 
member list)


I wrote a python module to configure the list details (hopefully attached)
The following steps are used to configure the lists. Run as mailman user.

# Create special list-all list
mailman create --owner sitead...@example.com list-...@example.com
mailman shell -l list-...@example.com --run configure_list dummy_value

# Create specal list-admin list
mailman create --owner sitead...@example.com list-ad...@example.com
mailman shell -l list-ad...@example.com --run configure_list dummy_value


# CONFIGURE A NOTIFICATION LIST (4 steps)

mailman create --owner sitead...@example.com list-0...@example.com

# ues-admin list gets copied on posts sent to every list
echo 'list-ad...@example.com' | mailman addmembers --delivery regular 
--no-welcome-msg - list-0...@example.com

# Configure the list options
mailman shell -l list-0...@example.com --run configure_list "Short Description"

# The following should be run for each new notification list to allow copies to 
go to the admin list
mailman shell -l list-ad...@example.com --run configure_list list-0000


________________________________
From: Sparks, Paul
Sent: Friday, July 25, 2025 13:38
To: Mailman 3 Users <mailman-users@mailman3.org>
Subject: Advice on how to set announcement only lists?

Here's the basics of what I'm trying to set up:
The Web UI is not available. CLI tools are being used for configuration and 
ongoing maintenance functions. The server instance is ephemeral, but has 
persistent storage for postfix / mailman configuration.
There are a series of notification lists list-0...@example.com, 
list-0...@example.com, etc. Users can subscribe / unsubscribe via email.
A list-...@example.com list can be used to send posts to all lists (this is 
rare).
A sitead...@example.com email address is the only sender allowed to post to any 
list.
A list-ad...@example.com list is defined. This list should be copied on all 
posts that are sent to any of the notification lists. The admin list membership 
is maintained via CLI tools by list admins

Below are a couple of ideas I've played around with, but haven't gotten a good 
solution. Suggestions would be welcome. I've had a little experience with the  
CLI tools, but I'm not having luck with trying to add non-members.

Idea 1
Have list-...@example.com be an umbrella list with all notifications lists as 
members.
list-ad...@example.com is added to all lists as a member
sitead...@example.com is added to all notification lists as a member with 
moderation_action = Action.defer to allow sending posts.
ues-...@example.com is added to all notification lists as a member with 
moderation_action = Action.defer to allow "nested" sending to members of the 
list-all list.
There seem to be issues with having the senders as members of the list. Having 
them as non-members might be a solution, but I haven't yet figured out how to 
add non-members via CLI.

Idea 2
Use cron with CLI tools to extract all notification list members and update 
(mailman syncmembers) the list-all membership.
Use script to add all list-admin users to each notification list. Update all 
notification lists when the list-admin membership changes. This is somewhat 
problematic since individuals could be direct members of notification lists and 
removal from list-admin would remove the direct membership.
sitead...@example.com is added to all lists as a member with moderation_action 
= Action.defer to allow sending posts.

________________________________

The contents of this e-mail, including attachments, are intended for use by the 
named addressee only and may contain information that is confidential or 
private according to applicable law. If you received this electronic 
transmission in error, please notify the sender by a reply to sender only 
message, permanently delete the original message and any attachments from your 
electronic device and keep this message confidential. Unauthorized use, 
copying, review and/or distribution to unauthorized persons is strictly 
prohibited and subjects the user to penalty of law. Thank you for your 
cooperation.

#! /usr/bin/python3
#
# mailman3 module to configure notification mailing lists
# Update this as needed for your application. Look for example.com
#
# This single file handles both the 2 special lists as well as the basic notification lists.
# This makes the call interface a bit confusing since dummy parameter are needed at times.
# Split into multiple files if desired.
#
# This module must be in the Python sys.path 
# sys.path = ['/opt/mailman/bin', '/usr/lib64/python39.zip', '/usr/lib64/python3.9', '/usr/lib64/python3.9/lib-dynload', '/opt/mailman/lib64/python3.9/site-packages', '/opt/mailman/lib/python3.9/site-packages']
## Example usage:
## SET UP 2 SPECIAL LISTS
# mailman create --owner sitead...@example.com list-...@example.com
# mailman shell -l list-...@example.com --run configure_list dummy_value
# mailman create --owner sitead...@example.com list-ad...@example.com
# mailman shell -l list-ad...@example.com --run configure_list dummy_value
#
## CONFIGURE A NOTIFICATION LIST
# mailman create --owner sitead...@example.com list-0...@example.com
## ues-admin list gets copied on posts sent to every list
# echo 'list-ad...@example.com' | mailman addmembers --delivery regular --no-welcome-msg - list-0...@example.com
## Configure the list options
# mailman shell -l list-0...@example.com --run configure_list "Short Description"
## The following should be run for each new notification list to allow copies to go to the admin list
# mailman shell -l list-ad...@example.com --run configure_list list-0000

import datetime

# Find these module paths using mailman shell for any list (mailman shell -l test1.example.com)
# Look at __module__ attribute of the class  (e.g for SubscriptionPolicy)
# >>> SubscriptionPolicy.__module__
# 'mailman.interfaces.mailinglist'
#
from mailman.interfaces.archiver import ArchivePolicy
from mailman.interfaces.action import Action
from mailman.interfaces.mailinglist import ReplyToMunging
from mailman.interfaces.mailinglist import SubscriptionPolicy
from mailman.interfaces.member import MemberRole
from mailman.interfaces.usermanager import IUserManager
from mailman.utilities.datetime import now
from zope.component import getUtility

admin_description = 'Admins'

def get_user(display_name, email, user_manager):
  """Return an existing address record if available, otherwise make one."""
  user = user_manager.get_user(email)
  if user is not None:
      # We have a user with this email.  Return that.
      return user
  # Unknown email.  Create an address for this.
  return user_manager.create_user(email, display_name)

def add_nonmember_sender(ml, email):
  """Add nonmember to a mailing list."""
  user_manager = getUtility(IUserManager)

  display_name = email.split('@')[0]
  user = get_user(display_name, email, user_manager)
  address = list(user.addresses)[0]
  address.verified_on = now()
  user.preferred_address = address
  ml.subscribe(user, MemberRole.nonmember)
  #print(email,'subscribed as nonmember to', ml.list_name)
  # Update moderation_action after nonmember is added. Before does not work
  nonmembers = ml.get_roster(MemberRole.nonmember)
  for nonmember in nonmembers.members:
    #print('Moderation action-Checking', nonmember.address, '==', email)
    if email == nonmember.address.original_email:
      #print('Setting moderation action for', email)
      nonmember.moderation_action = Action.defer


def set_common(ml):
  """Properties common to all lists."""
  ml.admin_immed_notify = False
  ml.advertised = False
  ml.allow_list_posts = False
  ml.anonymous_list = True
  ml.archive_policy = ArchivePolicy.never
  ml.bounce_info_stale_after = datetime.timedelta(days=90)
  ml.bounce_notify_owner_on_disable = False
  ml.bounce_notify_owner_on_removal = False
  ml.bounce_score_threshold = 3
  ml.bounce_you_are_disabled_warnings = 0
  ml.default_member_action = Action.discard
  ml.default_nonmember_action = Action.discard
  ml.digests_enabled = False
  ml.filter_content = True
  ml.first_strip_reply_to = True
  ml.forward_auto_discards = False
  ml.max_days_to_hold = 1
  ml.max_message_size = 0
  ml.nntp_prefix_subject_too = False
  ml.pass_extensions = []
  ml.pass_types = ['text/plain','multipart/alternative']
  ml.reply_goes_to_list = ReplyToMunging.explicit_header
  ml.reply_to_address = "no-re...@example.com"
  ml.require_explicit_destination = False
  ml.respond_to_post_requests = False


# Description value must be passed as a parameter
def configure_notification_list(ml, description):
  """Configure general notification list."""
  set_common(ml)
  ml.description = description
  ml.subscription_policy = SubscriptionPolicy.open
  ml.unsubscription_policy = SubscriptionPolicy.open

  add_nonmember_sender(ml, 'list-all-boun...@example.com')
  add_nonmember_sender(ml, 'sitead...@example.com')


def configure_all_list(ml):
  """Configure the send to all lists list."""
  set_common(ml)
  ml.description = "Notify_All"
  ml.subscription_policy = SubscriptionPolicy.confirm_then_moderate
  ml.unsubscription_policy = SubscriptionPolicy.confirm

  add_nonmember_sender(ml, 'sitead...@example.com')


def configure_admin_list(ml):
  """Configure the admin list that is copied on all posts"""
  set_common(ml)
  ml.description = admin_description
  ml.subscription_policy = SubscriptionPolicy.confirm_then_moderate
  ml.unsubscription_policy = SubscriptionPolicy.confirm

  add_nonmember_sender(ml, 'list-all-boun...@example.com')
  add_nonmember_sender(ml, 'sitead...@example.com')


# Sender list username value must be passed as a parameter (e.g. list-0000)
def update_admin_list(ml, sender):
  """Add a notification list as approved sender to the admin list."""
  add_nonmember_sender(ml, sender +'-boun...@example.com')


## Main entry point
def configure_list(ml, parameter):
  if ml.list_name == 'list-all':
    configure_all_list(ml)
  elif ml.list_name == 'list-admin':
    if ml.description == None or ml.description != admin_description:
      configure_admin_list(ml)
    else:
      update_admin_list(ml, parameter)
  else:
    configure_notification_list(ml,parameter)
___________________________________________
Mailman's content filtering has removed the
following MIME parts from this message.

Replaced multipart/alternative part with first alternative.
_______________________________________________
Mailman-users mailing list -- mailman-users@mailman3.org
To unsubscribe send an email to mailman-users-le...@mailman3.org
https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/
Archived at: 
https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/message/EFPYKO22R5E7OITWYMNV22W7UE472WQ5/

This message sent to arch...@mail-archive.com

Reply via email to