{#- Converges listmonk's database-held configuration. Every statement prints the number of rows it changed, so the play can report "changed" and only restart listmonk when something actually moved. -#} {%- macro q(s) -%}$lmv${{ s }}$lmv${%- endmacro -%} {%- set settings = { 'app.site_name': listmonk_site_name, 'app.root_url': listmonk_root_url, 'app.from_email': listmonk_from_email, 'app.logo_url': listmonk_logo_url, 'app.favicon_url': listmonk_favicon_url, 'app.notify_emails': listmonk_notify_emails, 'app.enable_public_subscription_page': true, 'app.enable_public_archive': true, 'app.send_optin_confirmation': true, 'privacy.individual_tracking': false, 'privacy.unsubscribe_header': true, 'privacy.record_optin_ip': false, 'security.captcha': { 'altcha': {'enabled': true, 'complexity': 300000}, 'hcaptcha': {'enabled': false, 'key': '', 'secret': ''}, }, 'security.oidc': { 'enabled': listmonk_oidc_enabled | bool, 'provider_url': listmonk_oidc_provider_url, 'provider_name': listmonk_oidc_provider_name, 'client_id': listmonk_oidc_client_id, 'client_secret': listmonk_oidc_client_secret, 'auto_create_users': false, 'default_user_role_id': none, 'default_list_role_id': none, }, 'upload.provider': 'filesystem', 'upload.filesystem.upload_path': '/listmonk/uploads', 'upload.filesystem.upload_uri': '/uploads', 'smtp': [{ 'enabled': true, 'host': listmonk_smtp_host, 'port': listmonk_smtp_port | int, 'auth_protocol': 'login', 'username': listmonk_smtp_username, 'password': listmonk_smtp_password, 'hello_hostname': listmonk_host, 'max_conns': listmonk_smtp_max_conns | int, 'idle_timeout': '15s', 'wait_timeout': '5s', 'max_msg_retries': 2, 'msg_retry_delay': '10ms', 'tls_type': listmonk_smtp_tls_type, 'tls_skip_verify': false, 'email_headers': [], 'from_addresses': [], }], 'appearance.public.custom_css': lookup('ansible.builtin.file', role_path ~ '/files/public.css'), 'appearance.admin.custom_css': lookup('ansible.builtin.file', role_path ~ '/files/admin.css'), } | combine(listmonk_settings_extra) -%} \set ON_ERROR_STOP on BEGIN; WITH desired(key, value) AS (VALUES {% for k, v in settings.items() %} ({{ q(k) }}, {{ q(v | to_json) }}::jsonb){{ ',' if not loop.last }} {% endfor %} ), changed AS ( UPDATE settings s SET value = d.value, updated_at = NOW() FROM desired d WHERE s.key = d.key AND s.value IS DISTINCT FROM d.value RETURNING s.key ) SELECT count(*) FROM changed; {% for u in listmonk_oidc_admins %} WITH ins AS ( INSERT INTO users (username, password_login, email, name, type, user_role_id, status) SELECT {{ q(u.username) }}, false, {{ q(u.email | lower) }}, {{ q(u.name) }}, 'user', r.id, 'enabled' FROM roles r WHERE r.name = 'Super Admin' AND r.type = 'user' ON CONFLICT DO NOTHING RETURNING id ) SELECT count(*) FROM ins; {% endfor %} {% for l in listmonk_lists %} WITH ins AS ( INSERT INTO lists (uuid, name, type, optin, tags, description) SELECT gen_random_uuid(), {{ q(l.name) }}, {{ q(l.type | default('public')) }}::list_type, {{ q(l.optin | default('double')) }}::list_optin, ARRAY[{% for t in l.tags | default([]) %}{{ q(t) }}{{ ',' if not loop.last }}{% endfor %}]::varchar(100)[], {{ q(l.description | default('') | trim) }} WHERE NOT EXISTS (SELECT 1 FROM lists WHERE name = {{ q(l.name) }}) RETURNING id ) SELECT count(*) FROM ins; WITH upd AS ( UPDATE lists SET type = {{ q(l.type | default('public')) }}::list_type, optin = {{ q(l.optin | default('double')) }}::list_optin, description = {{ q(l.description | default('') | trim) }}, updated_at = NOW() WHERE name = {{ q(l.name) }} AND (type, optin, description) IS DISTINCT FROM ({{ q(l.type | default('public')) }}::list_type, {{ q(l.optin | default('double')) }}::list_optin, {{ q(l.description | default('') | trim) }}) RETURNING id ) SELECT count(*) FROM upd; {% endfor %} {% if listmonk_remove_sample_data | bool %} WITH del AS ( DELETE FROM campaigns WHERE archive_slug = 'welcome-to-listmonk' AND status = 'draft' AND 'test-campaign' = ANY(tags) RETURNING id ) SELECT count(*) FROM del; WITH del AS ( DELETE FROM subscribers WHERE email IN ('john@example.com', 'anon@example.com') RETURNING id ) SELECT count(*) FROM del; WITH del AS ( DELETE FROM lists l WHERE l.name IN ('Default list', 'Opt-in list') AND l.tags = ARRAY['test']::varchar(100)[] AND NOT EXISTS (SELECT 1 FROM subscriber_lists sl WHERE sl.list_id = l.id) RETURNING id ) SELECT count(*) FROM del; {% endif %} COMMIT;