diff --git a/.gitignore b/.gitignore
index 796b25dc3..5e0a9d100 100644
--- a/.gitignore
+++ b/.gitignore
@@ -87,6 +87,7 @@
!/macrocli/
!/sbox/
!/quietshrink/
+!/mailchimp/
# Step 5: Inside each software dir, ignore everything (including dotfiles)
/gimp/*
@@ -181,6 +182,8 @@
/sbox/.*
/quietshrink/*
/quietshrink/.*
+/mailchimp/*
+/mailchimp/.*
# Step 6: ...except agent-harness/
!/gimp/agent-harness/
@@ -235,6 +238,7 @@
!/macrocli/agent-harness/
!/sbox/agent-harness/
!/quietshrink/agent-harness/
+!/mailchimp/agent-harness/
# Exclude non-gedit demo macros from macrocli (local only)
/macrocli/agent-harness/cli_anything/macrocli/macro_definitions/demo/flameshot*
diff --git a/README.md b/README.md
index b22f197ee..d98b16cd8 100644
--- a/README.md
+++ b/README.md
@@ -862,6 +862,13 @@ Each application received complete, production-ready CLI interfaces โ not demo
โ
55+ cmds |
+| ๐ง Mailchimp |
+Email Marketing & Automation |
+cli-anything-mailchimp |
+Mailchimp Marketing API v3.0 |
+โ
303 cmds |
+
+
| ๐ Zotero |
Reference Management |
cli-anything-zotero |
@@ -1162,6 +1169,7 @@ cli-anything/
โโโ ๐ต audacity/agent-harness/ # Audacity CLI (161 tests)
โโโ ๐ browser/agent-harness/ # Browser CLI (DOMShell MCP, new)
โโโ ๐ libreoffice/agent-harness/ # LibreOffice CLI (158 tests)
+โโโ ๐ง mailchimp/agent-harness/ # Mailchimp Marketing API CLI (303 commands, 36 unit tests)
โโโ ๐ zotero/agent-harness/ # Zotero CLI (new, write import support)
โโโ ๐ mubu/agent-harness/ # Mubu CLI (96 tests)
โโโ ๐น obs-studio/agent-harness/ # OBS Studio CLI (153 tests)
diff --git a/mailchimp/agent-harness/MAILCHIMP.md b/mailchimp/agent-harness/MAILCHIMP.md
new file mode 100644
index 000000000..106c61682
--- /dev/null
+++ b/mailchimp/agent-harness/MAILCHIMP.md
@@ -0,0 +1,160 @@
+# MAILCHIMP.md โ cli-anything Harness for Mailchimp Marketing API v3.0
+
+## Overview
+
+`cli-anything-mailchimp` makes the [Mailchimp Marketing API v3.0](https://mailchimp.com/developer/marketing/docs/fundamentals/) fully agent-native. Every endpoint from the official Swagger spec is exposed as a typed Click command, with JSON output and REPL mode.
+
+**303 commands across 30 resource groups**, covering the full Marketing API surface.
+
+---
+
+## Backend
+
+| Property | Value |
+|---|---|
+| API base | `https://.api.mailchimp.com/3.0` |
+| Auth | HTTP Basic โ username `anystring`, password = API key |
+| Key format | `-` e.g. `abc123-us8` |
+| Spec source | `mailchimp/mailchimp-client-lib-codegen` โ `spec/marketing.json` (Swagger 2.0) |
+
+**Required env var:**
+```bash
+export MAILCHIMP_API_KEY=-
+```
+No config files. The data-centre prefix (`us8`, `eu2`, etc.) is derived automatically from the API key suffix.
+
+---
+
+## Command Hierarchy
+
+```
+cli-anything-mailchimp [--json] [--version]
+โ
+โโโ ping # GET /ping โ health check
+โโโ root # GET / โ account info
+โ
+โโโ lists # 66 operations (audiences, members, merge fields, segments, tags, webhooks)
+โ โโโ list / get / create / update / delete
+โ โโโ list-lists-id-members / get-lists-id-members-id / create-members / ...
+โ โโโ list-merge-fields / create-merge-fields / ...
+โ โโโ list-segments / get-segment-id / create-segments / ...
+โ โโโ list-webhooks / get-webhook-id / create-webhooks / ...
+โ
+โโโ campaigns # 22 operations
+โ โโโ list / get / create / update / delete
+โ โโโ send / schedule / cancel-send / pause / resume / replicate
+โ โโโ list-content / list-feedback / get-feedback-id / create-feedback
+โ โโโ list-send-checklist / create-resend
+โ
+โโโ reports # 22 operations โ sent campaign analytics
+โ โโโ list / get
+โ โโโ list-abuse-reports / list-click-details / list-domain-performance
+โ โโโ list-email-activity / list-locations / list-open-details
+โ โโโ list-sub-reports / list-unsubscribed
+โ
+โโโ automations # 18 operations
+โ โโโ list / get / create / update
+โ โโโ pause / start / archive
+โ โโโ list-emails / get-email / pause-email / start-email / delete-email
+โ
+โโโ ecommerce # 60 operations โ stores, orders, products, carts, promo codes
+โโโ templates # 6 operations
+โโโ template-folders # 5 operations
+โโโ campaign-folders # 5 operations
+โโโ file-manager # 11 operations โ files and folders
+โโโ reporting # 12 operations โ Facebook/landing-page reporting
+โโโ landing-pages # 8 operations
+โโโ sms-campaigns # 10 operations
+โโโ surveys # 3 operations
+โโโ audiences # 4 operations โ connected audience management
+โโโ batch-webhooks # 5 operations
+โโโ batches # 4 operations โ bulk API batch operations
+โโโ connected-sites # 5 operations
+โโโ contacts # 4 operations
+โโโ conversations # 4 operations
+โโโ customer-journeys # 1 operation
+โโโ facebook-ads # 2 operations
+โโโ verified-domains # 5 operations
+โโโ authorized-apps # 2 operations
+โโโ activity-feed # 1 operation
+โโโ account-export # 1 operation
+โโโ account-exports # 2 operations
+โโโ search-campaigns # 1 operation
+โโโ search-members # 1 operation
+```
+
+---
+
+## Output Strategy
+
+All commands share a root `--json` flag:
+
+```bash
+cli-anything-mailchimp --json lists list
+cli-anything-mailchimp --json campaigns get
+```
+
+**JSON envelopes** (commands emit the native Mailchimp API response):
+
+| Endpoint type | Shape |
+|---|---|
+| List / collection | Native shape: `{"lists":[...], "total_items":N}` / `{"campaigns":[...]}` etc. โ resource key matches the API path noun |
+| Single resource GET | Raw Mailchimp response object |
+| Mutation (POST/PATCH/PUT) | Raw Mailchimp response object |
+| DELETE | `{"ok": true, "message": "Deleted."}` |
+| Error | `{"ok": false, "message": "...", "data": }` |
+
+Use the Mailchimp-native field name when piping to `jq` (e.g. `.lists[]`, `.campaigns[]`, `.members[]`).
+
+Human mode prints compact key-value pairs for single objects and annotated lists for collections.
+
+Collection commands expose Mailchimp's native `count` and `offset` query parameters where the API supports them. The CLI does not auto-fetch every page by default.
+
+---
+
+## Design Decisions
+
+1. **Code generation from spec** โ 303 commands are auto-generated from Mailchimp's public Swagger 2.0 spec via `_codegen/generate.py`. Generated files are committed so end-users get fast `--help` without downloading the spec.
+
+2. **Env-var-only auth** โ per CLI-Anything convention, no config files. `MAILCHIMP_API_KEY` is the single source of truth.
+
+3. **Verbatim `repl_skin.py`** โ the REPL skin is copied unmodified from `cli-anything-plugin/repl_skin.py` as required by CLI-Anything's contribution rules.
+
+4. **Path params as positional args** โ Mailchimp path parameters (`{list_id}`, `{campaign_id}`, etc.) become required positional Click arguments, keeping commands concise.
+
+5. **Body as `--data` JSON** โ request bodies are passed as `--data '{"key": "value"}'` JSON strings. This avoids generating dozens of per-field flags per command and works naturally for agent use (agents can construct JSON payloads directly).
+
+6. **Subscriber hash utility** โ `cli_anything.mailchimp.core.client.subscriber_hash(email)` computes the MD5 hash Mailchimp uses as a member identifier, matching the Node.js reference implementation.
+
+---
+
+## File Layout
+
+```
+mailchimp/agent-harness/
+โโโ setup.py
+โโโ MAILCHIMP.md โ this file
+โโโ cli_anything/mailchimp/
+ โโโ __init__.py
+ โโโ __main__.py
+ โโโ mailchimp_cli.py โ Click root + REPL
+ โโโ README.md
+ โโโ core/
+ โ โโโ client.py โ HTTP client, auth, error handling
+ โ โโโ pagination.py โ count/offset paginator
+ โโโ commands/ โ auto-generated (30 modules)
+ โ โโโ __init__.py โ imports ALL_GROUPS
+ โ โโโ lists.py โ 66 commands
+ โ โโโ campaigns.py โ 22 commands
+ โ โโโ ... โ one module per tag
+ โโโ utils/
+ โ โโโ output.py โ _out() JSON/human switch
+ โ โโโ repl_skin.py โ verbatim copy from cli-anything-plugin/repl_skin.py
+ โโโ _codegen/
+ โ โโโ generate.py โ spec โ commands/*.py generator
+ โโโ skills/SKILL.md โ packaged skill copy
+ โโโ tests/
+ โโโ TEST.md
+ โโโ test_core.py โ unit tests (no API key)
+ โโโ test_full_e2e.py โ 9 live tests (gated on API key)
+```
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/README.md b/mailchimp/agent-harness/cli_anything/mailchimp/README.md
new file mode 100644
index 000000000..a552b04df
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/README.md
@@ -0,0 +1,26 @@
+# cli-anything-mailchimp
+
+Python CLI harness for the [Mailchimp Marketing API v3.0](https://mailchimp.com/developer/marketing/docs/fundamentals/), built on the [CLI-Anything](https://github.com/HKUDS/CLI-Anything) framework.
+
+## Install
+
+```bash
+pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=mailchimp/agent-harness
+```
+
+## Auth
+
+```bash
+export MAILCHIMP_API_KEY=-
+```
+
+## Usage
+
+```bash
+cli-anything-mailchimp ping
+cli-anything-mailchimp --json lists list
+cli-anything-mailchimp --json campaigns list --count 10
+cli-anything-mailchimp # interactive REPL
+```
+
+See `SKILL.md` for full command reference.
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/__init__.py b/mailchimp/agent-harness/cli_anything/mailchimp/__init__.py
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/__init__.py
@@ -0,0 +1 @@
+
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/__main__.py b/mailchimp/agent-harness/cli_anything/mailchimp/__main__.py
new file mode 100644
index 000000000..793b5c756
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/__main__.py
@@ -0,0 +1,3 @@
+from cli_anything.mailchimp.mailchimp_cli import main
+if __name__ == "__main__":
+ main()
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/_codegen/__init__.py b/mailchimp/agent-harness/cli_anything/mailchimp/_codegen/__init__.py
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/_codegen/__init__.py
@@ -0,0 +1 @@
+
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/_codegen/generate.py b/mailchimp/agent-harness/cli_anything/mailchimp/_codegen/generate.py
new file mode 100644
index 000000000..130a3f202
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/_codegen/generate.py
@@ -0,0 +1,429 @@
+"""
+Code generator: Mailchimp Swagger 2.0 spec โ Click command modules.
+
+Usage:
+ python -m cli_anything.mailchimp._codegen.generate
+
+Downloads the Mailchimp Marketing API spec and emits one Python module per
+tag into cli_anything/mailchimp/commands/. The generated files are committed
+to the repository so end-users do not need to run the generator.
+"""
+
+from __future__ import annotations
+
+import builtins
+import json
+import keyword
+import os
+import re
+import sys
+import textwrap
+from collections import defaultdict
+from pathlib import Path
+
+import requests
+
+SPEC_URL = (
+ "https://raw.githubusercontent.com/mailchimp/mailchimp-client-lib-codegen"
+ "/main/spec/marketing.json"
+)
+
+OUT_DIR = Path(__file__).resolve().parents[1] / "commands"
+
+# Tags that should be skipped (internal/meta).
+_SKIP_TAGS: set[str] = set()
+
+# Names that must not appear as Python function/param names even if technically
+# valid identifiers (builtins + common shadowing traps).
+_BUILTIN_NAMES: frozenset[str] = frozenset(dir(builtins))
+
+
+def _slugify(name: str) -> str:
+ """Convert camelCase or PascalCase or space-separated to kebab-case."""
+ s = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1-\2", name)
+ s = re.sub(r"([a-z\d])([A-Z])", r"\1-\2", s)
+ s = s.replace(" ", "-").replace("_", "-").lower()
+ s = re.sub(r"-+", "-", s).strip("-")
+ return s
+
+
+def _safe_name(name: str) -> str:
+ """Convert a string to a safe Python identifier (keywords and builtins get underscore suffix)."""
+ name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
+ if name and name[0].isdigit():
+ name = "_" + name
+ if keyword.iskeyword(name) or name in _BUILTIN_NAMES:
+ name += "_"
+ return name
+
+
+def _tag_to_module(tag: str) -> str:
+ return _slugify(tag).replace("-", "_")
+
+
+def _tag_to_group(tag: str) -> str:
+ return _slugify(tag)
+
+
+def _infer_command_name(method: str, path: str, operation_id: str) -> str:
+ """Derive a clean command name from the HTTP method and path."""
+ # Action endpoints (POST to .../actions/xxx)
+ action_match = re.search(r"/actions/([^/]+)$", path)
+ if action_match:
+ return _slugify(action_match.group(1))
+
+ # Determine if this is a collection endpoint or single-resource by checking
+ # whether the path ends with a path parameter.
+ ends_with_param = bool(re.search(r"\{[^}]+\}$", path))
+
+ if method == "get":
+ return "get" if ends_with_param else "list"
+ elif method == "post":
+ return "create"
+ elif method in ("patch", "put"):
+ return "update"
+ elif method == "delete":
+ return "delete"
+ else:
+ return _slugify(operation_id)
+
+
+def _dedup_suffix(cmd_name: str, path: str, operation_id: str, count: int) -> str:
+ """Return a unique suffix for a colliding command name.
+
+ Prefers a slug derived from the operationId over a raw path segment,
+ because path segments are often path-param shaped ({list_id}) which
+ produces confusing names like 'create-list-id'.
+ """
+ # Try a meaningful suffix from the operationId (strip the HTTP verb prefix)
+ op_slug = _slugify(re.sub(r"^(get|post|patch|put|delete)", "", operation_id))
+ if op_slug and op_slug != cmd_name:
+ return f"{cmd_name}-{op_slug}"
+
+ # Fall back to the last non-param path segment
+ segments = [s for s in path.rstrip("/").split("/") if s and not s.startswith("{")]
+ if segments:
+ suffix = _slugify(segments[-1])
+ if suffix and suffix != cmd_name:
+ return f"{cmd_name}-{suffix}"
+
+ return f"{cmd_name}-{count}"
+
+
+def _param_type_to_click(param: dict) -> str:
+ t = param.get("type", "string")
+ if t == "integer":
+ return "int"
+ if t == "boolean":
+ return "bool"
+ return "str"
+
+
+def _click_help_text(description: str) -> str:
+ """Return a single-line Click help string without truncating useful API context."""
+ first_line = description.split("\n")[0]
+ return " ".join(first_line.replace('"', '\\"').split())
+
+
+def _collect_params(operation: dict, path: str) -> tuple[list[dict], list[dict], dict | None]:
+ """Return (path_params, query_params, body_param) from operation."""
+ params = operation.get("parameters", [])
+ path_params = [p for p in params if p.get("in") == "path"]
+ query_params = [p for p in params if p.get("in") == "query"]
+ body_params = [p for p in params if p.get("in") == "body"]
+ body = body_params[0] if body_params else None
+ return path_params, query_params, body
+
+
+def _generate_command_func(
+ cmd_name: str,
+ method: str,
+ path: str,
+ operation: dict,
+ path_params: list,
+ query_params: list,
+ body_param: dict | None,
+) -> str:
+ summary = operation.get("summary", "").replace('"', '\\"')
+ # C1: prefix with _cmd_ so no builtin shadowing (list, get, delete, etc.)
+ func_name = "_cmd_" + _safe_name(cmd_name.replace("-", "_"))
+
+ lines: list[str] = []
+
+ group_var = f"{_tag_to_module(operation['tags'][0])}_group"
+ decorators = [f'@{group_var}.command("{cmd_name}")']
+
+ # Path params as Click arguments (positional)
+ for p in path_params:
+ py_arg = _safe_name(p["name"]).upper()
+ decorators.append(f'@click.argument("{py_arg}")')
+
+ # Body option
+ if body_param is not None:
+ decorators.append(
+ '@click.option("--data", default=None, '
+ 'help="Request body as JSON string.")'
+ )
+
+ # I3: All query params (no arbitrary cap); --extra-params escape hatch
+ for p in query_params:
+ flag = _slugify(p["name"])
+ py_name = _safe_name(p["name"]).lower()
+ ptype = _param_type_to_click(p)
+ desc = _click_help_text(p.get("description", ""))
+ if ptype == "int":
+ type_clause = "type=int, "
+ elif ptype == "bool":
+ type_clause = "type=bool, "
+ else:
+ type_clause = ""
+ decorators.append(
+ f'@click.option("--{flag}", "{py_name}", default=None, {type_clause}help="{desc}")'
+ )
+
+ # Escape hatch for extra/future query params
+ decorators.append(
+ '@click.option("--extra-params", default=None, '
+ 'help="Extra query params as JSON object, e.g. \'{\\"key\\":\\"val\\"}\'")'
+ )
+
+ decorators.append("@click.pass_context")
+
+ for d in decorators:
+ lines.append(d)
+
+ # Function signature โ M4: no module-level USE_JSON import needed
+ sig_parts = ["ctx"]
+ for p in path_params:
+ sig_parts.append(_safe_name(p["name"]).lower())
+ if body_param is not None:
+ sig_parts.append("data")
+ for p in query_params:
+ sig_parts.append(_safe_name(p["name"]).lower())
+ sig_parts.append("extra_params")
+
+ lines.append(f'def {func_name}({", ".join(sig_parts)}):')
+ lines.append(f' """{summary}"""')
+
+ lines.append(" from cli_anything.mailchimp.core.client import get_client, MailchimpError")
+ lines.append(" from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err")
+
+ # Build path with lowercased path params
+ url_parts = re.sub(
+ r"\{([^}]+)\}",
+ lambda m: "{" + _safe_name(m.group(1)).lower() + "}",
+ path,
+ )
+ lines.append(f' path = f"{url_parts}"')
+
+ # Build query params dict
+ if query_params:
+ lines.append(" params = {k: v for k, v in {")
+ for p in query_params:
+ py_name = _safe_name(p["name"]).lower()
+ lines.append(f' "{p["name"]}": {py_name},')
+ lines.append(" }.items() if v is not None}")
+ else:
+ lines.append(" params = {}")
+
+ # Merge --extra-params
+ lines.append(" if extra_params:")
+ lines.append(' params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))')
+
+ # Parse body
+ if body_param is not None:
+ lines.append(' body = _parse_json_option(data, "--data") if data else None')
+
+ # Make the request
+ lines.append(" client = get_client()")
+ lines.append(" try:")
+ if method == "get":
+ lines.append(" result = client.get(path, params=params or None)")
+ elif method == "post":
+ body_arg = "body" if body_param else "None"
+ lines.append(f" result = client.post(path, json={body_arg}, params=params or None)")
+ elif method == "patch":
+ body_arg = "body" if body_param else "None"
+ lines.append(f" result = client.patch(path, json={body_arg}, params=params or None)")
+ elif method == "put":
+ body_arg = "body" if body_param else "None"
+ lines.append(f" result = client.put(path, json={body_arg}, params=params or None)")
+ elif method == "delete":
+ lines.append(" result = client.delete(path, params=params or None)")
+ else:
+ lines.append(" result = client.get(path, params=params or None)")
+
+ lines.append(" except MailchimpError as e:")
+ lines.append(" _out_err(e.status, e.title, e.detail, e.raw)")
+ lines.append(" return")
+
+ if method == "delete":
+ lines.append(' _out_ok("Deleted.")')
+ else:
+ lines.append(" _out(result)")
+
+ lines.append("")
+ return "\n".join(lines)
+
+
+def _generate_module(tag: str, operations: list[tuple[str, str, dict]]) -> str:
+ """Generate a complete Python module for a given tag."""
+ module_name = _tag_to_module(tag)
+ group_name = _tag_to_group(tag)
+ group_var = f"{module_name}_group"
+
+ group_decorator = f'@click.group("{group_name}")'
+ group_signature = f"def {group_var}(ctx):"
+ if tag.lower() == "ping":
+ group_decorator = f'@click.group("{group_name}", invoke_without_command=True)'
+ group_lines = [
+ f' """{_slugify(tag)} resource commands."""',
+ ]
+ if tag.lower() == "ping":
+ group_lines.extend(
+ [
+ " if ctx.invoked_subcommand is None:",
+ " ctx.invoke(_cmd_list_)",
+ ]
+ )
+
+ header_lines = [
+ f'"""Commands for the Mailchimp /{group_name} API resource.',
+ "",
+ "Auto-generated by cli_anything/mailchimp/_codegen/generate.py.",
+ "Do not edit manually โ re-run the generator to update.",
+ '"""',
+ "",
+ "import json",
+ "",
+ "import click",
+ "",
+ "",
+ "def _parse_json_option(value, option_name, require_object=False):",
+ " try:",
+ " parsed = json.loads(value)",
+ " except json.JSONDecodeError as exc:",
+ " raise click.BadParameter(",
+ ' f"must be valid JSON ({exc.msg})",',
+ " param_hint=option_name,",
+ " ) from exc",
+ " if require_object and not isinstance(parsed, dict):",
+ ' raise click.BadParameter("must be a JSON object", param_hint=option_name)',
+ " return parsed",
+ "",
+ "",
+ group_decorator,
+ "@click.pass_context",
+ group_signature,
+ *group_lines,
+ "",
+ "",
+ ]
+ header = "\n".join(header_lines)
+
+ body_parts: list[str] = []
+ # Track ALL assigned names (base + deduped) to guarantee uniqueness.
+ assigned: set[str] = set()
+
+ for method, path, operation in sorted(operations, key=lambda x: (x[1], x[0])):
+ op_id = operation.get("operationId", "")
+ cmd_name = _infer_command_name(method, path, op_id)
+
+ # I4: De-duplicate using operationId slug; fall back to counter if still collides.
+ if cmd_name in assigned:
+ candidate = _dedup_suffix(cmd_name, path, op_id, 2)
+ counter = 2
+ while candidate in assigned:
+ counter += 1
+ candidate = f"{cmd_name}-{counter}"
+ cmd_name = candidate
+
+ assigned.add(cmd_name)
+
+ operation = dict(operation)
+ operation.setdefault("tags", [tag])
+
+ path_params, query_params, body_param = _collect_params(operation, path)
+ func_code = _generate_command_func(
+ cmd_name, method, path, operation, path_params, query_params, body_param
+ )
+ body_parts.append(func_code)
+ if tag.lower() == "campaigns" and cmd_name == "list-campaigns-id-content":
+ body_parts.append('campaigns_group.add_command(_cmd_list_campaigns_id_content, "list-content")\n')
+ if tag.lower() == "campaigns" and cmd_name == "list-campaigns-id-send-checklist":
+ body_parts.append('campaigns_group.add_command(_cmd_list_campaigns_id_send_checklist, "list-send-checklist")\n')
+ if tag.lower() == "reports" and cmd_name == "list-reports-id-click-details":
+ body_parts.append('reports_group.add_command(_cmd_list_reports_id_click_details, "list-click-details")\n')
+ if tag.lower() == "reports" and cmd_name == "list-reports-id-domain-performance":
+ body_parts.append('reports_group.add_command(_cmd_list_reports_id_domain_performance, "list-domain-performance")\n')
+ if tag.lower() == "reports" and cmd_name == "list-reports-id-email-activity":
+ body_parts.append('reports_group.add_command(_cmd_list_reports_id_email_activity, "list-email-activity")\n')
+ if tag.lower() == "reports" and cmd_name == "list-reports-id-locations":
+ body_parts.append('reports_group.add_command(_cmd_list_reports_id_locations, "list-locations")\n')
+ if tag.lower() == "reports" and cmd_name == "list-reports-id-open-details":
+ body_parts.append('reports_group.add_command(_cmd_list_reports_id_open_details, "list-open-details")\n')
+ if tag.lower() == "reports" and cmd_name == "list-reports-id-unsubscribed":
+ body_parts.append('reports_group.add_command(_cmd_list_reports_id_unsubscribed, "list-unsubscribed")\n')
+ if tag.lower() == "automations" and cmd_name == "list-automations-id-emails":
+ body_parts.append('automations_group.add_command(_cmd_list_automations_id_emails, "list-emails")\n')
+ if tag.lower() == "lists" and cmd_name == "create-lists-id-members":
+ body_parts.append('lists_group.add_command(_cmd_create_lists_id_members, "create-members")\n')
+ if tag.lower() == "lists" and cmd_name == "list-preview-a-segment":
+ body_parts.append('lists_group.add_command(_cmd_list_preview_a_segment, "list-lists-id-segments")\n')
+
+ return header + "\n".join(body_parts)
+
+
+def load_spec(url: str = SPEC_URL) -> dict:
+ print(f"Fetching spec from {url} ...", file=sys.stderr)
+ resp = requests.get(url, timeout=60)
+ resp.raise_for_status()
+ return resp.json()
+
+
+def generate(spec: dict, out_dir: Path = OUT_DIR) -> None:
+ out_dir.mkdir(parents=True, exist_ok=True)
+
+ by_tag: dict[str, list[tuple[str, str, dict]]] = defaultdict(list)
+
+ for path, path_item in spec.get("paths", {}).items():
+ for method, operation in path_item.items():
+ if method not in ("get", "post", "patch", "put", "delete"):
+ continue
+ if not isinstance(operation, dict):
+ continue
+ tags = operation.get("tags", ["misc"])
+ tag = tags[0]
+ if tag in _SKIP_TAGS:
+ continue
+ by_tag[tag].append((method, path, operation))
+
+ generated: list[str] = []
+ for tag, operations in sorted(by_tag.items()):
+ module_name = _tag_to_module(tag)
+ out_path = out_dir / f"{module_name}.py"
+ code = _generate_module(tag, operations)
+ out_path.write_text(code, encoding="utf-8")
+ generated.append(module_name)
+ print(f" Generated {out_path.name} ({len(operations)} commands)", file=sys.stderr)
+
+ # Write __init__.py that imports all groups
+ init_lines = ['"""Auto-generated command groups for cli-anything-mailchimp."""', ""]
+ for mod in sorted(generated):
+ group_var = f"{mod}_group"
+ init_lines.append(f"from cli_anything.mailchimp.commands.{mod} import {group_var}")
+ init_lines.append("")
+ init_lines.append("ALL_GROUPS = [")
+ for mod in sorted(generated):
+ group_var = f"{mod}_group"
+ init_lines.append(f" {group_var},")
+ init_lines.append("]")
+ init_lines.append("")
+
+ (out_dir / "__init__.py").write_text("\n".join(init_lines), encoding="utf-8")
+ print(f"\nDone โ {len(generated)} modules written to {out_dir}", file=sys.stderr)
+
+
+if __name__ == "__main__":
+ spec = load_spec()
+ generate(spec)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/__init__.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/__init__.py
new file mode 100644
index 000000000..2cb1ce622
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/__init__.py
@@ -0,0 +1,65 @@
+"""Auto-generated command groups for cli-anything-mailchimp."""
+
+from cli_anything.mailchimp.commands.account_export import account_export_group
+from cli_anything.mailchimp.commands.account_exports import account_exports_group
+from cli_anything.mailchimp.commands.activity_feed import activity_feed_group
+from cli_anything.mailchimp.commands.audiences import audiences_group
+from cli_anything.mailchimp.commands.authorized_apps import authorized_apps_group
+from cli_anything.mailchimp.commands.automations import automations_group
+from cli_anything.mailchimp.commands.batch_webhooks import batch_webhooks_group
+from cli_anything.mailchimp.commands.batches import batches_group
+from cli_anything.mailchimp.commands.campaign_folders import campaign_folders_group
+from cli_anything.mailchimp.commands.campaigns import campaigns_group
+from cli_anything.mailchimp.commands.connected_sites import connected_sites_group
+from cli_anything.mailchimp.commands.contacts import contacts_group
+from cli_anything.mailchimp.commands.conversations import conversations_group
+from cli_anything.mailchimp.commands.customer_journeys import customer_journeys_group
+from cli_anything.mailchimp.commands.ecommerce import ecommerce_group
+from cli_anything.mailchimp.commands.facebook_ads import facebook_ads_group
+from cli_anything.mailchimp.commands.file_manager import file_manager_group
+from cli_anything.mailchimp.commands.landing_pages import landing_pages_group
+from cli_anything.mailchimp.commands.lists import lists_group
+from cli_anything.mailchimp.commands.ping import ping_group
+from cli_anything.mailchimp.commands.reporting import reporting_group
+from cli_anything.mailchimp.commands.reports import reports_group
+from cli_anything.mailchimp.commands.root import root_group
+from cli_anything.mailchimp.commands.search_campaigns import search_campaigns_group
+from cli_anything.mailchimp.commands.search_members import search_members_group
+from cli_anything.mailchimp.commands.sms_campaigns import sms_campaigns_group
+from cli_anything.mailchimp.commands.surveys import surveys_group
+from cli_anything.mailchimp.commands.template_folders import template_folders_group
+from cli_anything.mailchimp.commands.templates import templates_group
+from cli_anything.mailchimp.commands.verified_domains import verified_domains_group
+
+ALL_GROUPS = [
+ account_export_group,
+ account_exports_group,
+ activity_feed_group,
+ audiences_group,
+ authorized_apps_group,
+ automations_group,
+ batch_webhooks_group,
+ batches_group,
+ campaign_folders_group,
+ campaigns_group,
+ connected_sites_group,
+ contacts_group,
+ conversations_group,
+ customer_journeys_group,
+ ecommerce_group,
+ facebook_ads_group,
+ file_manager_group,
+ landing_pages_group,
+ lists_group,
+ ping_group,
+ reporting_group,
+ reports_group,
+ root_group,
+ search_campaigns_group,
+ search_members_group,
+ sms_campaigns_group,
+ surveys_group,
+ template_folders_group,
+ templates_group,
+ verified_domains_group,
+]
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/account_export.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/account_export.py
new file mode 100644
index 000000000..724211309
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/account_export.py
@@ -0,0 +1,53 @@
+"""Commands for the Mailchimp /account-export API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("account-export")
+@click.pass_context
+def account_export_group(ctx):
+ """account-export resource commands."""
+
+@account_export_group.command("get")
+@click.argument("EXPORT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, export_id, fields, exclude_fields, extra_params):
+ """Get account export info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/account-exports/{export_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/account_exports.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/account_exports.py
new file mode 100644
index 000000000..69e5f0d99
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/account_exports.py
@@ -0,0 +1,77 @@
+"""Commands for the Mailchimp /account-exports API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("account-exports")
+@click.pass_context
+def account_exports_group(ctx):
+ """account-exports resource commands."""
+
+@account_exports_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List account exports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/account-exports"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@account_exports_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add export"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/account-exports"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/activity_feed.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/activity_feed.py
new file mode 100644
index 000000000..bf8caeabc
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/activity_feed.py
@@ -0,0 +1,52 @@
+"""Commands for the Mailchimp /activity-feed API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("activity-feed")
+@click.pass_context
+def activity_feed_group(ctx):
+ """activity-feed resource commands."""
+
+@activity_feed_group.command("list")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, count, offset, extra_params):
+ """Get latest chimp chatter"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/activity-feed/chimp-chatter"
+ params = {k: v for k, v in {
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/audiences.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/audiences.py
new file mode 100644
index 000000000..8ea4fc767
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/audiences.py
@@ -0,0 +1,150 @@
+"""Commands for the Mailchimp /audiences API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("audiences")
+@click.pass_context
+def audiences_group(ctx):
+ """audiences resource commands."""
+
+@audiences_group.command("list")
+@click.argument("AUDIENCE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--cursor", "cursor", default=None, help="Paginate through a collection of records by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request. Default value fetches the first \"page\" of results.")
+@click.option("--created-before", "created_before", default=None, help="Restricts the response to contacts created at or before the specified time (inclusive). Uses ISO 8601 format: 2025-04-23T15:41:36+00:00.")
+@click.option("--created-since", "created_since", default=None, help="Restricts the response to contacts created after the specified time (exclusive). Uses ISO 8601 format: 2025-04-23T15:41:36+00:00.")
+@click.option("--updated-before", "updated_before", default=None, help="Restricts the response to contacts updated at or before the specified time (inclusive). Uses ISO 8601 format: 2025-04-23T15:41:36+00:00.")
+@click.option("--updated-since", "updated_since", default=None, help="Restricts the response to contacts updated after the specified time (exclusive). Uses ISO 8601 format: 2025-04-23T15:41:36+00:00.")
+@click.option("--sort-field", "sort_field", default=None, help="Specifies the field to sort the returned contacts by.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, audience_id, fields, exclude_fields, count, cursor, created_before, created_since, updated_before, updated_since, sort_field, sort_dir, extra_params):
+ """Get Contacts"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}/contacts"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "cursor": cursor,
+ "created_before": created_before,
+ "created_since": created_since,
+ "updated_before": updated_before,
+ "updated_since": updated_since,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@audiences_group.command("create")
+@click.argument("AUDIENCE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--merge-field-validation-mode", "merge_field_validation_mode", default=None, help="Defines how merge field validation is handled. When set to `ignore_required_checks`, the API does not raise an error if required merge fields are missing from the request. When set to `strict`, the API enforces validation and returns an error if any required merge field is not provided. If this setting is omitted, `strict` is applied by default.")
+@click.option("--data-mode", "data_mode", default=None, help="Indicates the data processing mode. In `historical` mode, contact data changes do not trigger automations or webhooks. In `live mode`, such changes do trigger them.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, audience_id, data, merge_field_validation_mode, data_mode, extra_params):
+ """Add Contact"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}/contacts"
+ params = {k: v for k, v in {
+ "merge_field_validation_mode": merge_field_validation_mode,
+ "data_mode": data_mode,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@audiences_group.command("get")
+@click.argument("AUDIENCE_ID")
+@click.argument("CONTACT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, audience_id, contact_id, fields, exclude_fields, extra_params):
+ """Get Contact"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}/contacts/{contact_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@audiences_group.command("update")
+@click.argument("AUDIENCE_ID")
+@click.argument("CONTACT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--merge-field-validation-mode", "merge_field_validation_mode", default=None, help="Defines how merge field validation is handled. When set to `ignore_required_checks`, the API does not raise an error if required merge fields are missing from the request. When set to `strict`, the API enforces validation and returns an error if any required merge field is not provided. If this setting is omitted, `strict` is applied by default.")
+@click.option("--data-mode", "data_mode", default=None, help="Indicates the data processing mode. In `historical` mode, contact data changes do not trigger automations or webhooks. In `live mode`, such changes do trigger them.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, audience_id, contact_id, data, merge_field_validation_mode, data_mode, extra_params):
+ """Update Contact"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}/contacts/{contact_id}"
+ params = {k: v for k, v in {
+ "merge_field_validation_mode": merge_field_validation_mode,
+ "data_mode": data_mode,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/authorized_apps.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/authorized_apps.py
new file mode 100644
index 000000000..38bb6fd85
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/authorized_apps.py
@@ -0,0 +1,81 @@
+"""Commands for the Mailchimp /authorized-apps API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("authorized-apps")
+@click.pass_context
+def authorized_apps_group(ctx):
+ """authorized-apps resource commands."""
+
+@authorized_apps_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List authorized apps"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/authorized-apps"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@authorized_apps_group.command("get")
+@click.argument("APP_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, app_id, fields, exclude_fields, extra_params):
+ """Get authorized app info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/authorized-apps/{app_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/automations.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/automations.py
new file mode 100644
index 000000000..3ca327bcc
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/automations.py
@@ -0,0 +1,430 @@
+"""Commands for the Mailchimp /automations API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("automations")
+@click.pass_context
+def automations_group(ctx):
+ """automations resource commands."""
+
+@automations_group.command("list")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--before-create-time", "before_create_time", default=None, help="Restrict the response to automations created before this time. Uses the ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-create-time", "since_create_time", default=None, help="Restrict the response to automations created after this time. Uses the ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-start-time", "before_start_time", default=None, help="Restrict the response to automations started before this time. Uses the ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-start-time", "since_start_time", default=None, help="Restrict the response to automations started after this time. Uses the ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--status", "status", default=None, help="Restrict the results to automations with the specified status.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, count, offset, fields, exclude_fields, before_create_time, since_create_time, before_start_time, since_start_time, status, extra_params):
+ """List automations"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations"
+ params = {k: v for k, v in {
+ "count": count,
+ "offset": offset,
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "before_create_time": before_create_time,
+ "since_create_time": since_create_time,
+ "before_start_time": before_start_time,
+ "since_start_time": since_start_time,
+ "status": status,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add automation"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("get")
+@click.argument("WORKFLOW_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, workflow_id, fields, exclude_fields, extra_params):
+ """Get automation info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("archive")
+@click.argument("WORKFLOW_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_archive(ctx, workflow_id, extra_params):
+ """Archive automation"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/actions/archive"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("pause-all-emails")
+@click.argument("WORKFLOW_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_pause_all_emails(ctx, workflow_id, extra_params):
+ """Pause automation emails"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/actions/pause-all-emails"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("start-all-emails")
+@click.argument("WORKFLOW_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_start_all_emails(ctx, workflow_id, extra_params):
+ """Start automation emails"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/actions/start-all-emails"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("list-automations-id-emails")
+@click.argument("WORKFLOW_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_automations_id_emails(ctx, workflow_id, extra_params):
+ """List automated emails"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+automations_group.add_command(_cmd_list_automations_id_emails, "list-emails")
+
+@automations_group.command("delete")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, workflow_id, workflow_email_id, extra_params):
+ """Delete workflow email"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@automations_group.command("get-automations-id-emails-id")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_automations_id_emails_id(ctx, workflow_id, workflow_email_id, extra_params):
+ """Get workflow email info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("update")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, workflow_id, workflow_email_id, data, extra_params):
+ """Update workflow email"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("pause")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_pause(ctx, workflow_id, workflow_email_id, extra_params):
+ """Pause automated email"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}/actions/pause"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("start")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_start(ctx, workflow_id, workflow_email_id, extra_params):
+ """Start automated email"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}/actions/start"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("list-automations-id-emails-id-queue")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_automations_id_emails_id_queue(ctx, workflow_id, workflow_email_id, extra_params):
+ """List automated email subscribers"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}/queue"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("create-automations-id-emails-id-queue")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_automations_id_emails_id_queue(ctx, workflow_id, workflow_email_id, data, extra_params):
+ """Add subscriber to workflow email"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}/queue"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("get-automations-id-emails-id-queue-id")
+@click.argument("WORKFLOW_ID")
+@click.argument("WORKFLOW_EMAIL_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_automations_id_emails_id_queue_id(ctx, workflow_id, workflow_email_id, subscriber_hash, extra_params):
+ """Get automated email subscriber"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/emails/{workflow_email_id}/queue/{subscriber_hash}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("list-automations-id-removed-subscribers")
+@click.argument("WORKFLOW_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_automations_id_removed_subscribers(ctx, workflow_id, extra_params):
+ """List subscribers removed from workflow"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/removed-subscribers"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("create-automations-id-removed-subscribers")
+@click.argument("WORKFLOW_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_automations_id_removed_subscribers(ctx, workflow_id, data, extra_params):
+ """Remove subscriber from workflow"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/removed-subscribers"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@automations_group.command("get-automations-id-removed-subscribers-id")
+@click.argument("WORKFLOW_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_automations_id_removed_subscribers_id(ctx, workflow_id, subscriber_hash, extra_params):
+ """Get subscriber removed from workflow"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/automations/{workflow_id}/removed-subscribers/{subscriber_hash}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/batch_webhooks.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/batch_webhooks.py
new file mode 100644
index 000000000..dd1655409
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/batch_webhooks.py
@@ -0,0 +1,144 @@
+"""Commands for the Mailchimp /batch-webhooks API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("batch-webhooks")
+@click.pass_context
+def batch_webhooks_group(ctx):
+ """batch-webhooks resource commands."""
+
+@batch_webhooks_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List batch webhooks"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batch-webhooks"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@batch_webhooks_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add batch webhook"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batch-webhooks"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@batch_webhooks_group.command("delete")
+@click.argument("BATCH_WEBHOOK_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, batch_webhook_id, extra_params):
+ """Delete batch webhook"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batch-webhooks/{batch_webhook_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@batch_webhooks_group.command("get")
+@click.argument("BATCH_WEBHOOK_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, batch_webhook_id, fields, exclude_fields, extra_params):
+ """Get batch webhook info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batch-webhooks/{batch_webhook_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@batch_webhooks_group.command("update")
+@click.argument("BATCH_WEBHOOK_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, batch_webhook_id, data, extra_params):
+ """Update batch webhook"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batch-webhooks/{batch_webhook_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/batches.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/batches.py
new file mode 100644
index 000000000..1aa3a7c5b
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/batches.py
@@ -0,0 +1,122 @@
+"""Commands for the Mailchimp /batches API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("batches")
+@click.pass_context
+def batches_group(ctx):
+ """batches resource commands."""
+
+@batches_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List batch requests"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batches"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@batches_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Start batch operation"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batches"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@batches_group.command("delete")
+@click.argument("BATCH_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, batch_id, extra_params):
+ """Delete batch request"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batches/{batch_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@batches_group.command("get")
+@click.argument("BATCH_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, batch_id, fields, exclude_fields, extra_params):
+ """Get batch operation status"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/batches/{batch_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/campaign_folders.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/campaign_folders.py
new file mode 100644
index 000000000..74aa12717
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/campaign_folders.py
@@ -0,0 +1,144 @@
+"""Commands for the Mailchimp /campaign-folders API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("campaign-folders")
+@click.pass_context
+def campaign_folders_group(ctx):
+ """campaign-folders resource commands."""
+
+@campaign_folders_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List campaign folders"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaign-folders"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaign_folders_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add campaign folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaign-folders"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaign_folders_group.command("delete")
+@click.argument("FOLDER_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, folder_id, extra_params):
+ """Delete campaign folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaign-folders/{folder_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@campaign_folders_group.command("get")
+@click.argument("FOLDER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, folder_id, fields, exclude_fields, extra_params):
+ """Get campaign folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaign-folders/{folder_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaign_folders_group.command("update")
+@click.argument("FOLDER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, folder_id, data, extra_params):
+ """Update campaign folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaign-folders/{folder_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/campaigns.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/campaigns.py
new file mode 100644
index 000000000..68152bc05
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/campaigns.py
@@ -0,0 +1,553 @@
+"""Commands for the Mailchimp /campaigns API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("campaigns")
+@click.pass_context
+def campaigns_group(ctx):
+ """campaigns resource commands."""
+
+@campaigns_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="The campaign type.")
+@click.option("--status", "status", default=None, help="The status of the campaign.")
+@click.option("--before-send-time", "before_send_time", default=None, help="Restrict the response to campaigns sent before the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-send-time", "since_send_time", default=None, help="Restrict the response to campaigns sent after the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-create-time", "before_create_time", default=None, help="Restrict the response to campaigns created before the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-create-time", "since_create_time", default=None, help="Restrict the response to campaigns created after the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--list-id", "list_id", default=None, help="The unique id for the list.")
+@click.option("--folder-id", "folder_id", default=None, help="The unique folder id.")
+@click.option("--member-id", "member_id", default=None, help="Retrieve campaigns sent to a particular list member. Member ID is The MD5 hash of the lowercase version of the list memberโs email address.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--include-resend-shortcut-eligibility", "include_resend_shortcut_eligibility", default=None, type=bool, help="Return the `resend_shortcut_eligibility` field in the response, which tells you if the campaign is eligible for the various Campaign Resend Shortcuts offered.")
+@click.option("--include-resend-shortcut-usage", "include_resend_shortcut_usage", default=None, type=bool, help="Return the `resend_shortcut_usage` field in the response. This includes information about campaigns related by a shortcut.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, type_, status, before_send_time, since_send_time, before_create_time, since_create_time, list_id, folder_id, member_id, sort_field, sort_dir, include_resend_shortcut_eligibility, include_resend_shortcut_usage, extra_params):
+ """List campaigns"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "status": status,
+ "before_send_time": before_send_time,
+ "since_send_time": since_send_time,
+ "before_create_time": before_create_time,
+ "since_create_time": since_create_time,
+ "list_id": list_id,
+ "folder_id": folder_id,
+ "member_id": member_id,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ "include_resend_shortcut_eligibility": include_resend_shortcut_eligibility,
+ "include_resend_shortcut_usage": include_resend_shortcut_usage,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("delete")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, campaign_id, extra_params):
+ """Delete campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@campaigns_group.command("get")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--include-resend-shortcut-eligibility", "include_resend_shortcut_eligibility", default=None, type=bool, help="Return the `resend_shortcut_eligibility` field in the response, which tells you if the campaign is eligible for the various Campaign Resend Shortcuts offered.")
+@click.option("--include-resend-shortcut-usage", "include_resend_shortcut_usage", default=None, type=bool, help="Return the `resend_shortcut_usage` field in the response. This includes information about campaigns related by a shortcut.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, campaign_id, fields, exclude_fields, include_resend_shortcut_eligibility, include_resend_shortcut_usage, extra_params):
+ """Get campaign info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "include_resend_shortcut_eligibility": include_resend_shortcut_eligibility,
+ "include_resend_shortcut_usage": include_resend_shortcut_usage,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("update")
+@click.argument("CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, campaign_id, data, extra_params):
+ """Update campaign settings"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("cancel-send")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_cancel_send(ctx, campaign_id, extra_params):
+ """Cancel campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/cancel-send"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("create-resend")
+@click.argument("CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_resend(ctx, campaign_id, data, extra_params):
+ """Resend campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/create-resend"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("pause")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_pause(ctx, campaign_id, extra_params):
+ """Pause rss campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/pause"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("replicate")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_replicate(ctx, campaign_id, extra_params):
+ """Replicate campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/replicate"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("resume")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_resume(ctx, campaign_id, extra_params):
+ """Resume rss campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/resume"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("schedule")
+@click.argument("CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_schedule(ctx, campaign_id, data, extra_params):
+ """Schedule campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/schedule"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("send")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_send(ctx, campaign_id, extra_params):
+ """Send campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/send"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("test")
+@click.argument("CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_test(ctx, campaign_id, data, extra_params):
+ """Send test email"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/test"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("unschedule")
+@click.argument("CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_unschedule(ctx, campaign_id, extra_params):
+ """Unschedule campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/actions/unschedule"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("list-campaigns-id-content")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_campaigns_id_content(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """Get campaign content"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/content"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+campaigns_group.add_command(_cmd_list_campaigns_id_content, "list-content")
+
+@campaigns_group.command("update-campaigns-id-content")
+@click.argument("CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_campaigns_id_content(ctx, campaign_id, data, extra_params):
+ """Set campaign content"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/content"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("list-campaigns-id-feedback")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_campaigns_id_feedback(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """List campaign feedback"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/feedback"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("create-campaigns-id-feedback")
+@click.argument("CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_campaigns_id_feedback(ctx, campaign_id, data, extra_params):
+ """Add campaign feedback"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/feedback"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("delete-campaigns-id-feedback-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("FEEDBACK_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_campaigns_id_feedback_id(ctx, campaign_id, feedback_id, extra_params):
+ """Delete campaign feedback message"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/feedback/{feedback_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@campaigns_group.command("get-campaigns-id-feedback-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("FEEDBACK_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_campaigns_id_feedback_id(ctx, campaign_id, feedback_id, fields, exclude_fields, extra_params):
+ """Get campaign feedback message"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/feedback/{feedback_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("update-campaigns-id-feedback-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("FEEDBACK_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_campaigns_id_feedback_id(ctx, campaign_id, feedback_id, data, extra_params):
+ """Update campaign feedback message"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/feedback/{feedback_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@campaigns_group.command("list-campaigns-id-send-checklist")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_campaigns_id_send_checklist(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """Get campaign send checklist"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/campaigns/{campaign_id}/send-checklist"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+campaigns_group.add_command(_cmd_list_campaigns_id_send_checklist, "list-send-checklist")
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/connected_sites.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/connected_sites.py
new file mode 100644
index 000000000..d3b0a0d1b
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/connected_sites.py
@@ -0,0 +1,142 @@
+"""Commands for the Mailchimp /connected-sites API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("connected-sites")
+@click.pass_context
+def connected_sites_group(ctx):
+ """connected-sites resource commands."""
+
+@connected_sites_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List connected sites"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/connected-sites"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@connected_sites_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add connected site"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/connected-sites"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@connected_sites_group.command("delete")
+@click.argument("CONNECTED_SITE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, connected_site_id, extra_params):
+ """Delete connected site"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/connected-sites/{connected_site_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@connected_sites_group.command("get")
+@click.argument("CONNECTED_SITE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, connected_site_id, fields, exclude_fields, extra_params):
+ """Get connected site"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/connected-sites/{connected_site_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@connected_sites_group.command("verify-script-installation")
+@click.argument("CONNECTED_SITE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_verify_script_installation(ctx, connected_site_id, extra_params):
+ """Verify connected site script"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/connected-sites/{connected_site_id}/actions/verify-script-installation"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/contacts.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/contacts.py
new file mode 100644
index 000000000..ce446aece
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/contacts.py
@@ -0,0 +1,123 @@
+"""Commands for the Mailchimp /contacts API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("contacts")
+@click.pass_context
+def contacts_group(ctx):
+ """contacts resource commands."""
+
+@contacts_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """Get a list of audiences"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@contacts_group.command("get")
+@click.argument("AUDIENCE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, audience_id, fields, exclude_fields, extra_params):
+ """Get audience info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@contacts_group.command("archive")
+@click.argument("AUDIENCE_ID")
+@click.argument("CONTACT_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_archive(ctx, audience_id, contact_id, extra_params):
+ """Archive Contact"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}/contacts/{contact_id}/actions/archive"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@contacts_group.command("forget")
+@click.argument("AUDIENCE_ID")
+@click.argument("CONTACT_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_forget(ctx, audience_id, contact_id, extra_params):
+ """Forget Contact"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/audiences/{audience_id}/contacts/{contact_id}/actions/forget"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/conversations.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/conversations.py
new file mode 100644
index 000000000..2742c6e3c
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/conversations.py
@@ -0,0 +1,144 @@
+"""Commands for the Mailchimp /conversations API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("conversations")
+@click.pass_context
+def conversations_group(ctx):
+ """conversations resource commands."""
+
+@conversations_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--has-unread-messages", "has_unread_messages", default=None, help="Whether the conversation has any unread messages.")
+@click.option("--list-id", "list_id", default=None, help="The unique id for the list.")
+@click.option("--campaign-id", "campaign_id", default=None, help="The unique id for the campaign.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, has_unread_messages, list_id, campaign_id, extra_params):
+ """List conversations"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/conversations"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "has_unread_messages": has_unread_messages,
+ "list_id": list_id,
+ "campaign_id": campaign_id,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@conversations_group.command("get")
+@click.argument("CONVERSATION_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, conversation_id, fields, exclude_fields, extra_params):
+ """Get conversation"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/conversations/{conversation_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@conversations_group.command("list-conversations-id-messages")
+@click.argument("CONVERSATION_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--is-read", "is_read", default=None, help="Whether a conversation message has been marked as read.")
+@click.option("--before-timestamp", "before_timestamp", default=None, help="Restrict the response to messages created before the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-timestamp", "since_timestamp", default=None, help="Restrict the response to messages created after the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_conversations_id_messages(ctx, conversation_id, fields, exclude_fields, is_read, before_timestamp, since_timestamp, extra_params):
+ """List messages"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/conversations/{conversation_id}/messages"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "is_read": is_read,
+ "before_timestamp": before_timestamp,
+ "since_timestamp": since_timestamp,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@conversations_group.command("get-conversations-id-messages-id")
+@click.argument("CONVERSATION_ID")
+@click.argument("MESSAGE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_conversations_id_messages_id(ctx, conversation_id, message_id, fields, exclude_fields, extra_params):
+ """Get message"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/conversations/{conversation_id}/messages/{message_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/customer_journeys.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/customer_journeys.py
new file mode 100644
index 000000000..4366cbc86
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/customer_journeys.py
@@ -0,0 +1,51 @@
+"""Commands for the Mailchimp /customer-journeys API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("customer-journeys")
+@click.pass_context
+def customer_journeys_group(ctx):
+ """customer-journeys resource commands."""
+
+@customer_journeys_group.command("trigger")
+@click.argument("JOURNEY_ID")
+@click.argument("STEP_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_trigger(ctx, journey_id, step_id, data, extra_params):
+ """Customer Journeys API trigger for a contact"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/customer-journeys/journeys/{journey_id}/steps/{step_id}/actions/trigger"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/ecommerce.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/ecommerce.py
new file mode 100644
index 000000000..862efe287
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/ecommerce.py
@@ -0,0 +1,1518 @@
+"""Commands for the Mailchimp /ecommerce API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("ecommerce")
+@click.pass_context
+def ecommerce_group(ctx):
+ """ecommerce resource commands."""
+
+@ecommerce_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--campaign-id", "campaign_id", default=None, help="Restrict results to orders with a specific `campaign_id` value.")
+@click.option("--outreach-id", "outreach_id", default=None, help="Restrict results to orders with a specific `outreach_id` value.")
+@click.option("--customer-id", "customer_id", default=None, help="Restrict results to orders made by a specific customer.")
+@click.option("--has-outreach", "has_outreach", default=None, type=bool, help="Restrict results to orders that have an outreach attached. For example, an email campaign or Facebook ad.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, campaign_id, outreach_id, customer_id, has_outreach, extra_params):
+ """List account orders"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/orders"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "campaign_id": campaign_id,
+ "outreach_id": outreach_id,
+ "customer_id": customer_id,
+ "has_outreach": has_outreach,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List stores"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add store"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete")
+@click.argument("STORE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, store_id, extra_params):
+ """Delete store"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, store_id, fields, exclude_fields, extra_params):
+ """Get store info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update")
+@click.argument("STORE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, store_id, data, extra_params):
+ """Update store"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-carts")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_carts(ctx, store_id, fields, exclude_fields, count, offset, extra_params):
+ """List carts"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-carts")
+@click.argument("STORE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_carts(ctx, store_id, data, extra_params):
+ """Add cart"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-carts-id")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_carts_id(ctx, store_id, cart_id, extra_params):
+ """Delete cart"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-carts-id")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_carts_id(ctx, store_id, cart_id, fields, exclude_fields, extra_params):
+ """Get cart info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-carts-id")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_carts_id(ctx, store_id, cart_id, data, extra_params):
+ """Update cart"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-carts-id-lines")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_carts_id_lines(ctx, store_id, cart_id, fields, exclude_fields, count, offset, extra_params):
+ """List cart line items"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}/lines"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-carts-id-lines")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_carts_id_lines(ctx, store_id, cart_id, data, extra_params):
+ """Add cart line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}/lines"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-carts-lines-id")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.argument("LINE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_carts_lines_id(ctx, store_id, cart_id, line_id, extra_params):
+ """Delete cart line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}/lines/{line_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-carts-id-lines-id")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.argument("LINE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_carts_id_lines_id(ctx, store_id, cart_id, line_id, fields, exclude_fields, extra_params):
+ """Get cart line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}/lines/{line_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-carts-id-lines-id")
+@click.argument("STORE_ID")
+@click.argument("CART_ID")
+@click.argument("LINE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_carts_id_lines_id(ctx, store_id, cart_id, line_id, data, extra_params):
+ """Update cart line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/carts/{cart_id}/lines/{line_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-customers")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--email-address", "email_address", default=None, help="Restrict the response to customers with the email address.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_customers(ctx, store_id, fields, exclude_fields, count, offset, email_address, extra_params):
+ """List customers"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/customers"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "email_address": email_address,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-customers")
+@click.argument("STORE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_customers(ctx, store_id, data, extra_params):
+ """Add customer"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/customers"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-customers-id")
+@click.argument("STORE_ID")
+@click.argument("CUSTOMER_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_customers_id(ctx, store_id, customer_id, extra_params):
+ """Delete customer"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/customers/{customer_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-customers-id")
+@click.argument("STORE_ID")
+@click.argument("CUSTOMER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_customers_id(ctx, store_id, customer_id, fields, exclude_fields, extra_params):
+ """Get customer info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/customers/{customer_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-customers-id")
+@click.argument("STORE_ID")
+@click.argument("CUSTOMER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_customers_id(ctx, store_id, customer_id, data, extra_params):
+ """Update customer"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/customers/{customer_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-3")
+@click.argument("STORE_ID")
+@click.argument("CUSTOMER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_3(ctx, store_id, customer_id, data, extra_params):
+ """Add or update customer"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/customers/{customer_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-orders")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--customer-id", "customer_id", default=None, help="Restrict results to orders made by a specific customer.")
+@click.option("--has-outreach", "has_outreach", default=None, type=bool, help="Restrict results to orders that have an outreach attached. For example, an email campaign or Facebook ad.")
+@click.option("--campaign-id", "campaign_id", default=None, help="Restrict results to orders with a specific `campaign_id` value.")
+@click.option("--outreach-id", "outreach_id", default=None, help="Restrict results to orders with a specific `outreach_id` value.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_orders(ctx, store_id, fields, exclude_fields, count, offset, customer_id, has_outreach, campaign_id, outreach_id, extra_params):
+ """List orders"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "customer_id": customer_id,
+ "has_outreach": has_outreach,
+ "campaign_id": campaign_id,
+ "outreach_id": outreach_id,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-orders")
+@click.argument("STORE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_orders(ctx, store_id, data, extra_params):
+ """Add order"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-orders-id")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_orders_id(ctx, store_id, order_id, extra_params):
+ """Delete order"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-orders-id")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_orders_id(ctx, store_id, order_id, fields, exclude_fields, extra_params):
+ """Get order info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-orders-id")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_orders_id(ctx, store_id, order_id, data, extra_params):
+ """Update order"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-4")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_4(ctx, store_id, order_id, data, extra_params):
+ """Add or update order"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-orders-id-lines")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_orders_id_lines(ctx, store_id, order_id, fields, exclude_fields, count, offset, extra_params):
+ """List order line items"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}/lines"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-orders-id-lines")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_orders_id_lines(ctx, store_id, order_id, data, extra_params):
+ """Add order line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}/lines"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-orders-id-lines-id")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.argument("LINE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_orders_id_lines_id(ctx, store_id, order_id, line_id, extra_params):
+ """Delete order line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}/lines/{line_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-orders-id-lines-id")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.argument("LINE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_orders_id_lines_id(ctx, store_id, order_id, line_id, fields, exclude_fields, extra_params):
+ """Get order line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}/lines/{line_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-orders-id-lines-id")
+@click.argument("STORE_ID")
+@click.argument("ORDER_ID")
+@click.argument("LINE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_orders_id_lines_id(ctx, store_id, order_id, line_id, data, extra_params):
+ """Update order line item"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/orders/{order_id}/lines/{line_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-products")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_products(ctx, store_id, fields, exclude_fields, count, offset, extra_params):
+ """List product"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-products")
+@click.argument("STORE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_products(ctx, store_id, data, extra_params):
+ """Add product"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-products-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_products_id(ctx, store_id, product_id, extra_params):
+ """Delete product"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-products-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_products_id(ctx, store_id, product_id, fields, exclude_fields, extra_params):
+ """Get product info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-products-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_products_id(ctx, store_id, product_id, data, extra_params):
+ """Update product"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-5")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_5(ctx, store_id, product_id, data, extra_params):
+ """Create or update product"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-products-id-images")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_products_id_images(ctx, store_id, product_id, fields, exclude_fields, count, offset, extra_params):
+ """List product images"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/images"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-products-id-images")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_products_id_images(ctx, store_id, product_id, data, extra_params):
+ """Add product image"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/images"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-products-id-images-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("IMAGE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_products_id_images_id(ctx, store_id, product_id, image_id, extra_params):
+ """Delete product image"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/images/{image_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-products-id-images-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("IMAGE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_products_id_images_id(ctx, store_id, product_id, image_id, fields, exclude_fields, extra_params):
+ """Get product image info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/images/{image_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-products-id-images-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("IMAGE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_products_id_images_id(ctx, store_id, product_id, image_id, data, extra_params):
+ """Update product image"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/images/{image_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-products-id-variants")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_products_id_variants(ctx, store_id, product_id, fields, exclude_fields, count, offset, extra_params):
+ """List product variants"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/variants"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-products-id-variants")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_products_id_variants(ctx, store_id, product_id, data, extra_params):
+ """Add product variant"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/variants"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-products-id-variants-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("VARIANT_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_products_id_variants_id(ctx, store_id, product_id, variant_id, extra_params):
+ """Delete product variant"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-products-id-variants-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("VARIANT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_products_id_variants_id(ctx, store_id, product_id, variant_id, fields, exclude_fields, extra_params):
+ """Get product variant info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-products-id-variants-id")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("VARIANT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_products_id_variants_id(ctx, store_id, product_id, variant_id, data, extra_params):
+ """Update product variant"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-6")
+@click.argument("STORE_ID")
+@click.argument("PRODUCT_ID")
+@click.argument("VARIANT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_6(ctx, store_id, product_id, variant_id, data, extra_params):
+ """Add or update product variant"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-promorules")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_promorules(ctx, store_id, fields, exclude_fields, count, offset, extra_params):
+ """List promo rules"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-promorules")
+@click.argument("STORE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_promorules(ctx, store_id, data, extra_params):
+ """Add promo rule"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-promorules-id")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_promorules_id(ctx, store_id, promo_rule_id, extra_params):
+ """Delete promo rule"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-promorules-id")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_promorules_id(ctx, store_id, promo_rule_id, fields, exclude_fields, extra_params):
+ """Get promo rule"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-promorules-id")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_promorules_id(ctx, store_id, promo_rule_id, data, extra_params):
+ """Update promo rule"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("list-ecommerce-stores-id-promocodes")
+@click.argument("PROMO_RULE_ID")
+@click.argument("STORE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_ecommerce_stores_id_promocodes(ctx, promo_rule_id, store_id, fields, exclude_fields, count, offset, extra_params):
+ """List promo codes"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("create-ecommerce-stores-id-promocodes")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_ecommerce_stores_id_promocodes(ctx, store_id, promo_rule_id, data, extra_params):
+ """Add promo code"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("delete-ecommerce-stores-id-promocodes-id")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.argument("PROMO_CODE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_ecommerce_stores_id_promocodes_id(ctx, store_id, promo_rule_id, promo_code_id, extra_params):
+ """Delete promo code"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes/{promo_code_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@ecommerce_group.command("get-ecommerce-stores-id-promocodes-id")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.argument("PROMO_CODE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_ecommerce_stores_id_promocodes_id(ctx, store_id, promo_rule_id, promo_code_id, fields, exclude_fields, extra_params):
+ """Get promo code"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes/{promo_code_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@ecommerce_group.command("update-ecommerce-stores-id-promocodes-id")
+@click.argument("STORE_ID")
+@click.argument("PROMO_RULE_ID")
+@click.argument("PROMO_CODE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_ecommerce_stores_id_promocodes_id(ctx, store_id, promo_rule_id, promo_code_id, data, extra_params):
+ """Update promo code"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes/{promo_code_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/facebook_ads.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/facebook_ads.py
new file mode 100644
index 000000000..012edeb79
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/facebook_ads.py
@@ -0,0 +1,85 @@
+"""Commands for the Mailchimp /facebook-ads API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("facebook-ads")
+@click.pass_context
+def facebook_ads_group(ctx):
+ """facebook-ads resource commands."""
+
+@facebook_ads_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, sort_field, sort_dir, extra_params):
+ """List facebook ads"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/facebook-ads"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@facebook_ads_group.command("get")
+@click.argument("OUTREACH_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, outreach_id, fields, exclude_fields, extra_params):
+ """Get facebook ad info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/facebook-ads/{outreach_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/file_manager.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/file_manager.py
new file mode 100644
index 000000000..69935e077
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/file_manager.py
@@ -0,0 +1,319 @@
+"""Commands for the Mailchimp /file-manager API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("file-manager")
+@click.pass_context
+def file_manager_group(ctx):
+ """file-manager resource commands."""
+
+@file_manager_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="The file type for the File Manager file.")
+@click.option("--created-by", "created_by", default=None, help="The Mailchimp account user who created the File Manager file.")
+@click.option("--before-created-at", "before_created_at", default=None, help="Restrict the response to files created before the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-created-at", "since_created_at", default=None, help="Restrict the response to files created after the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, type_, created_by, before_created_at, since_created_at, sort_field, sort_dir, extra_params):
+ """List stored files"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/files"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "created_by": created_by,
+ "before_created_at": before_created_at,
+ "since_created_at": since_created_at,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add file"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/files"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("delete")
+@click.argument("FILE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, file_id, extra_params):
+ """Delete file"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/files/{file_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@file_manager_group.command("get")
+@click.argument("FILE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, file_id, fields, exclude_fields, extra_params):
+ """Get file"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/files/{file_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("update")
+@click.argument("FILE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, file_id, data, extra_params):
+ """Update file"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/files/{file_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("list-file-manager-folders")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--created-by", "created_by", default=None, help="The Mailchimp account user who created the File Manager file.")
+@click.option("--before-created-at", "before_created_at", default=None, help="Restrict the response to files created before the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-created-at", "since_created_at", default=None, help="Restrict the response to files created after the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_file_manager_folders(ctx, fields, exclude_fields, count, offset, created_by, before_created_at, since_created_at, extra_params):
+ """List folders"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/folders"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "created_by": created_by,
+ "before_created_at": before_created_at,
+ "since_created_at": since_created_at,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("create-file-manager-folders")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_file_manager_folders(ctx, data, extra_params):
+ """Add folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/folders"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("delete-file-manager-folders-id")
+@click.argument("FOLDER_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_file_manager_folders_id(ctx, folder_id, extra_params):
+ """Delete folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/folders/{folder_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@file_manager_group.command("get-file-manager-folders-id")
+@click.argument("FOLDER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_file_manager_folders_id(ctx, folder_id, fields, exclude_fields, extra_params):
+ """Get folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/folders/{folder_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("update-file-manager-folders-id")
+@click.argument("FOLDER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_file_manager_folders_id(ctx, folder_id, data, extra_params):
+ """Update folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/folders/{folder_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@file_manager_group.command("list-file-manager-folders-files")
+@click.argument("FOLDER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="The file type for the File Manager file.")
+@click.option("--created-by", "created_by", default=None, help="The Mailchimp account user who created the File Manager file.")
+@click.option("--before-created-at", "before_created_at", default=None, help="Restrict the response to files created before the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-created-at", "since_created_at", default=None, help="Restrict the response to files created after the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_file_manager_folders_files(ctx, folder_id, fields, exclude_fields, count, offset, type_, created_by, before_created_at, since_created_at, sort_field, sort_dir, extra_params):
+ """List stored files"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/file-manager/folders/{folder_id}/files"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "created_by": created_by,
+ "before_created_at": before_created_at,
+ "since_created_at": since_created_at,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/landing_pages.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/landing_pages.py
new file mode 100644
index 000000000..616e64079
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/landing_pages.py
@@ -0,0 +1,214 @@
+"""Commands for the Mailchimp /landing-pages API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("landing-pages")
+@click.pass_context
+def landing_pages_group(ctx):
+ """landing-pages resource commands."""
+
+@landing_pages_group.command("list")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, sort_dir, sort_field, fields, exclude_fields, count, extra_params):
+ """List landing pages"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages"
+ params = {k: v for k, v in {
+ "sort_dir": sort_dir,
+ "sort_field": sort_field,
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@landing_pages_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--use-default-list", "use_default_list", default=None, type=bool, help="Will create the Landing Page using the account's Default List instead of requiring a list_id.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, use_default_list, extra_params):
+ """Add landing page"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages"
+ params = {k: v for k, v in {
+ "use_default_list": use_default_list,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@landing_pages_group.command("delete")
+@click.argument("PAGE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, page_id, extra_params):
+ """Delete landing page"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages/{page_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@landing_pages_group.command("get")
+@click.argument("PAGE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, page_id, fields, exclude_fields, extra_params):
+ """Get landing page info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages/{page_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@landing_pages_group.command("update")
+@click.argument("PAGE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, page_id, data, extra_params):
+ """Update landing page"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages/{page_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@landing_pages_group.command("publish")
+@click.argument("PAGE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_publish(ctx, page_id, extra_params):
+ """Publish landing page"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages/{page_id}/actions/publish"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@landing_pages_group.command("unpublish")
+@click.argument("PAGE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_unpublish(ctx, page_id, extra_params):
+ """Unpublish landing page"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages/{page_id}/actions/unpublish"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@landing_pages_group.command("list-landing-page-id-content")
+@click.argument("PAGE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_landing_page_id_content(ctx, page_id, fields, exclude_fields, extra_params):
+ """Get landing page content"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/landing-pages/{page_id}/content"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/lists.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/lists.py
new file mode 100644
index 000000000..9638617cc
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/lists.py
@@ -0,0 +1,1758 @@
+"""Commands for the Mailchimp /lists API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("lists")
+@click.pass_context
+def lists_group(ctx):
+ """lists resource commands."""
+
+@lists_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--before-date-created", "before_date_created", default=None, help="Restrict response to lists created before the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-date-created", "since_date_created", default=None, help="Restrict results to lists created after the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-campaign-last-sent", "before_campaign_last_sent", default=None, help="Restrict results to lists created before the last campaign send date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-campaign-last-sent", "since_campaign_last_sent", default=None, help="Restrict results to lists created after the last campaign send date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--email", "email", default=None, help="Restrict results to lists that include a specific subscriber's email address.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--has-ecommerce-store", "has_ecommerce_store", default=None, type=bool, help="Restrict results to lists that contain an active, connected, undeleted ecommerce store.")
+@click.option("--include-total-contacts", "include_total_contacts", default=None, type=bool, help="Return the total_contacts field in the stats response, which contains an approximate count of all contacts in any state.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, before_date_created, since_date_created, before_campaign_last_sent, since_campaign_last_sent, email, sort_field, sort_dir, has_ecommerce_store, include_total_contacts, extra_params):
+ """Get lists info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "before_date_created": before_date_created,
+ "since_date_created": since_date_created,
+ "before_campaign_last_sent": before_campaign_last_sent,
+ "since_campaign_last_sent": since_campaign_last_sent,
+ "email": email,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ "has_ecommerce_store": has_ecommerce_store,
+ "include_total_contacts": include_total_contacts,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add list"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete")
+@click.argument("LIST_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, list_id, extra_params):
+ """Delete list"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--include-total-contacts", "include_total_contacts", default=None, type=bool, help="Return the total_contacts field in the stats response, which contains an approximate count of all contacts in any state.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, list_id, fields, exclude_fields, include_total_contacts, extra_params):
+ """Get list info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "include_total_contacts": include_total_contacts,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, list_id, data, extra_params):
+ """Update lists"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--skip-merge-validation", "skip_merge_validation", default=None, type=bool, help="If skip_merge_validation is true, member data will be accepted without merge field values, even if the merge field is usually required. This defaults to false.")
+@click.option("--skip-duplicate-check", "skip_duplicate_check", default=None, type=bool, help="If skip_duplicate_check is true, we will ignore duplicates sent in the request when using the batch sub/unsub on the lists endpoint. The status of the first appearance in the request will be saved. This defaults to false.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id(ctx, list_id, data, skip_merge_validation, skip_duplicate_check, extra_params):
+ """Batch subscribe or unsubscribe"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}"
+ params = {k: v for k, v in {
+ "skip_merge_validation": skip_merge_validation,
+ "skip_duplicate_check": skip_duplicate_check,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-abuse-reports")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_abuse_reports(ctx, list_id, fields, exclude_fields, count, offset, extra_params):
+ """List abuse reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/abuse-reports"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("get-lists-id-abuse-reports-id")
+@click.argument("LIST_ID")
+@click.argument("REPORT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_abuse_reports_id(ctx, list_id, report_id, fields, exclude_fields, count, offset, extra_params):
+ """Get abuse report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/abuse-reports/{report_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-activity")
+@click.argument("LIST_ID")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_activity(ctx, list_id, count, offset, fields, exclude_fields, extra_params):
+ """List recent activity"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/activity"
+ params = {k: v for k, v in {
+ "count": count,
+ "offset": offset,
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-clients")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_clients(ctx, list_id, fields, exclude_fields, extra_params):
+ """List top email clients"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/clients"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-growth-history")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_growth_history(ctx, list_id, fields, exclude_fields, count, offset, sort_field, sort_dir, extra_params):
+ """List growth history data"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/growth-history"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("get-lists-id-growth-history-id")
+@click.argument("LIST_ID")
+@click.argument("MONTH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_growth_history_id(ctx, list_id, month, fields, exclude_fields, extra_params):
+ """Get growth history by month"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/growth-history/{month}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-interest-categories")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="Restrict results a type of interest group")
+@click.option("--sort-field", "sort_field", default=None, help="Returns interest categories sorted by the specified field. Defaults to display_order.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_interest_categories(ctx, list_id, fields, exclude_fields, count, offset, type_, sort_field, sort_dir, extra_params):
+ """List interest categories"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-interest-categories")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_interest_categories(ctx, list_id, data, extra_params):
+ """Add interest category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-interest-categories-id")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_interest_categories_id(ctx, list_id, interest_category_id, extra_params):
+ """Delete interest category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-interest-categories-id")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_interest_categories_id(ctx, list_id, interest_category_id, fields, exclude_fields, extra_params):
+ """Get interest category info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-interest-categories-id")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_interest_categories_id(ctx, list_id, interest_category_id, data, extra_params):
+ """Update interest category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-interest-categories-id-interests")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_interest_categories_id_interests(ctx, list_id, interest_category_id, fields, exclude_fields, count, offset, extra_params):
+ """List interests in category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}/interests"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-interest-categories-id-interests")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_interest_categories_id_interests(ctx, list_id, interest_category_id, data, extra_params):
+ """Add interest in category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}/interests"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-interest-categories-id-interests-id")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.argument("INTEREST_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_interest_categories_id_interests_id(ctx, list_id, interest_category_id, interest_id, extra_params):
+ """Delete interest in category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}/interests/{interest_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-interest-categories-id-interests-id")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.argument("INTEREST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_interest_categories_id_interests_id(ctx, list_id, interest_category_id, interest_id, fields, exclude_fields, extra_params):
+ """Get interest in category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}/interests/{interest_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-interest-categories-id-interests-id")
+@click.argument("LIST_ID")
+@click.argument("INTEREST_CATEGORY_ID")
+@click.argument("INTEREST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_interest_categories_id_interests_id(ctx, list_id, interest_category_id, interest_id, data, extra_params):
+ """Update interest in category"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/interest-categories/{interest_category_id}/interests/{interest_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-locations")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_locations(ctx, list_id, fields, exclude_fields, extra_params):
+ """List locations"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/locations"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-members")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--email-type", "email_type", default=None, help="The email type.")
+@click.option("--status", "status", default=None, help="The subscriber's status.")
+@click.option("--since-timestamp-opt", "since_timestamp_opt", default=None, help="Restrict results to subscribers who opted-in after the set timeframe. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-timestamp-opt", "before_timestamp_opt", default=None, help="Restrict results to subscribers who opted-in before the set timeframe. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-last-changed", "since_last_changed", default=None, help="Restrict results to subscribers whose information changed after the set timeframe. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-last-changed", "before_last_changed", default=None, help="Restrict results to subscribers whose information changed before the set timeframe. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--unique-email-id", "unique_email_id", default=None, help="A unique identifier for the email address across all Mailchimp lists.")
+@click.option("--vip-only", "vip_only", default=None, type=bool, help="A filter to return only the list's VIP members. Passing `true` will restrict results to VIP list members, passing `false` will return all list members.")
+@click.option("--interest-category-id", "interest_category_id", default=None, help="The unique id for the interest category.")
+@click.option("--interest-ids", "interest_ids", default=None, help="Used to filter list members by interests. Must be accompanied by interest_category_id and interest_match. The value must be a comma separated list of interest ids present for any supplied interest categories.")
+@click.option("--interest-match", "interest_match", default=None, help="Used to filter list members by interests. Must be accompanied by interest_category_id and interest_ids. \"any\" will match a member with any of the interest supplied, \"all\" will only match members with every interest supplied, and \"none\" will match members without any of the interest supplied.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--since-last-campaign", "since_last_campaign", default=None, type=bool, help="Filter subscribers by those subscribed/unsubscribed/pending/cleaned since last email campaign send. Member status is required to use this filter.")
+@click.option("--unsubscribed-since", "unsubscribed_since", default=None, help="Filter subscribers by those unsubscribed since a specific date. Using any status other than unsubscribed with this filter will result in an error.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_members(ctx, list_id, fields, exclude_fields, count, offset, email_type, status, since_timestamp_opt, before_timestamp_opt, since_last_changed, before_last_changed, unique_email_id, vip_only, interest_category_id, interest_ids, interest_match, sort_field, sort_dir, since_last_campaign, unsubscribed_since, extra_params):
+ """List members info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "email_type": email_type,
+ "status": status,
+ "since_timestamp_opt": since_timestamp_opt,
+ "before_timestamp_opt": before_timestamp_opt,
+ "since_last_changed": since_last_changed,
+ "before_last_changed": before_last_changed,
+ "unique_email_id": unique_email_id,
+ "vip_only": vip_only,
+ "interest_category_id": interest_category_id,
+ "interest_ids": interest_ids,
+ "interest_match": interest_match,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ "since_last_campaign": since_last_campaign,
+ "unsubscribed_since": unsubscribed_since,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-members")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--skip-merge-validation", "skip_merge_validation", default=None, type=bool, help="If skip_merge_validation is true, member data will be accepted without merge field values, even if the merge field is usually required. This defaults to false.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_members(ctx, list_id, data, skip_merge_validation, extra_params):
+ """Add member to list"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members"
+ params = {k: v for k, v in {
+ "skip_merge_validation": skip_merge_validation,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+lists_group.add_command(_cmd_create_lists_id_members, "create-members")
+
+@lists_group.command("delete-lists-id-members-id")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_members_id(ctx, list_id, subscriber_hash, extra_params):
+ """Archive list member"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-members-id")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_members_id(ctx, list_id, subscriber_hash, fields, exclude_fields, extra_params):
+ """Get member info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-members-id")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--skip-merge-validation", "skip_merge_validation", default=None, type=bool, help="If skip_merge_validation is true, member data will be accepted without merge field values, even if the merge field is usually required. This defaults to false.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_members_id(ctx, list_id, subscriber_hash, data, skip_merge_validation, extra_params):
+ """Update list member"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "skip_merge_validation": skip_merge_validation,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-3")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--skip-merge-validation", "skip_merge_validation", default=None, type=bool, help="If skip_merge_validation is true, member data will be accepted without merge field values, even if the merge field is usually required. This defaults to false.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_3(ctx, list_id, subscriber_hash, data, skip_merge_validation, extra_params):
+ """Add or update list member"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "skip_merge_validation": skip_merge_validation,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-permanent")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_permanent(ctx, list_id, subscriber_hash, extra_params):
+ """Delete list member"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/actions/delete-permanent"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-members-id-activity")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--action", "action", default=None, help="A comma seperated list of actions to return.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_members_id_activity(ctx, list_id, subscriber_hash, fields, exclude_fields, action, extra_params):
+ """View recent activity 50"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/activity"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "action": action,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-members-id-activity-feed")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--activity-filters", "activity_filters", default=None, help="A comma-separated list of activity filters that correspond to a set of activity types, e.g \"?activity_filters=open,bounce,click\".")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_members_id_activity_feed(ctx, list_id, subscriber_hash, fields, exclude_fields, count, offset, activity_filters, extra_params):
+ """View recent activity"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/activity-feed"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "activity_filters": activity_filters,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-members-id-events")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_members_id_events(ctx, list_id, subscriber_hash, count, offset, fields, exclude_fields, extra_params):
+ """List member events"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/events"
+ params = {k: v for k, v in {
+ "count": count,
+ "offset": offset,
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-list-member-events")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_list_member_events(ctx, list_id, subscriber_hash, data, extra_params):
+ """Add event"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/events"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-members-id-goals")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_members_id_goals(ctx, list_id, subscriber_hash, fields, exclude_fields, extra_params):
+ """List member goal events"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/goals"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-members-id-notes")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--sort-field", "sort_field", default=None, help="Returns notes sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_members_id_notes(ctx, list_id, subscriber_hash, sort_field, sort_dir, fields, exclude_fields, count, offset, extra_params):
+ """List recent member notes"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/notes"
+ params = {k: v for k, v in {
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-members-id-notes")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_members_id_notes(ctx, list_id, subscriber_hash, data, extra_params):
+ """Add member note"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/notes"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-members-id-notes-id")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.argument("NOTE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_members_id_notes_id(ctx, list_id, subscriber_hash, note_id, extra_params):
+ """Delete note"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/notes/{note_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-members-id-notes-id")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.argument("NOTE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_members_id_notes_id(ctx, list_id, subscriber_hash, note_id, fields, exclude_fields, extra_params):
+ """Get member note"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/notes/{note_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-members-id-notes-id")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.argument("NOTE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_members_id_notes_id(ctx, list_id, subscriber_hash, note_id, data, extra_params):
+ """Update note"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/notes/{note_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-list-member-tags")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_list_member_tags(ctx, list_id, subscriber_hash, fields, exclude_fields, count, offset, extra_params):
+ """List member tags"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/tags"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-list-member-tags")
+@click.argument("LIST_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_list_member_tags(ctx, list_id, subscriber_hash, data, extra_params):
+ """Add or remove member tags"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/members/{subscriber_hash}/tags"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-merge-fields")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="The merge field type.")
+@click.option("--required", "required", default=None, type=bool, help="Whether it's a required merge field.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_merge_fields(ctx, list_id, fields, exclude_fields, count, offset, type_, required, extra_params):
+ """List merge fields"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/merge-fields"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "required": required,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-merge-fields")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_merge_fields(ctx, list_id, data, extra_params):
+ """Add merge field"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/merge-fields"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-merge-fields-id")
+@click.argument("LIST_ID")
+@click.argument("MERGE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_merge_fields_id(ctx, list_id, merge_id, extra_params):
+ """Delete merge field"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/merge-fields/{merge_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-merge-fields-id")
+@click.argument("LIST_ID")
+@click.argument("MERGE_ID")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_merge_fields_id(ctx, list_id, merge_id, exclude_fields, fields, extra_params):
+ """Get merge field"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/merge-fields/{merge_id}"
+ params = {k: v for k, v in {
+ "exclude_fields": exclude_fields,
+ "fields": fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-merge-fields-id")
+@click.argument("LIST_ID")
+@click.argument("MERGE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_merge_fields_id(ctx, list_id, merge_id, data, extra_params):
+ """Update merge field"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/merge-fields/{merge_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-preview-a-segment")
+@click.argument("LIST_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="Limit results based on segment type.")
+@click.option("--since-created-at", "since_created_at", default=None, help="Restrict results to segments created after the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-created-at", "before_created_at", default=None, help="Restrict results to segments created before the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--include-cleaned", "include_cleaned", default=None, type=bool, help="Include cleaned members in response")
+@click.option("--include-transactional", "include_transactional", default=None, type=bool, help="Include transactional members in response")
+@click.option("--include-unsubscribed", "include_unsubscribed", default=None, type=bool, help="Include unsubscribed members in response")
+@click.option("--since-updated-at", "since_updated_at", default=None, help="Restrict results to segments update after the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-updated-at", "before_updated_at", default=None, help="Restrict results to segments update before the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--exclude-type", "exclude_type", default=None, help="Exclude results based on segment type. For example, use `exclude_type=static` to exclude tags from the response.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_preview_a_segment(ctx, list_id, fields, exclude_fields, count, offset, type_, since_created_at, before_created_at, include_cleaned, include_transactional, include_unsubscribed, since_updated_at, before_updated_at, exclude_type, extra_params):
+ """List segments"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "since_created_at": since_created_at,
+ "before_created_at": before_created_at,
+ "include_cleaned": include_cleaned,
+ "include_transactional": include_transactional,
+ "include_unsubscribed": include_unsubscribed,
+ "since_updated_at": since_updated_at,
+ "before_updated_at": before_updated_at,
+ "exclude_type": exclude_type,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+lists_group.add_command(_cmd_list_preview_a_segment, "list-lists-id-segments")
+
+@lists_group.command("create-lists-id-segments")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_segments(ctx, list_id, data, extra_params):
+ """Add segment"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-segments-id")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_segments_id(ctx, list_id, segment_id, extra_params):
+ """Delete segment"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-segments-id")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--include-cleaned", "include_cleaned", default=None, type=bool, help="Include cleaned members in response")
+@click.option("--include-transactional", "include_transactional", default=None, type=bool, help="Include transactional members in response")
+@click.option("--include-unsubscribed", "include_unsubscribed", default=None, type=bool, help="Include unsubscribed members in response")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_segments_id(ctx, list_id, segment_id, fields, exclude_fields, include_cleaned, include_transactional, include_unsubscribed, extra_params):
+ """Get segment info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "include_cleaned": include_cleaned,
+ "include_transactional": include_transactional,
+ "include_unsubscribed": include_unsubscribed,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-segments-id")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_segments_id(ctx, list_id, segment_id, data, extra_params):
+ """Update segment"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-segments-id")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_segments_id(ctx, list_id, segment_id, data, extra_params):
+ """Batch add or remove members"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-segments-id-members")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--include-cleaned", "include_cleaned", default=None, type=bool, help="Include cleaned members in response")
+@click.option("--include-transactional", "include_transactional", default=None, type=bool, help="Include transactional members in response")
+@click.option("--include-unsubscribed", "include_unsubscribed", default=None, type=bool, help="Include unsubscribed members in response")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_segments_id_members(ctx, list_id, segment_id, fields, exclude_fields, count, offset, include_cleaned, include_transactional, include_unsubscribed, extra_params):
+ """List members in segment"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}/members"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "include_cleaned": include_cleaned,
+ "include_transactional": include_transactional,
+ "include_unsubscribed": include_unsubscribed,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-segments-id-members")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_segments_id_members(ctx, list_id, segment_id, data, extra_params):
+ """Add member to segment"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}/members"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-segments-id-members-id")
+@click.argument("LIST_ID")
+@click.argument("SEGMENT_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_segments_id_members_id(ctx, list_id, segment_id, subscriber_hash, extra_params):
+ """Remove list member from segment"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/segments/{segment_id}/members/{subscriber_hash}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("list-lists-id-signup-forms")
+@click.argument("LIST_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_signup_forms(ctx, list_id, extra_params):
+ """List signup forms"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/signup-forms"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-signup-forms")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_signup_forms(ctx, list_id, data, extra_params):
+ """Customize signup form"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/signup-forms"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-surveys")
+@click.argument("LIST_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_surveys(ctx, list_id, extra_params):
+ """Get information about all surveys for a list"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/surveys"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("get-lists-id-surveys-id")
+@click.argument("LIST_ID")
+@click.argument("SURVEY_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_surveys_id(ctx, list_id, survey_id, extra_params):
+ """Get survey"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/surveys/{survey_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-search-tags-by-name")
+@click.argument("LIST_ID")
+@click.option("--name", "name", default=None, help="The search query used to filter tags. The search query will be compared to each tag as a prefix, so all tags that have a name starting with this field will be returned.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_search_tags_by_name(ctx, list_id, name, extra_params):
+ """Search for tags on a list by name."""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/tag-search"
+ params = {k: v for k, v in {
+ "name": name,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("list-lists-id-webhooks")
+@click.argument("LIST_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_lists_id_webhooks(ctx, list_id, extra_params):
+ """List webhooks"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/webhooks"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("create-lists-id-webhooks")
+@click.argument("LIST_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_lists_id_webhooks(ctx, list_id, data, extra_params):
+ """Add webhook"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/webhooks"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("delete-lists-id-webhooks-id")
+@click.argument("LIST_ID")
+@click.argument("WEBHOOK_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete_lists_id_webhooks_id(ctx, list_id, webhook_id, extra_params):
+ """Delete webhook"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/webhooks/{webhook_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@lists_group.command("get-lists-id-webhooks-id")
+@click.argument("LIST_ID")
+@click.argument("WEBHOOK_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_lists_id_webhooks_id(ctx, list_id, webhook_id, extra_params):
+ """Get webhook info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/webhooks/{webhook_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@lists_group.command("update-lists-id-webhooks-id")
+@click.argument("LIST_ID")
+@click.argument("WEBHOOK_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_lists_id_webhooks_id(ctx, list_id, webhook_id, data, extra_params):
+ """Update webhook"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/webhooks/{webhook_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/ping.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/ping.py
new file mode 100644
index 000000000..a0f97c1c7
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/ping.py
@@ -0,0 +1,49 @@
+"""Commands for the Mailchimp /ping API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("ping", invoke_without_command=True)
+@click.pass_context
+def ping_group(ctx):
+ """ping resource commands."""
+ if ctx.invoked_subcommand is None:
+ ctx.invoke(_cmd_list_)
+
+@ping_group.command("list")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, extra_params):
+ """Ping"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/ping"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/reporting.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/reporting.py
new file mode 100644
index 000000000..4f2642a0e
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/reporting.py
@@ -0,0 +1,353 @@
+"""Commands for the Mailchimp /reporting API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("reporting")
+@click.pass_context
+def reporting_group(ctx):
+ """reporting resource commands."""
+
+@reporting_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, sort_field, sort_dir, extra_params):
+ """List facebook ads reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/facebook-ads"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("get")
+@click.argument("OUTREACH_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, outreach_id, fields, exclude_fields, extra_params):
+ """Get facebook ad report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/facebook-ads/{outreach_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("list-reporting-facebook-ads-id-ecommerce-product-activity")
+@click.argument("OUTREACH_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reporting_facebook_ads_id_ecommerce_product_activity(ctx, outreach_id, fields, exclude_fields, count, offset, sort_field, extra_params):
+ """List facebook ecommerce report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/facebook-ads/{outreach_id}/ecommerce-product-activity"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "sort_field": sort_field,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("list-reporting-landing-pages")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reporting_landing_pages(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List landing pages reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/landing-pages"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("get-reporting-landing-pages-id")
+@click.argument("OUTREACH_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reporting_landing_pages_id(ctx, outreach_id, fields, exclude_fields, extra_params):
+ """Get landing page report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/landing-pages/{outreach_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("list-reporting-surveys")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reporting_surveys(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List survey reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("get-reporting-surveys-id")
+@click.argument("SURVEY_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reporting_surveys_id(ctx, survey_id, fields, exclude_fields, extra_params):
+ """Get survey report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys/{survey_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("list-reporting-surveys-id-questions")
+@click.argument("SURVEY_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reporting_surveys_id_questions(ctx, survey_id, fields, exclude_fields, extra_params):
+ """List survey question reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys/{survey_id}/questions"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("get-reporting-surveys-id-questions-id")
+@click.argument("SURVEY_ID")
+@click.argument("QUESTION_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reporting_surveys_id_questions_id(ctx, survey_id, question_id, fields, exclude_fields, extra_params):
+ """Get survey question report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys/{survey_id}/questions/{question_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("list-reporting-surveys-id-questions-id-answers")
+@click.argument("SURVEY_ID")
+@click.argument("QUESTION_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--respondent-familiarity-is", "respondent_familiarity_is", default=None, help="Filter survey responses by familiarity of the respondents.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reporting_surveys_id_questions_id_answers(ctx, survey_id, question_id, fields, exclude_fields, respondent_familiarity_is, extra_params):
+ """List answers for question"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys/{survey_id}/questions/{question_id}/answers"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "respondent_familiarity_is": respondent_familiarity_is,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("list-reporting-surveys-id-responses")
+@click.argument("SURVEY_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--answered-question", "answered_question", default=None, type=int, help="The ID of the question that was answered.")
+@click.option("--chose-answer", "chose_answer", default=None, help="The ID of the option chosen to filter responses on.")
+@click.option("--respondent-familiarity-is", "respondent_familiarity_is", default=None, help="Filter survey responses by familiarity of the respondents.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reporting_surveys_id_responses(ctx, survey_id, fields, exclude_fields, answered_question, chose_answer, respondent_familiarity_is, extra_params):
+ """List survey responses"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys/{survey_id}/responses"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "answered_question": answered_question,
+ "chose_answer": chose_answer,
+ "respondent_familiarity_is": respondent_familiarity_is,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reporting_group.command("get-reporting-surveys-id-responses-id")
+@click.argument("SURVEY_ID")
+@click.argument("RESPONSE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reporting_surveys_id_responses_id(ctx, survey_id, response_id, extra_params):
+ """Get survey response"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reporting/surveys/{survey_id}/responses/{response_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/reports.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/reports.py
new file mode 100644
index 000000000..466341e2c
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/reports.py
@@ -0,0 +1,656 @@
+"""Commands for the Mailchimp /reports API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("reports")
+@click.pass_context
+def reports_group(ctx):
+ """reports resource commands."""
+
+@reports_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--type", "type_", default=None, help="The campaign type.")
+@click.option("--before-send-time", "before_send_time", default=None, help="Restrict the response to campaigns sent before the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--since-send-time", "since_send_time", default=None, help="Restrict the response to campaigns sent after the set time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, type_, before_send_time, since_send_time, extra_params):
+ """List campaign reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "type": type_,
+ "before_send_time": before_send_time,
+ "since_send_time": since_send_time,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("get")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """Get campaign report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-abuse-reports-id")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_abuse_reports_id(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """List abuse reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/abuse-reports"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("get-reports-id-abuse-reports-id-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("REPORT_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_abuse_reports_id_id(ctx, campaign_id, report_id, fields, exclude_fields, extra_params):
+ """Get abuse report"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/abuse-reports/{report_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-advice")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_advice(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """List campaign feedback"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/advice"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-click-details")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns click reports sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_click_details(ctx, campaign_id, fields, exclude_fields, count, offset, sort_field, sort_dir, extra_params):
+ """List campaign details"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/click-details"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+reports_group.add_command(_cmd_list_reports_id_click_details, "list-click-details")
+
+@reports_group.command("get-reports-id-click-details-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("LINK_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_click_details_id(ctx, campaign_id, link_id, fields, exclude_fields, extra_params):
+ """Get campaign link details"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/click-details/{link_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-click-details-id-members")
+@click.argument("CAMPAIGN_ID")
+@click.argument("LINK_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_click_details_id_members(ctx, campaign_id, link_id, fields, exclude_fields, count, offset, extra_params):
+ """List clicked link subscribers"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/click-details/{link_id}/members"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("get-reports-id-click-details-id-members-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("LINK_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_click_details_id_members_id(ctx, campaign_id, link_id, subscriber_hash, fields, exclude_fields, extra_params):
+ """Get clicked link subscriber"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/click-details/{link_id}/members/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-domain-performance")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_domain_performance(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """List domain performance stats"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/domain-performance"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+reports_group.add_command(_cmd_list_reports_id_domain_performance, "list-domain-performance")
+
+@reports_group.command("list-reports-id-ecommerce-product-activity")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns files sorted by the specified field.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_ecommerce_product_activity(ctx, campaign_id, fields, exclude_fields, count, offset, sort_field, extra_params):
+ """List campaign product activity"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/ecommerce-product-activity"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "sort_field": sort_field,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-eepurl")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_eepurl(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """List EepURL activity"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/eepurl"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-email-activity")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--since", "since", default=None, help="Restrict results to email activity events that occur after a specific time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_email_activity(ctx, campaign_id, fields, exclude_fields, count, offset, since, extra_params):
+ """List email activity"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/email-activity"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "since": since,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+reports_group.add_command(_cmd_list_reports_id_email_activity, "list-email-activity")
+
+@reports_group.command("get-reports-id-email-activity-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--since", "since", default=None, help="Restrict results to email activity events that occur after a specific time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_email_activity_id(ctx, campaign_id, subscriber_hash, fields, exclude_fields, since, extra_params):
+ """Get subscriber email activity"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/email-activity/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "since": since,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-locations")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_locations(ctx, campaign_id, fields, exclude_fields, count, offset, extra_params):
+ """List top open activities"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/locations"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+reports_group.add_command(_cmd_list_reports_id_locations, "list-locations")
+
+@reports_group.command("list-reports-id-open-details")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--since", "since", default=None, help="Restrict results to campaign open events that occur after a specific time. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns open reports sorted by the specified field.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_open_details(ctx, campaign_id, fields, exclude_fields, count, offset, since, sort_field, sort_dir, extra_params):
+ """List campaign open details"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/open-details"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "since": since,
+ "sort_field": sort_field,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+reports_group.add_command(_cmd_list_reports_id_open_details, "list-open-details")
+
+@reports_group.command("get-reports-id-open-details-id-members-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_open_details_id_members_id(ctx, campaign_id, subscriber_hash, fields, exclude_fields, extra_params):
+ """Get opened campaign subscriber"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/open-details/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-sent-to")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_sent_to(ctx, campaign_id, fields, exclude_fields, count, offset, extra_params):
+ """List campaign recipients"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/sent-to"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("get-reports-id-sent-to-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_sent_to_id(ctx, campaign_id, subscriber_hash, fields, exclude_fields, extra_params):
+ """Get campaign recipient info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/sent-to/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-sub-reports-id")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_sub_reports_id(ctx, campaign_id, fields, exclude_fields, extra_params):
+ """List child campaign reports"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/sub-reports"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@reports_group.command("list-reports-id-unsubscribed")
+@click.argument("CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_reports_id_unsubscribed(ctx, campaign_id, fields, exclude_fields, count, offset, extra_params):
+ """List unsubscribed members"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/unsubscribed"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+reports_group.add_command(_cmd_list_reports_id_unsubscribed, "list-unsubscribed")
+
+@reports_group.command("get-reports-id-unsubscribed-id")
+@click.argument("CAMPAIGN_ID")
+@click.argument("SUBSCRIBER_HASH")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get_reports_id_unsubscribed_id(ctx, campaign_id, subscriber_hash, fields, exclude_fields, extra_params):
+ """Get unsubscribed member"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/reports/{campaign_id}/unsubscribed/{subscriber_hash}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/root.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/root.py
new file mode 100644
index 000000000..e5c012410
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/root.py
@@ -0,0 +1,52 @@
+"""Commands for the Mailchimp /root API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("root")
+@click.pass_context
+def root_group(ctx):
+ """root resource commands."""
+
+@root_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, extra_params):
+ """List api root resources"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/search_campaigns.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/search_campaigns.py
new file mode 100644
index 000000000..a28ad6eeb
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/search_campaigns.py
@@ -0,0 +1,54 @@
+"""Commands for the Mailchimp /search-campaigns API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("search-campaigns")
+@click.pass_context
+def search_campaigns_group(ctx):
+ """search-campaigns resource commands."""
+
+@search_campaigns_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--query", "query", default=None, help="The search query used to filter results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, query, extra_params):
+ """Search campaigns"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/search-campaigns"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "query": query,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/search_members.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/search_members.py
new file mode 100644
index 000000000..6ac8ec940
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/search_members.py
@@ -0,0 +1,56 @@
+"""Commands for the Mailchimp /search-members API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("search-members")
+@click.pass_context
+def search_members_group(ctx):
+ """search-members resource commands."""
+
+@search_members_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--query", "query", default=None, help="The search query used to filter results. Query should be a valid email, or a string representing a contact's first or last name.")
+@click.option("--list-id", "list_id", default=None, help="The unique id for the list.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, query, list_id, extra_params):
+ """Search members"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/search-members"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "query": query,
+ "list_id": list_id,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/sms_campaigns.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/sms_campaigns.py
new file mode 100644
index 000000000..a30d5373c
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/sms_campaigns.py
@@ -0,0 +1,253 @@
+"""Commands for the Mailchimp /sms-campaigns API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("sms-campaigns")
+@click.pass_context
+def sms_campaigns_group(ctx):
+ """sms-campaigns resource commands."""
+
+@sms_campaigns_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List SMS campaigns"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add SMS campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("delete")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, sms_campaign_id, extra_params):
+ """Delete SMS campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@sms_campaigns_group.command("get")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, sms_campaign_id, fields, exclude_fields, extra_params):
+ """Get SMS campaign info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("update")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, sms_campaign_id, data, extra_params):
+ """Update SMS campaign settings"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("cancel-send")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_cancel_send(ctx, sms_campaign_id, extra_params):
+ """Cancel SMS campaign send"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}/actions/cancel-send"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("schedule")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_schedule(ctx, sms_campaign_id, data, extra_params):
+ """Schedule SMS campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}/actions/schedule"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("send")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_send(ctx, sms_campaign_id, extra_params):
+ """Send SMS campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}/actions/send"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("list-sms-campaigns-id-content")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_sms_campaigns_id_content(ctx, sms_campaign_id, fields, exclude_fields, extra_params):
+ """Get SMS campaign content"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}/content"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@sms_campaigns_group.command("update-sms-campaigns-id-content")
+@click.argument("SMS_CAMPAIGN_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update_sms_campaigns_id_content(ctx, sms_campaign_id, data, extra_params):
+ """Set SMS campaign content"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/sms-campaigns/{sms_campaign_id}/content"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.put(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/surveys.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/surveys.py
new file mode 100644
index 000000000..6d7ef7704
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/surveys.py
@@ -0,0 +1,91 @@
+"""Commands for the Mailchimp /surveys API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("surveys")
+@click.pass_context
+def surveys_group(ctx):
+ """surveys resource commands."""
+
+@surveys_group.command("create-email")
+@click.argument("LIST_ID")
+@click.argument("SURVEY_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create_email(ctx, list_id, survey_id, extra_params):
+ """Create a Survey Campaign"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/surveys/{survey_id}/actions/create-email"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@surveys_group.command("publish")
+@click.argument("LIST_ID")
+@click.argument("SURVEY_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_publish(ctx, list_id, survey_id, extra_params):
+ """Publish a Survey"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/surveys/{survey_id}/actions/publish"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@surveys_group.command("unpublish")
+@click.argument("LIST_ID")
+@click.argument("SURVEY_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_unpublish(ctx, list_id, survey_id, extra_params):
+ """Unpublish a Survey"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/lists/{list_id}/surveys/{survey_id}/actions/unpublish"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.post(path, json=None, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/template_folders.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/template_folders.py
new file mode 100644
index 000000000..afefc23ad
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/template_folders.py
@@ -0,0 +1,144 @@
+"""Commands for the Mailchimp /template-folders API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("template-folders")
+@click.pass_context
+def template_folders_group(ctx):
+ """template-folders resource commands."""
+
+@template_folders_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, extra_params):
+ """List template folders"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/template-folders"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@template_folders_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add template folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/template-folders"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@template_folders_group.command("delete")
+@click.argument("FOLDER_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, folder_id, extra_params):
+ """Delete template folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/template-folders/{folder_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@template_folders_group.command("get")
+@click.argument("FOLDER_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, folder_id, fields, exclude_fields, extra_params):
+ """Get template folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/template-folders/{folder_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@template_folders_group.command("update")
+@click.argument("FOLDER_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, folder_id, data, extra_params):
+ """Update template folder"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/template-folders/{folder_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/templates.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/templates.py
new file mode 100644
index 000000000..face49459
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/templates.py
@@ -0,0 +1,187 @@
+"""Commands for the Mailchimp /templates API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("templates")
+@click.pass_context
+def templates_group(ctx):
+ """templates resource commands."""
+
+@templates_group.command("list")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--count", "count", default=None, type=int, help="The number of records to return. Default value is 10. Maximum value is 1000")
+@click.option("--offset", "offset", default=None, type=int, help="Used for [pagination](https://mailchimp.com/developer/marketing/docs/methods-parameters/#pagination), this is the number of records from a collection to skip. Default value is 0.")
+@click.option("--created-by", "created_by", default=None, help="The Mailchimp account user who created the template.")
+@click.option("--since-date-created", "since_date_created", default=None, help="Restrict the response to templates created after the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--before-date-created", "before_date_created", default=None, help="Restrict the response to templates created before the set date. Uses ISO 8601 time format: 2015-10-21T15:41:36+00:00.")
+@click.option("--type", "type_", default=None, help="Limit results based on template type.")
+@click.option("--category", "category", default=None, help="Limit results based on category.")
+@click.option("--folder-id", "folder_id", default=None, help="The unique folder id.")
+@click.option("--sort-field", "sort_field", default=None, help="Returns user templates sorted by the specified field.")
+@click.option("--content-type", "content_type", default=None, help="Limit results based on how the template's content is put together. Only templates of type `user` can be filtered by `content_type`. If you want to retrieve saved templates created with the legacy email editor, then filter `content_type` to `template`. If you'd rather pull your saved templates for the new editor, filter to `multichannel`. For code your own templates, filter to `html`.")
+@click.option("--sort-dir", "sort_dir", default=None, help="Determines the order direction for sorted results.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, fields, exclude_fields, count, offset, created_by, since_date_created, before_date_created, type_, category, folder_id, sort_field, content_type, sort_dir, extra_params):
+ """List templates"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/templates"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ "count": count,
+ "offset": offset,
+ "created_by": created_by,
+ "since_date_created": since_date_created,
+ "before_date_created": before_date_created,
+ "type": type_,
+ "category": category,
+ "folder_id": folder_id,
+ "sort_field": sort_field,
+ "content_type": content_type,
+ "sort_dir": sort_dir,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@templates_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add template"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/templates"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@templates_group.command("delete")
+@click.argument("TEMPLATE_ID")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, template_id, extra_params):
+ """Delete template"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/templates/{template_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@templates_group.command("get")
+@click.argument("TEMPLATE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, template_id, fields, exclude_fields, extra_params):
+ """Get template info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/templates/{template_id}"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@templates_group.command("update")
+@click.argument("TEMPLATE_ID")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_update(ctx, template_id, data, extra_params):
+ """Update template"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/templates/{template_id}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.patch(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@templates_group.command("list-templates-id-default-content")
+@click.argument("TEMPLATE_ID")
+@click.option("--fields", "fields", default=None, help="A comma-separated list of fields to return. Reference parameters of sub-objects with dot notation.")
+@click.option("--exclude-fields", "exclude_fields", default=None, help="A comma-separated list of fields to exclude. Reference parameters of sub-objects with dot notation.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_templates_id_default_content(ctx, template_id, fields, exclude_fields, extra_params):
+ """View default content"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/templates/{template_id}/default-content"
+ params = {k: v for k, v in {
+ "fields": fields,
+ "exclude_fields": exclude_fields,
+ }.items() if v is not None}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/commands/verified_domains.py b/mailchimp/agent-harness/cli_anything/mailchimp/commands/verified_domains.py
new file mode 100644
index 000000000..c6902adfa
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/commands/verified_domains.py
@@ -0,0 +1,130 @@
+"""Commands for the Mailchimp /verified-domains API resource.
+
+Auto-generated by cli_anything/mailchimp/_codegen/generate.py.
+Do not edit manually โ re-run the generator to update.
+"""
+
+import json
+
+import click
+
+
+def _parse_json_option(value, option_name, require_object=False):
+ try:
+ parsed = json.loads(value)
+ except json.JSONDecodeError as exc:
+ raise click.BadParameter(
+ f"must be valid JSON ({exc.msg})",
+ param_hint=option_name,
+ ) from exc
+ if require_object and not isinstance(parsed, dict):
+ raise click.BadParameter("must be a JSON object", param_hint=option_name)
+ return parsed
+
+
+@click.group("verified-domains")
+@click.pass_context
+def verified_domains_group(ctx):
+ """verified-domains resource commands."""
+
+@verified_domains_group.command("list")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_list_(ctx, extra_params):
+ """List sending domains"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/verified-domains"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@verified_domains_group.command("create")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_create(ctx, data, extra_params):
+ """Add domain to account"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/verified-domains"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@verified_domains_group.command("delete")
+@click.argument("DOMAIN_NAME")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_delete(ctx, domain_name, extra_params):
+ """Delete domain"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/verified-domains/{domain_name}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.delete(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out_ok("Deleted.")
+
+@verified_domains_group.command("get")
+@click.argument("DOMAIN_NAME")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_get(ctx, domain_name, extra_params):
+ """Get domain info"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/verified-domains/{domain_name}"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ client = get_client()
+ try:
+ result = client.get(path, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
+
+@verified_domains_group.command("verify")
+@click.argument("DOMAIN_NAME")
+@click.option("--data", default=None, help="Request body as JSON string.")
+@click.option("--extra-params", default=None, help="Extra query params as JSON object, e.g. '{\"key\":\"val\"}'")
+@click.pass_context
+def _cmd_verify(ctx, domain_name, data, extra_params):
+ """Verify domain"""
+ from cli_anything.mailchimp.core.client import get_client, MailchimpError
+ from cli_anything.mailchimp.utils.output import _out, _out_ok, _out_err
+ path = f"/verified-domains/{domain_name}/actions/verify"
+ params = {}
+ if extra_params:
+ params.update(_parse_json_option(extra_params, "--extra-params", require_object=True))
+ body = _parse_json_option(data, "--data") if data else None
+ client = get_client()
+ try:
+ result = client.post(path, json=body, params=params or None)
+ except MailchimpError as e:
+ _out_err(e.status, e.title, e.detail, e.raw)
+ return
+ _out(result)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/core/__init__.py b/mailchimp/agent-harness/cli_anything/mailchimp/core/__init__.py
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/core/__init__.py
@@ -0,0 +1 @@
+
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/core/client.py b/mailchimp/agent-harness/cli_anything/mailchimp/core/client.py
new file mode 100644
index 000000000..47348ae13
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/core/client.py
@@ -0,0 +1,128 @@
+"""Mailchimp Marketing API v3.0 HTTP client."""
+
+from __future__ import annotations
+
+import hashlib
+import os
+import sys
+from typing import Any
+
+import requests
+
+_BASE = "https://{dc}.api.mailchimp.com/3.0"
+_DEFAULT_TIMEOUT = 30
+
+
+def _server_prefix(api_key: str) -> str:
+ """Derive the data-centre prefix from the API key suffix (e.g. 'us8')."""
+ if "-" not in api_key:
+ raise ValueError(
+ "MAILCHIMP_API_KEY must include the data-centre suffix, "
+ "e.g. 'abc123-us8'."
+ )
+ return api_key.rsplit("-", 1)[-1]
+
+
+def subscriber_hash(email: str) -> str:
+ """MD5 hash of the lowercased email โ Mailchimp's subscriber identifier."""
+ return hashlib.md5(email.strip().lower().encode()).hexdigest()
+
+
+class MailchimpAuthError(Exception):
+ """Raised when no API key is available."""
+
+
+class MailchimpError(Exception):
+ def __init__(self, status: int, title: str, detail: str, raw: dict):
+ super().__init__(f"HTTP {status}: {title} โ {detail}")
+ self.status = status
+ self.title = title
+ self.detail = detail
+ self.raw = raw
+
+
+class MailchimpClient:
+ def __init__(self, api_key: str | None = None):
+ key = api_key or os.environ.get("MAILCHIMP_API_KEY", "")
+ if not key:
+ raise MailchimpAuthError(
+ "MAILCHIMP_API_KEY is not set. "
+ "Export it before use: export MAILCHIMP_API_KEY=-"
+ )
+ self._key = key
+ try:
+ self._dc = _server_prefix(key)
+ except ValueError as e:
+ raise MailchimpAuthError(str(e)) from e
+ self._base = _BASE.format(dc=self._dc)
+ self._session = requests.Session()
+ self._session.auth = ("anystring", key)
+ self._session.headers.update({"User-Agent": "cli-anything-mailchimp/0.1.0"})
+
+ # โโ Low-level request helpers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def _url(self, path: str) -> str:
+ return f"{self._base}/{path.lstrip('/')}"
+
+ def _raise(self, resp: requests.Response) -> None:
+ if resp.ok:
+ return
+ try:
+ body = resp.json()
+ raise MailchimpError(
+ status=resp.status_code,
+ title=body.get("title", resp.reason),
+ detail=body.get("detail", ""),
+ raw=body,
+ )
+ except ValueError:
+ raise MailchimpError(
+ status=resp.status_code,
+ title=resp.reason,
+ detail=resp.text[:200],
+ raw={},
+ )
+
+ def get(self, path: str, params: dict | None = None) -> Any:
+ resp = self._session.get(self._url(path), params=params, timeout=_DEFAULT_TIMEOUT)
+ self._raise(resp)
+ return resp.json()
+
+ def post(self, path: str, json: dict | None = None, params: dict | None = None) -> Any:
+ resp = self._session.post(
+ self._url(path), json=json, params=params, timeout=_DEFAULT_TIMEOUT
+ )
+ self._raise(resp)
+ if resp.status_code == 204:
+ return {}
+ return resp.json()
+
+ def patch(self, path: str, json: dict | None = None, params: dict | None = None) -> Any:
+ resp = self._session.patch(
+ self._url(path), json=json, params=params, timeout=_DEFAULT_TIMEOUT
+ )
+ self._raise(resp)
+ return resp.json()
+
+ def put(self, path: str, json: dict | None = None, params: dict | None = None) -> Any:
+ resp = self._session.put(
+ self._url(path), json=json, params=params, timeout=_DEFAULT_TIMEOUT
+ )
+ self._raise(resp)
+ return resp.json()
+
+ def delete(self, path: str, params: dict | None = None) -> dict:
+ resp = self._session.delete(
+ self._url(path), params=params, timeout=_DEFAULT_TIMEOUT
+ )
+ self._raise(resp)
+ return {"ok": True}
+
+
+def get_client() -> MailchimpClient:
+ """Return a client instance, printing an error and exiting if key is missing."""
+ try:
+ return MailchimpClient()
+ except MailchimpAuthError as e:
+ print(f"Error: {e}", file=sys.stderr)
+ raise SystemExit(1)
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/core/pagination.py b/mailchimp/agent-harness/cli_anything/mailchimp/core/pagination.py
new file mode 100644
index 000000000..e4ed7e557
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/core/pagination.py
@@ -0,0 +1,68 @@
+"""Generic count/offset paginator for the Mailchimp API."""
+
+from __future__ import annotations
+
+from typing import Generator
+
+_PAGE_SIZE = 1000
+
+
+def paginate(
+ client,
+ path: str,
+ result_key: str,
+ params: dict | None = None,
+ page_size: int = _PAGE_SIZE,
+) -> Generator[dict, None, None]:
+ """Yield all items from a paginated Mailchimp endpoint.
+
+ Args:
+ client: MailchimpClient instance.
+ path: API path, e.g. "/lists".
+ result_key: Key inside the response that holds the item array.
+ params: Extra query params (count/offset will be added automatically).
+ page_size: Items per page.
+ """
+ params = dict(params or {})
+ params["count"] = page_size
+ offset = 0
+ total: int | None = None
+
+ while True:
+ params["offset"] = offset
+ data = client.get(path, params=params)
+ items: list = data.get(result_key, [])
+
+ if total is None:
+ total = data.get("total_items", None)
+
+ yield from items
+
+ offset += len(items)
+ # Stop when we have fetched all items or got an empty page
+ if not items or (total is not None and offset >= total):
+ break
+
+
+def collect(
+ client,
+ path: str,
+ result_key: str,
+ params: dict | None = None,
+ page_size: int = _PAGE_SIZE,
+) -> tuple[list[dict], int]:
+ """Return (items, total_items) โ fetches a single page by default.
+
+ When the caller passes explicit count/offset in params those are respected;
+ otherwise a single page of page_size is fetched.
+ """
+ params = dict(params or {})
+ if "count" not in params:
+ params["count"] = page_size
+ if "offset" not in params:
+ params["offset"] = 0
+
+ data = client.get(path, params=params)
+ items = data.get(result_key, [])
+ total = data.get("total_items", len(items))
+ return items, total
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/mailchimp_cli.py b/mailchimp/agent-harness/cli_anything/mailchimp/mailchimp_cli.py
new file mode 100644
index 000000000..7587e8467
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/mailchimp_cli.py
@@ -0,0 +1,93 @@
+"""cli-anything harness for the Mailchimp Marketing API v3.0."""
+
+from __future__ import annotations
+
+import click
+
+import cli_anything.mailchimp.utils.output as _output_mod
+from cli_anything.mailchimp.commands import ALL_GROUPS
+
+
+@click.group(invoke_without_command=True)
+@click.option("--json", "use_json", is_flag=True, default=False, help="Output as JSON.")
+@click.version_option("0.1.0", prog_name="cli-anything-mailchimp")
+@click.pass_context
+def cli(ctx: click.Context, use_json: bool) -> None:
+ """cli-anything harness for the Mailchimp Marketing API v3.0.
+
+ Set MAILCHIMP_API_KEY before use:
+
+ export MAILCHIMP_API_KEY=-
+
+ Run without arguments to enter the interactive REPL.
+ """
+ ctx.ensure_object(dict)
+ _output_mod.USE_JSON = use_json
+ if ctx.invoked_subcommand is None:
+ _start_repl()
+
+
+# Register all generated resource groups
+for _group in ALL_GROUPS:
+ cli.add_command(_group)
+
+
+def main() -> None:
+ """Entry point for the Click CLI."""
+ cli()
+
+
+def _start_repl() -> None:
+ """Interactive REPL using prompt_toolkit."""
+ from cli_anything.mailchimp.utils.repl_skin import ReplSkin
+ import shlex
+
+ skin = ReplSkin("mailchimp", version="0.1.0")
+ skin.print_banner()
+
+ pt_session = skin.create_prompt_session()
+
+ while True:
+ try:
+ raw = skin.get_input(pt_session)
+ except (KeyboardInterrupt, EOFError):
+ skin.print_goodbye()
+ break
+
+ line = raw.strip()
+ if not line:
+ continue
+ if line in ("quit", "exit", "q"):
+ skin.print_goodbye()
+ break
+ if line in ("help", "?"):
+ _print_repl_help(skin)
+ continue
+
+ try:
+ args = shlex.split(line)
+ except ValueError as e:
+ skin.error(f"Parse error: {e}")
+ continue
+
+ try:
+ cli.main(args=args, standalone_mode=False)
+ except SystemExit:
+ pass
+ except click.UsageError as e:
+ skin.error(str(e))
+ except Exception as e:
+ skin.error(str(e))
+
+
+def _print_repl_help(skin: object) -> None:
+ from cli_anything.mailchimp.commands import ALL_GROUPS
+
+ commands = {g.name: (g.help or "").split("\n")[0] for g in ALL_GROUPS}
+ commands["--help"] = "Show help for any command"
+ commands["quit"] = "Exit the REPL"
+ skin.help(commands) # type: ignore[attr-defined]
+
+
+if __name__ == "__main__":
+ main()
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/skills/SKILL.md b/mailchimp/agent-harness/cli_anything/mailchimp/skills/SKILL.md
new file mode 100644
index 000000000..c730e9f6c
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/skills/SKILL.md
@@ -0,0 +1,228 @@
+---
+name: cli-anything-mailchimp
+description: CLI harness for the Mailchimp Marketing API v3.0 โ 303 commands across 30 resource groups (lists, campaigns, reports, automations, ecommerce, templates, and more). Supports JSON output and interactive REPL mode.
+---
+
+# cli-anything-mailchimp
+
+## Identity
+
+An agent-native CLI for the [Mailchimp Marketing API v3.0](https://mailchimp.com/developer/marketing/docs/fundamentals/), built on the [CLI-Anything](https://github.com/HKUDS/CLI-Anything) framework.
+
+## What This CLI Does
+
+- Manage **audiences (lists)** โ create, update, delete lists; add/update/archive members; manage merge fields, segments, tags, and webhooks.
+- Run **campaigns** โ create, schedule, send, pause, replicate, and analyse email campaigns.
+- Read **reports** โ open rates, click rates, bounce stats, unsubscribes, email activity, geographic data.
+- Control **automations** โ create and manage automated email workflows.
+- Manage **e-commerce** โ stores, orders, customers, products, carts, and promo codes.
+- Use **templates, file manager, landing pages, SMS campaigns, surveys**, and all other Marketing API resources.
+
+## Prerequisites
+
+- Python 3.10+
+- `MAILCHIMP_API_KEY` environment variable set to your API key (including datacenter suffix, e.g. `abc123-us8`)
+
+## Installation
+
+```bash
+# From the CLI-Anything repo (once merged):
+pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=mailchimp/agent-harness
+
+# During development:
+cd mailchimp/agent-harness && pip install -e .
+```
+
+## Command Reference
+
+### Root
+
+| Command | Description |
+|---|---|
+| `cli-anything-mailchimp ping` | Health check โ confirms API connectivity |
+| `cli-anything-mailchimp root list` | Get account info |
+| `cli-anything-mailchimp --json ` | Output any command as JSON |
+| `cli-anything-mailchimp` | Launch interactive REPL |
+
+### Lists (Audiences)
+
+| Command | Description |
+|---|---|
+| `lists list` | List all audiences |
+| `lists get ` | Get audience info |
+| `lists create --data ''` | Create audience |
+| `lists update --data ''` | Update audience |
+| `lists delete ` | Delete audience |
+| `lists list-lists-id-members ` | List members |
+| `lists get-lists-id-members-id ` | Get member by MD5 hash |
+| `lists create-lists-id-members --data ''` | Add member |
+| `lists list-lists-id-merge-fields ` | List merge fields |
+| `lists create-lists-id-merge-fields --data ''` | Add merge field |
+| `lists list-lists-id-segments ` | List segments |
+| `lists list-list-member-tags ` | List member tags |
+| `lists create-list-member-tags --data ''` | Add/remove member tags |
+| `lists list-lists-id-webhooks ` | List webhooks |
+| `lists create-lists-id-webhooks --data ''` | Add webhook |
+
+### Campaigns
+
+| Command | Description |
+|---|---|
+| `campaigns list` | List campaigns |
+| `campaigns get ` | Get campaign info |
+| `campaigns create --data ''` | Create campaign |
+| `campaigns update --data ''` | Update campaign settings |
+| `campaigns delete ` | Delete campaign |
+| `campaigns send ` | Send campaign immediately |
+| `campaigns schedule --data ''` | Schedule campaign |
+| `campaigns cancel-send ` | Cancel scheduled send |
+| `campaigns pause ` | Pause RSS campaign |
+| `campaigns resume ` | Resume RSS campaign |
+| `campaigns replicate ` | Duplicate campaign |
+| `campaigns list-content ` | Get campaign content |
+| `campaigns list-send-checklist ` | Pre-send checklist |
+
+### Reports
+
+| Command | Description |
+|---|---|
+| `reports list` | List all campaign reports |
+| `reports get ` | Get campaign summary report |
+| `reports list-email-activity ` | Per-subscriber open/click activity |
+| `reports list-click-details ` | Link click breakdown |
+| `reports list-open-details ` | Per-subscriber opens |
+| `reports list-unsubscribed ` | Unsubscribers |
+| `reports list-locations ` | Geographic breakdown |
+| `reports list-domain-performance ` | Per-domain stats |
+
+### Automations
+
+| Command | Description |
+|---|---|
+| `automations list` | List automations |
+| `automations get ` | Get automation info |
+| `automations create --data ''` | Create automation |
+| `automations pause ` | Pause automation |
+| `automations start ` | Start automation |
+| `automations archive ` | Archive automation |
+| `automations list-emails ` | List automation emails |
+
+### E-commerce
+
+| Command | Description |
+|---|---|
+| `ecommerce list-ecommerce-stores` | List stores |
+| `ecommerce get ` | Get store info |
+| `ecommerce create --data ''` | Add store |
+| `ecommerce list-ecommerce-stores-id-orders ` | List orders |
+| `ecommerce list-ecommerce-stores-id-products ` | List products |
+| `ecommerce list-ecommerce-stores-id-customers ` | List customers |
+| `ecommerce list-ecommerce-stores-id-carts ` | List carts |
+| `ecommerce list-ecommerce-stores-id-promocodes ` | List promo codes |
+
+### Other Resources
+
+| Group | Description |
+|---|---|
+| `templates` | Email templates (list, get, create, update, delete) |
+| `template-folders` | Template folders |
+| `campaign-folders` | Campaign folders |
+| `file-manager` | Files and folders in the file manager |
+| `landing-pages` | Landing pages (list, create, publish, unpublish) |
+| `sms-campaigns` | SMS campaigns (10 operations) |
+| `surveys` | Surveys (list, get, publish) |
+| `reporting` | Facebook ad and landing page reporting |
+| `search-campaigns` | Search campaigns by query |
+| `search-members` | Search members across all audiences |
+| `batches` | Batch API operations |
+| `batch-webhooks` | Batch operation webhooks |
+| `verified-domains` | Email domain verification |
+| `authorized-apps` | OAuth connected apps |
+| `connected-sites` | Connected site integrations |
+| `conversations` | Inbox conversations |
+| `activity-feed` | Account activity feed |
+| `account-exports` | Account data exports |
+
+## JSON Output
+
+All commands support `--json` at the root level:
+
+```bash
+# List all audiences as JSON
+cli-anything-mailchimp --json lists list
+
+# Get a campaign report as JSON
+cli-anything-mailchimp --json reports get abc123def
+
+# Pipe to jq โ use the native Mailchimp field name for the resource
+cli-anything-mailchimp --json lists list | jq '.lists[].name'
+cli-anything-mailchimp --json campaigns list | jq '.campaigns[].id'
+```
+
+**Envelope shapes** (native Mailchimp API response โ use the resource-specific key):
+
+```json
+// List endpoints โ key matches the resource name (lists, campaigns, members, etc.)
+{"lists": [...], "total_items": 42, "_links": [...]}
+{"campaigns": [...], "total_items": 10, "_links": [...]}
+
+// Single resource GET / POST / PATCH
+{"id": "abc123", "name": "My List", ...}
+
+// DELETE
+{"ok": true, "message": "Deleted."}
+
+// Error
+{"ok": false, "message": "Resource Not Found: ...", "data": {...}}
+```
+
+## Common Agent Patterns
+
+```bash
+# Get account health
+cli-anything-mailchimp --json ping | jq '.health_status'
+
+# List all audience IDs and names
+cli-anything-mailchimp --json lists list | jq '.lists[] | {id, name}'
+
+# Find all subscribed members in an audience
+cli-anything-mailchimp --json lists list-lists-id-members --status subscribed | jq '.members[].email_address'
+
+# Create a campaign and get its send checklist
+cli-anything-mailchimp --json campaigns create --data '{"type":"regular","settings":{"subject_line":"Hello","from_name":"Me","reply_to":"me@example.com"}}' | jq '.id'
+cli-anything-mailchimp --json campaigns list-send-checklist | jq '.items[] | select(.result == false)'
+
+# Get unsubscribes for a sent campaign
+cli-anything-mailchimp --json reports list-unsubscribed | jq '.unsubscribes[].email_address'
+
+# Add a member to an audience (subscriber hash = MD5 of lowercased email)
+cli-anything-mailchimp --json lists create-members --data '{"email_address":"user@example.com","status":"subscribed"}'
+
+# Search for a member across all audiences
+cli-anything-mailchimp --json search-members list --query "user@example.com" | jq '.exact_matches.members[]'
+```
+
+## Interactive REPL
+
+Run `cli-anything-mailchimp` with no arguments to enter the REPL:
+
+```
+โ cli-anything ยท Mailchimp
+ v0.1.0
+ Type help for commands, quit to exit
+
+โ mailchimp โฏ ping
+ โ {"health_status": "Everything's Chimpy!"}
+
+โ mailchimp โฏ --json lists list
+{"lists": [...], "total_items": 3, "_links": [...]}
+
+โ mailchimp โฏ quit
+```
+
+## Notes
+
+- **Subscriber hash**: Mailchimp identifies members by the MD5 hash of their lowercased email. Compute with `python -c "import hashlib; email='email@example.com'; print(hashlib.md5(email.strip().lower().encode()).hexdigest())"`.
+- **Body payloads**: All POST/PATCH/PUT commands accept `--data ''`. See [Mailchimp API docs](https://mailchimp.com/developer/marketing/api/) for the schema of each endpoint.
+- **Datacenter**: Your API key ends in `-us8`, `-eu2`, etc. The CLI extracts this automatically โ include it in `MAILCHIMP_API_KEY`.
+- **Rate limits**: The Marketing API rate-limits at 10 concurrent connections and a rolling per-account limit. For bulk operations, use the `batches` group.
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/tests/TEST.md b/mailchimp/agent-harness/cli_anything/mailchimp/tests/TEST.md
new file mode 100644
index 000000000..06cb3bda9
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/tests/TEST.md
@@ -0,0 +1,39 @@
+# Test Guide โ cli-anything-mailchimp
+
+## Prerequisites
+
+```bash
+pip install -e ".[dev]"
+# dev extras: pytest, pytest-cov, responses
+```
+
+## Unit tests (no API key needed)
+
+```bash
+cd mailchimp/agent-harness
+pytest cli_anything/mailchimp/tests/test_core.py -v
+```
+
+Expected: all collected tests pass. Runtime < 5 seconds.
+
+## Live E2E tests (requires MAILCHIMP_API_KEY)
+
+```bash
+export MAILCHIMP_API_KEY=-
+pytest cli_anything/mailchimp/tests/test_full_e2e.py -v -s
+```
+
+Expected: 9 tests. The fixture creates a throwaway audience, runs member and
+merge-field operations against it, then deletes it. Runtime ~15โ30 seconds.
+
+Cleanup is automatic (the `test_list` fixture deletes the audience in a
+`finally` block). If a run is interrupted, delete the `cli-anything-test-*`
+list from your Mailchimp account manually.
+
+## Coverage
+
+```bash
+pytest cli_anything/mailchimp/tests/test_core.py --cov=cli_anything.mailchimp.core --cov-report=term-missing
+```
+
+Target: โฅ 80% line coverage on `core/`.
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/tests/test_core.py b/mailchimp/agent-harness/cli_anything/mailchimp/tests/test_core.py
new file mode 100644
index 000000000..61a1f0b66
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/tests/test_core.py
@@ -0,0 +1,566 @@
+"""Unit tests for cli-anything-mailchimp core modules."""
+
+from __future__ import annotations
+
+import json
+import sys
+import unittest
+from unittest.mock import MagicMock, patch
+
+import responses as resp_lib
+import requests
+
+# โโ client tests โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+
+class TestServerPrefix(unittest.TestCase):
+ def test_extracts_suffix(self):
+ from cli_anything.mailchimp.core.client import _server_prefix
+
+ assert _server_prefix("abc123-us8") == "us8"
+ assert _server_prefix("xyz-eu2") == "eu2"
+
+ def test_missing_suffix_raises(self):
+ from cli_anything.mailchimp.core.client import _server_prefix
+
+ with self.assertRaises(ValueError):
+ _server_prefix("nodashinkey")
+
+
+class TestSubscriberHash(unittest.TestCase):
+ def test_md5_lowercased(self):
+ from cli_anything.mailchimp.core.client import subscriber_hash
+
+ # Known MD5 of "test@example.com"
+ assert subscriber_hash("test@example.com") == "55502f40dc8b7c769880b10874abc9d0"
+ # Should normalise to lowercase before hashing
+ assert subscriber_hash("TEST@EXAMPLE.COM") == subscriber_hash("test@example.com")
+
+ def test_strips_whitespace(self):
+ from cli_anything.mailchimp.core.client import subscriber_hash
+
+ assert subscriber_hash(" test@example.com ") == subscriber_hash("test@example.com")
+
+
+class TestMailchimpClient(unittest.TestCase):
+ def _make_client(self, key: str = "testkey-us1"):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ return MailchimpClient(api_key=key)
+
+ def test_base_url(self):
+ client = self._make_client("abc-us8")
+ assert client._base == "https://us8.api.mailchimp.com/3.0"
+
+ def test_auth_header(self):
+ client = self._make_client("abc-us8")
+ assert client._session.auth == ("anystring", "abc-us8")
+
+ def test_missing_key_raises_auth_error(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient, MailchimpAuthError
+ import os
+
+ orig = os.environ.pop("MAILCHIMP_API_KEY", None)
+ try:
+ with self.assertRaises(MailchimpAuthError):
+ MailchimpClient(api_key=None)
+ finally:
+ if orig:
+ os.environ["MAILCHIMP_API_KEY"] = orig
+
+ def test_get_client_exits_on_missing_key(self):
+ from cli_anything.mailchimp.core.client import get_client
+ import os
+
+ orig = os.environ.pop("MAILCHIMP_API_KEY", None)
+ try:
+ with self.assertRaises(SystemExit):
+ get_client()
+ finally:
+ if orig:
+ os.environ["MAILCHIMP_API_KEY"] = orig
+
+ def test_get_client_exits_cleanly_on_key_without_suffix(self):
+ from cli_anything.mailchimp.core.client import get_client
+ import os
+
+ orig = os.environ.get("MAILCHIMP_API_KEY")
+ os.environ["MAILCHIMP_API_KEY"] = "invalid"
+ try:
+ with self.assertRaises(SystemExit):
+ get_client()
+ finally:
+ if orig is None:
+ os.environ.pop("MAILCHIMP_API_KEY", None)
+ else:
+ os.environ["MAILCHIMP_API_KEY"] = orig
+
+ @resp_lib.activate
+ def test_get_success(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ client = MailchimpClient(api_key="key-us1")
+ resp_lib.add(
+ resp_lib.GET,
+ "https://us1.api.mailchimp.com/3.0/ping",
+ json={"health_status": "Everything's Chimpy!"},
+ status=200,
+ )
+ result = client.get("/ping")
+ assert result["health_status"] == "Everything's Chimpy!"
+
+ @resp_lib.activate
+ def test_get_error_raises(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient, MailchimpError
+
+ client = MailchimpClient(api_key="key-us1")
+ resp_lib.add(
+ resp_lib.GET,
+ "https://us1.api.mailchimp.com/3.0/lists/bad",
+ json={"title": "Resource Not Found", "detail": "The requested resource could not be found.", "status": 404},
+ status=404,
+ )
+ with self.assertRaises(MailchimpError) as ctx:
+ client.get("/lists/bad")
+ assert ctx.exception.status == 404
+ assert "Resource Not Found" in ctx.exception.title
+
+ @resp_lib.activate
+ def test_post_success(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ client = MailchimpClient(api_key="key-us1")
+ resp_lib.add(
+ resp_lib.POST,
+ "https://us1.api.mailchimp.com/3.0/lists",
+ json={"id": "abc123", "name": "My List"},
+ status=200,
+ )
+ result = client.post("/lists", json={"name": "My List"})
+ assert result["id"] == "abc123"
+
+ @resp_lib.activate
+ def test_delete_returns_ok(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ client = MailchimpClient(api_key="key-us1")
+ resp_lib.add(
+ resp_lib.DELETE,
+ "https://us1.api.mailchimp.com/3.0/lists/abc123",
+ status=204,
+ )
+ result = client.delete("/lists/abc123")
+ assert result == {"ok": True}
+
+ def test_patch_forwards_query_params(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ client = MailchimpClient(api_key="key-us1")
+ client._session.patch = MagicMock()
+ client._session.patch.return_value.ok = True
+ client._session.patch.return_value.json.return_value = {"id": "contact-1"}
+
+ result = client.patch(
+ "/audiences/audience-1/contacts/contact-1",
+ json={"email_address": "user@example.com"},
+ params={"data_mode": "sync"},
+ )
+
+ assert result == {"id": "contact-1"}
+ client._session.patch.assert_called_once_with(
+ "https://us1.api.mailchimp.com/3.0/audiences/audience-1/contacts/contact-1",
+ json={"email_address": "user@example.com"},
+ params={"data_mode": "sync"},
+ timeout=30,
+ )
+
+ def test_put_forwards_query_params(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ client = MailchimpClient(api_key="key-us1")
+ client._session.put = MagicMock()
+ client._session.put.return_value.ok = True
+ client._session.put.return_value.json.return_value = {"id": "member-1"}
+
+ result = client.put(
+ "/lists/list-1/members/hash-1",
+ json={"email_address": "user@example.com"},
+ params={"skip_merge_validation": True},
+ )
+
+ assert result == {"id": "member-1"}
+ client._session.put.assert_called_once_with(
+ "https://us1.api.mailchimp.com/3.0/lists/list-1/members/hash-1",
+ json={"email_address": "user@example.com"},
+ params={"skip_merge_validation": True},
+ timeout=30,
+ )
+
+ def test_delete_forwards_query_params(self):
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ client = MailchimpClient(api_key="key-us1")
+ client._session.delete = MagicMock()
+ client._session.delete.return_value.ok = True
+
+ result = client.delete("/lists/list-1", params={"force": True})
+
+ assert result == {"ok": True}
+ client._session.delete.assert_called_once_with(
+ "https://us1.api.mailchimp.com/3.0/lists/list-1",
+ params={"force": True},
+ timeout=30,
+ )
+
+
+# โโ pagination tests โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+
+class TestPagination(unittest.TestCase):
+ def _mock_client(self, pages: list[list]) -> MagicMock:
+ client = MagicMock()
+ side_effects = [
+ {"lists": page, "total_items": sum(len(p) for p in pages)}
+ for page in pages
+ ]
+ client.get.side_effect = side_effects
+ return client
+
+ def test_single_page(self):
+ from cli_anything.mailchimp.core.pagination import paginate
+
+ client = self._mock_client([[{"id": "1"}, {"id": "2"}]])
+ items = list(paginate(client, "/lists", "lists", page_size=100))
+ assert items == [{"id": "1"}, {"id": "2"}]
+ assert client.get.call_count == 1
+
+ def test_multiple_pages(self):
+ from cli_anything.mailchimp.core.pagination import paginate
+
+ page1 = [{"id": str(i)} for i in range(5)]
+ page2 = [{"id": str(i)} for i in range(5, 8)]
+ client = self._mock_client([page1, page2])
+ items = list(paginate(client, "/lists", "lists", page_size=5))
+ assert len(items) == 8
+ assert client.get.call_count == 2
+
+ def test_empty_result(self):
+ from cli_anything.mailchimp.core.pagination import paginate
+
+ client = self._mock_client([[]])
+ items = list(paginate(client, "/lists", "lists"))
+ assert items == []
+
+ def test_exact_page_boundary_no_extra_fetch(self):
+ """When total_items == page_size, paginator must not fetch a second empty page (I6 fix)."""
+ from cli_anything.mailchimp.core.pagination import paginate
+
+ page = [{"id": str(i)} for i in range(5)]
+ client = MagicMock()
+ # First call returns exactly page_size items with total_items matching
+ client.get.return_value = {"lists": page, "total_items": 5}
+ items = list(paginate(client, "/lists", "lists", page_size=5))
+ assert len(items) == 5
+ assert client.get.call_count == 1 # must not make a second call
+
+ def test_collect_returns_total(self):
+ from cli_anything.mailchimp.core.pagination import collect
+
+ client = MagicMock()
+ client.get.return_value = {"lists": [{"id": "1"}], "total_items": 42}
+ items, total = collect(client, "/lists", "lists")
+ assert items == [{"id": "1"}]
+ assert total == 42
+
+
+# โโ output tests โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+
+class TestOutput(unittest.TestCase):
+ def setUp(self):
+ import cli_anything.mailchimp.utils.output as out
+ self._orig = out.USE_JSON
+ out.USE_JSON = False
+
+ def tearDown(self):
+ import cli_anything.mailchimp.utils.output as out
+ out.USE_JSON = self._orig
+
+ def test_json_mode_outputs_json(self):
+ import cli_anything.mailchimp.utils.output as out
+ import io
+
+ out.USE_JSON = True
+ captured = io.StringIO()
+ with patch("builtins.print", lambda *a, **kw: captured.write(str(a[0]) + "\n")):
+ out._out({"key": "value"})
+
+ parsed = json.loads(captured.getvalue())
+ assert parsed["key"] == "value"
+
+# โโ smoke import tests โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+
+class TestGeneratedCommandsImport(unittest.TestCase):
+ """Verify every generated command module imports cleanly and registers commands.
+
+ This catches codegen regressions like C1 (builtin shadowing) which would
+ cause Click to fail silently or raise at import time.
+ """
+
+ def test_all_groups_importable(self):
+ from cli_anything.mailchimp.commands import ALL_GROUPS
+
+ assert len(ALL_GROUPS) == 30, f"Expected 30 groups, got {len(ALL_GROUPS)}"
+ for group in ALL_GROUPS:
+ assert group.name is not None
+ assert len(group.commands) > 0, f"Group {group.name!r} has no commands"
+
+ def test_generator_preserves_complete_first_line_help(self):
+ from cli_anything.mailchimp._codegen.generate import _click_help_text
+
+ description = (
+ "Used for [pagination](https://mailchimp.com/developer/marketing/docs/fundamentals/#pagination) "
+ "with enough context to exceed eighty characters.\nSecond line omitted."
+ )
+
+ help_text = _click_help_text(description)
+
+ assert help_text.endswith("eighty characters.")
+ assert "\n" not in help_text
+
+ def test_no_builtin_shadowing_in_function_names(self):
+ """Ensure generated functions are prefixed with _cmd_ (not builtins)."""
+ import glob
+ import ast
+ import builtins as _builtins
+
+ builtin_names = set(dir(_builtins))
+ issues = []
+
+ for path in glob.glob("cli_anything/mailchimp/commands/*.py"):
+ tree = ast.parse(open(path).read())
+ for node in ast.walk(tree):
+ if isinstance(node, ast.FunctionDef):
+ if node.name in builtin_names:
+ issues.append(f"{path}: def {node.name}()")
+
+ assert not issues, "Builtin shadowing in generated code:\n" + "\n".join(issues)
+
+ def test_all_commands_have_extra_params(self):
+ """Every generated command must accept --extra-params (I3 fix)."""
+ from cli_anything.mailchimp.commands import ALL_GROUPS
+ import click
+
+ missing = []
+ for group in ALL_GROUPS:
+ for cmd_name, cmd in group.commands.items():
+ if isinstance(cmd, click.Group):
+ continue
+ param_names = [p.name for p in cmd.params]
+ if "extra_params" not in param_names:
+ missing.append(f"{group.name} {cmd_name}")
+
+ assert not missing, "--extra-params missing on:\n" + "\n".join(missing)
+
+ def test_generated_patch_command_forwards_query_params(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.audiences import audiences_group
+
+ client = MagicMock()
+ client.patch.return_value = {"id": "contact-1"}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ result = CliRunner().invoke(
+ audiences_group,
+ [
+ "update",
+ "audience-1",
+ "contact-1",
+ "--data",
+ '{"email_address":"user@example.com"}',
+ "--data-mode",
+ "sync",
+ ],
+ )
+
+ assert result.exit_code == 0, result.output
+ client.patch.assert_called_once_with(
+ "/audiences/audience-1/contacts/contact-1",
+ json={"email_address": "user@example.com"},
+ params={"data_mode": "sync"},
+ )
+
+ def test_generated_put_command_forwards_query_params(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.lists import lists_group
+
+ client = MagicMock()
+ client.put.return_value = {"id": "member-1"}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ result = CliRunner().invoke(
+ lists_group,
+ [
+ "update-3",
+ "list-1",
+ "hash-1",
+ "--data",
+ '{"email_address":"user@example.com"}',
+ "--skip-merge-validation",
+ "true",
+ ],
+ )
+
+ assert result.exit_code == 0, result.output
+ client.put.assert_called_once_with(
+ "/lists/list-1/members/hash-1",
+ json={"email_address": "user@example.com"},
+ params={"skip_merge_validation": True},
+ )
+
+ def test_generated_keyword_query_option_uses_safe_callback_name(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.templates import templates_group
+
+ client = MagicMock()
+ client.get.return_value = {"templates": []}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ result = CliRunner().invoke(templates_group, ["list", "--type", "user"])
+
+ assert result.exit_code == 0, result.output
+ client.get.assert_called_once_with("/templates", params={"type": "user"})
+
+ def test_campaign_shortcut_aliases_match_generated_commands(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.campaigns import campaigns_group
+
+ client = MagicMock()
+ client.get.return_value = {"items": []}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ content = CliRunner().invoke(campaigns_group, ["list-content", "campaign-1"])
+ checklist = CliRunner().invoke(campaigns_group, ["list-send-checklist", "campaign-1"])
+
+ assert content.exit_code == 0, content.output
+ assert checklist.exit_code == 0, checklist.output
+ client.get.assert_any_call("/campaigns/campaign-1/content", params=None)
+ client.get.assert_any_call("/campaigns/campaign-1/send-checklist", params=None)
+
+ def test_report_shortcut_aliases_match_generated_commands(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.reports import reports_group
+
+ client = MagicMock()
+ client.get.return_value = {"items": []}
+
+ shortcuts = {
+ "list-email-activity": "/reports/campaign-1/email-activity",
+ "list-click-details": "/reports/campaign-1/click-details",
+ "list-open-details": "/reports/campaign-1/open-details",
+ "list-unsubscribed": "/reports/campaign-1/unsubscribed",
+ "list-locations": "/reports/campaign-1/locations",
+ "list-domain-performance": "/reports/campaign-1/domain-performance",
+ }
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ for command in shortcuts:
+ result = CliRunner().invoke(reports_group, [command, "campaign-1"])
+ assert result.exit_code == 0, result.output
+
+ for path in shortcuts.values():
+ client.get.assert_any_call(path, params=None)
+
+ def test_automation_and_segment_shortcut_aliases_match_generated_commands(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.automations import automations_group
+ from cli_anything.mailchimp.commands.lists import lists_group
+
+ client = MagicMock()
+ client.get.return_value = {"items": []}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ emails = CliRunner().invoke(automations_group, ["list-emails", "workflow-1"])
+ segments = CliRunner().invoke(lists_group, ["list-lists-id-segments", "list-1"])
+
+ assert emails.exit_code == 0, emails.output
+ assert segments.exit_code == 0, segments.output
+ client.get.assert_any_call("/automations/workflow-1/emails", params=None)
+ client.get.assert_any_call("/lists/list-1/segments", params=None)
+
+ def test_ping_group_invokes_health_check_without_list_subcommand(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.mailchimp_cli import cli
+
+ client = MagicMock()
+ client.get.return_value = {"health_status": "Everything's Chimpy!"}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ result = CliRunner().invoke(cli, ["ping"])
+
+ assert result.exit_code == 0, result.output
+ client.get.assert_called_once_with("/ping", params=None)
+
+ def test_create_members_alias_matches_generated_command(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.lists import lists_group
+
+ client = MagicMock()
+ client.post.return_value = {"id": "member-1"}
+
+ with patch("cli_anything.mailchimp.core.client.get_client", return_value=client):
+ result = CliRunner().invoke(
+ lists_group,
+ [
+ "create-members",
+ "list-1",
+ "--data",
+ '{"email_address":"user@example.com","status":"subscribed"}',
+ "--skip-merge-validation",
+ "true",
+ ],
+ )
+
+ assert result.exit_code == 0, result.output
+ client.post.assert_called_once_with(
+ "/lists/list-1/members",
+ json={"email_address": "user@example.com", "status": "subscribed"},
+ params={"skip_merge_validation": True},
+ )
+
+ def test_invalid_data_json_reports_click_error(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.lists import lists_group
+
+ result = CliRunner().invoke(lists_group, ["create", "--data", "{bad"])
+
+ assert result.exit_code == 2
+ assert "Invalid value for --data" in result.output
+ assert "valid JSON" in result.output
+ assert "Traceback" not in result.output
+
+ def test_extra_params_must_be_json_object(self):
+ from click.testing import CliRunner
+ from cli_anything.mailchimp.commands.lists import lists_group
+
+ result = CliRunner().invoke(lists_group, ["list", "--extra-params", "[]"])
+
+ assert result.exit_code == 2
+ assert "Invalid value for --extra-params" in result.output
+ assert "JSON object" in result.output
+ assert "Traceback" not in result.output
+
+ def test_cli_without_subcommand_starts_repl_through_click(self):
+ from click.testing import CliRunner
+ import cli_anything.mailchimp.mailchimp_cli as mailchimp_cli
+
+ with patch.object(mailchimp_cli, "_start_repl") as start_repl:
+ result = CliRunner().invoke(mailchimp_cli.cli, [])
+
+ assert result.exit_code == 0, result.output
+ start_repl.assert_called_once_with()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/tests/test_full_e2e.py b/mailchimp/agent-harness/cli_anything/mailchimp/tests/test_full_e2e.py
new file mode 100644
index 000000000..db85dabc1
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/tests/test_full_e2e.py
@@ -0,0 +1,127 @@
+"""End-to-end tests against the live Mailchimp API.
+
+Skipped unless MAILCHIMP_API_KEY is set. Creates a throwaway audience,
+exercises member and merge-field operations, then cleans up.
+
+Run:
+ MAILCHIMP_API_KEY=- pytest tests/test_full_e2e.py -v -s
+"""
+
+from __future__ import annotations
+
+import os
+import uuid
+import pytest
+
+pytestmark = pytest.mark.skipif(
+ not os.environ.get("MAILCHIMP_API_KEY"),
+ reason="MAILCHIMP_API_KEY not set โ skipping live API tests",
+)
+
+TEST_LIST_NAME = f"cli-anything-test-{uuid.uuid4().hex[:8]}"
+TEST_EMAIL = f"cli-test-{uuid.uuid4().hex[:8]}@example.com"
+
+
+@pytest.fixture(scope="module")
+def client():
+ from cli_anything.mailchimp.core.client import MailchimpClient
+
+ return MailchimpClient()
+
+
+@pytest.fixture(scope="module")
+def test_list(client):
+ """Create a throwaway Mailchimp audience, yield its ID, then delete it."""
+ body = {
+ "name": TEST_LIST_NAME,
+ "contact": {
+ "company": "CLI-Anything Test",
+ "address1": "123 Test St",
+ "city": "Testville",
+ "state": "CA",
+ "zip": "90210",
+ "country": "US",
+ },
+ "permission_reminder": "test permission reminder",
+ "email_type_option": False,
+ "campaign_defaults": {
+ "from_name": "CLI Test",
+ "from_email": "test@example.com",
+ "subject": "Test",
+ "language": "en",
+ },
+ }
+ result = client.post("/lists", json=body)
+ list_id = result["id"]
+ yield list_id
+ # Cleanup โ delete the test list
+ try:
+ client.delete(f"/lists/{list_id}")
+ except Exception:
+ pass
+
+
+class TestPing:
+ def test_ping(self, client):
+ result = client.get("/ping")
+ assert "health_status" in result
+
+
+class TestLists:
+ def test_get_lists(self, client):
+ result = client.get("/lists", params={"count": 1})
+ assert "lists" in result
+ assert isinstance(result["lists"], list)
+
+ def test_create_and_get_list(self, client, test_list):
+ result = client.get(f"/lists/{test_list}")
+ assert result["id"] == test_list
+ assert result["name"] == TEST_LIST_NAME
+
+ def test_update_list(self, client, test_list):
+ new_name = TEST_LIST_NAME + "-updated"
+ result = client.patch(f"/lists/{test_list}", json={"name": new_name})
+ assert result["name"] == new_name
+ # Restore
+ client.patch(f"/lists/{test_list}", json={"name": TEST_LIST_NAME})
+
+
+class TestMembers:
+ def test_add_member(self, client, test_list):
+ body = {
+ "email_address": TEST_EMAIL,
+ "status": "subscribed",
+ }
+ result = client.post(f"/lists/{test_list}/members", json=body)
+ assert result["email_address"] == TEST_EMAIL
+ assert result["status"] == "subscribed"
+
+ def test_get_member(self, client, test_list):
+ from cli_anything.mailchimp.core.client import subscriber_hash
+
+ h = subscriber_hash(TEST_EMAIL)
+ result = client.get(f"/lists/{test_list}/members/{h}")
+ assert result["email_address"] == TEST_EMAIL
+
+ def test_list_members(self, client, test_list):
+ result = client.get(f"/lists/{test_list}/members", params={"count": 10})
+ emails = [m["email_address"] for m in result.get("members", [])]
+ assert TEST_EMAIL in emails
+
+ def test_archive_member(self, client, test_list):
+ from cli_anything.mailchimp.core.client import subscriber_hash
+
+ h = subscriber_hash(TEST_EMAIL)
+ result = client.delete(f"/lists/{test_list}/members/{h}")
+ assert result == {"ok": True}
+
+
+class TestMergeFields:
+ def test_create_and_list_merge_fields(self, client, test_list):
+ body = {"tag": "TESTFIELD", "name": "Test Field", "type": "text"}
+ result = client.post(f"/lists/{test_list}/merge-fields", json=body)
+ assert result["tag"] == "TESTFIELD"
+
+ fields = client.get(f"/lists/{test_list}/merge-fields")
+ tags = [f["tag"] for f in fields.get("merge_fields", [])]
+ assert "TESTFIELD" in tags
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/utils/__init__.py b/mailchimp/agent-harness/cli_anything/mailchimp/utils/__init__.py
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/utils/__init__.py
@@ -0,0 +1 @@
+
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/utils/output.py b/mailchimp/agent-harness/cli_anything/mailchimp/utils/output.py
new file mode 100644
index 000000000..1b5bc8fe8
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/utils/output.py
@@ -0,0 +1,86 @@
+"""JSON / human output helpers for cli-anything-mailchimp."""
+
+from __future__ import annotations
+
+import json
+import sys
+from typing import Any
+
+# Module-level flag set by the root CLI group's --json option.
+USE_JSON: bool = False
+
+
+def _out(data: Any) -> None:
+ """Print data as JSON (when --json) or human-readable text."""
+ if USE_JSON:
+ print(json.dumps(data, indent=2, default=str))
+ elif isinstance(data, dict):
+ _print_dict(data)
+ elif isinstance(data, list):
+ _print_list(data)
+ else:
+ print(data)
+
+
+def _out_ok(message: str, data: dict | None = None) -> None:
+ """Print a success/mutation result.
+
+ JSON shape: {"ok": true, "message": ""} or {"ok": true, "message": "...", "data": {...}}
+ """
+ if USE_JSON:
+ payload: dict = {"ok": True, "message": message}
+ if data:
+ payload["data"] = data
+ print(json.dumps(payload, indent=2, default=str))
+ else:
+ print(f" \033[38;5;78mโ\033[0m {message}")
+ if data:
+ _print_dict(data)
+
+
+def _out_err(status: int, title: str, detail: str, raw: dict | None = None) -> None:
+ """Print an error and exit non-zero."""
+ if USE_JSON:
+ print(
+ json.dumps(
+ {"ok": False, "message": f"{title}: {detail}", "data": raw or {}},
+ indent=2,
+ ),
+ file=sys.stderr,
+ )
+ else:
+ print(f" \033[38;5;196mโ\033[0m HTTP {status}: {title}", file=sys.stderr)
+ if detail:
+ print(f" {detail}", file=sys.stderr)
+ sys.exit(1)
+
+
+# โโ Formatting helpers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+
+_GRAY = "\033[38;5;245m"
+_WHITE = "\033[97m"
+_CYAN = "\033[38;5;80m"
+_RESET = "\033[0m"
+
+
+def _print_dict(d: dict, indent: int = 2) -> None:
+ prefix = " " * indent
+ for k, v in d.items():
+ key = f"{_GRAY}{k}:{_RESET}"
+ if isinstance(v, dict):
+ print(f"{prefix}{key}")
+ _print_dict(v, indent + 2)
+ elif isinstance(v, list):
+ print(f"{prefix}{key} [{len(v)} items]")
+ else:
+ print(f"{prefix}{key} {_WHITE}{v}{_RESET}")
+
+
+def _print_list(items: list, indent: int = 2) -> None:
+ for item in items:
+ if isinstance(item, dict):
+ _print_dict(item, indent)
+ print()
+ else:
+ print(" " * indent + str(item))
diff --git a/mailchimp/agent-harness/cli_anything/mailchimp/utils/repl_skin.py b/mailchimp/agent-harness/cli_anything/mailchimp/utils/repl_skin.py
new file mode 100644
index 000000000..bc1fb6d1d
--- /dev/null
+++ b/mailchimp/agent-harness/cli_anything/mailchimp/utils/repl_skin.py
@@ -0,0 +1,567 @@
+"""cli-anything REPL Skin โ Unified terminal interface for all CLI harnesses.
+
+Copy this file into your CLI package at:
+ cli_anything//utils/repl_skin.py
+
+Usage:
+ from cli_anything..utils.repl_skin import ReplSkin
+
+ skin = ReplSkin("shotcut", version="1.0.0")
+ skin.print_banner() # auto-detects repo-root or packaged SKILL.md
+ prompt_text = skin.prompt(project_name="my_video.mlt", modified=True)
+ skin.success("Project saved")
+ skin.error("File not found")
+ skin.warning("Unsaved changes")
+ skin.info("Processing 24 clips...")
+ skin.status("Track 1", "3 clips, 00:02:30")
+ skin.table(headers, rows)
+ skin.print_goodbye()
+"""
+
+import os
+import sys
+from pathlib import Path
+
+# โโ ANSI color codes (no external deps for core styling) โโโโโโโโโโโโโโ
+
+_RESET = "\033[0m"
+_BOLD = "\033[1m"
+_DIM = "\033[2m"
+_ITALIC = "\033[3m"
+_UNDERLINE = "\033[4m"
+
+# Brand colors
+_CYAN = "\033[38;5;80m" # cli-anything brand cyan
+_CYAN_BG = "\033[48;5;80m"
+_WHITE = "\033[97m"
+_GRAY = "\033[38;5;245m"
+_DARK_GRAY = "\033[38;5;240m"
+_LIGHT_GRAY = "\033[38;5;250m"
+
+# Software accent colors โ each software gets a unique accent
+_ACCENT_COLORS = {
+ "gimp": "\033[38;5;214m", # warm orange
+ "blender": "\033[38;5;208m", # deep orange
+ "inkscape": "\033[38;5;39m", # bright blue
+ "audacity": "\033[38;5;33m", # navy blue
+ "libreoffice": "\033[38;5;40m", # green
+ "obs_studio": "\033[38;5;55m", # purple
+ "kdenlive": "\033[38;5;69m", # slate blue
+ "shotcut": "\033[38;5;35m", # teal green
+}
+_DEFAULT_ACCENT = "\033[38;5;75m" # default sky blue
+
+# Status colors
+_GREEN = "\033[38;5;78m"
+_YELLOW = "\033[38;5;220m"
+_RED = "\033[38;5;196m"
+_BLUE = "\033[38;5;75m"
+_MAGENTA = "\033[38;5;176m"
+
+_SKILL_SOURCE_REPO = os.environ.get("CLI_ANYTHING_SKILL_REPO", "HKUDS/CLI-Anything")
+
+# โโ Brand icon โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+# The cli-anything icon: a small colored diamond/chevron mark
+_ICON = f"{_CYAN}{_BOLD}โ{_RESET}"
+_ICON_SMALL = f"{_CYAN}โธ{_RESET}"
+
+# โโ Box drawing characters โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+_H_LINE = "โ"
+_V_LINE = "โ"
+_TL = "โญ"
+_TR = "โฎ"
+_BL = "โฐ"
+_BR = "โฏ"
+_T_DOWN = "โฌ"
+_T_UP = "โด"
+_T_RIGHT = "โ"
+_T_LEFT = "โค"
+_CROSS = "โผ"
+
+
+def _strip_ansi(text: str) -> str:
+ """Remove ANSI escape codes for length calculation."""
+ import re
+ return re.sub(r"\033\[[^m]*m", "", text)
+
+
+def _visible_len(text: str) -> int:
+ """Get visible length of text (excluding ANSI codes)."""
+ return len(_strip_ansi(text))
+
+
+def _display_home_path(path: str) -> str:
+ """Display a path relative to the home directory when possible."""
+ expanded = Path(path).expanduser().resolve()
+ home = Path.home().resolve()
+ try:
+ relative = expanded.relative_to(home)
+ return f"~/{relative.as_posix()}"
+ except ValueError:
+ return str(expanded)
+
+
+class ReplSkin:
+ """Unified REPL skin for cli-anything CLIs.
+
+ Provides consistent branding, prompts, and message formatting
+ across all CLI harnesses built with the cli-anything methodology.
+ """
+
+ def __init__(self, software: str, version: str = "1.0.0",
+ history_file: str | None = None, skill_path: str | None = None):
+ """Initialize the REPL skin.
+
+ Args:
+ software: Software name (e.g., "gimp", "shotcut", "blender").
+ version: CLI version string.
+ history_file: Path for persistent command history.
+ Defaults to ~/.cli-anything-/history
+ skill_path: Path to the SKILL.md file for agent discovery.
+ Auto-detected from the repo-root skills/ tree when present,
+ otherwise from the package's skills/ directory.
+ Displayed in banner for AI agents to know where to read skill info.
+ """
+ self.software = software.lower().replace("-", "_")
+ self.display_name = software.replace("_", " ").title()
+ self.version = version
+ software_aliases = {"iterm2_ctl": "iterm2"}
+ self.skill_slug = software_aliases.get(self.software, self.software).replace("_", "-")
+ self.skill_id = f"cli-anything-{self.skill_slug}"
+ self.skill_install_cmd = (
+ f"npx skills add {_SKILL_SOURCE_REPO} --skill {self.skill_id} -g -y"
+ )
+ global_skill_root = Path(
+ os.environ.get("CLI_ANYTHING_GLOBAL_SKILLS_DIR", str(Path.home() / ".agents" / "skills"))
+ ).expanduser()
+ self.global_skill_path = str(global_skill_root / self.skill_id / "SKILL.md")
+
+ # Prefer repo-root canonical skills//SKILL.md when running
+ # inside the CLI-Anything monorepo. Fall back to the packaged
+ # cli_anything//skills/SKILL.md for installed harnesses.
+ if skill_path is None:
+ package_skill = Path(__file__).resolve().parent.parent / "skills" / "SKILL.md"
+ repo_skill = None
+ for parent in Path(__file__).resolve().parents:
+ candidate = parent / "skills" / self.skill_id / "SKILL.md"
+ if candidate.is_file():
+ repo_skill = candidate
+ break
+ if repo_skill and repo_skill.is_file():
+ skill_path = str(repo_skill)
+ elif package_skill.is_file():
+ skill_path = str(package_skill)
+ self.skill_path = skill_path
+ self.accent = _ACCENT_COLORS.get(self.software, _DEFAULT_ACCENT)
+
+ # History file
+ if history_file is None:
+ hist_dir = Path.home() / f".cli-anything-{self.software}"
+ hist_dir.mkdir(parents=True, exist_ok=True)
+ self.history_file = str(hist_dir / "history")
+ else:
+ self.history_file = history_file
+
+ # Detect terminal capabilities
+ self._color = self._detect_color_support()
+
+ def _detect_color_support(self) -> bool:
+ """Check if terminal supports color."""
+ if os.environ.get("NO_COLOR"):
+ return False
+ if os.environ.get("CLI_ANYTHING_NO_COLOR"):
+ return False
+ if not hasattr(sys.stdout, "isatty"):
+ return False
+ return sys.stdout.isatty()
+
+ def _c(self, code: str, text: str) -> str:
+ """Apply color code if colors are supported."""
+ if not self._color:
+ return text
+ return f"{code}{text}{_RESET}"
+
+ # โโ Banner โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def print_banner(self):
+ """Print the startup banner with branding."""
+ import textwrap
+
+ inner = 72
+
+ def _box_line(content: str) -> str:
+ """Wrap content in box drawing, padding to inner width."""
+ pad = inner - _visible_len(content)
+ vl = self._c(_DARK_GRAY, _V_LINE)
+ return f"{vl}{content}{' ' * max(0, pad)}{vl}"
+
+ def _meta_lines(label: str, value: str) -> list[str]:
+ """Wrap a metadata line for the banner box."""
+ icon = self._c(_MAGENTA, "โ")
+ label_text = self._c(_DARK_GRAY, label)
+ prefix = f" {icon} {label_text} "
+ available = max(12, inner - _visible_len(prefix))
+ wrapped = textwrap.wrap(
+ value,
+ width=available,
+ break_long_words=True,
+ break_on_hyphens=False,
+ ) or [""]
+ lines = [f"{prefix}{self._c(_LIGHT_GRAY, wrapped[0])}"]
+ continuation_prefix = " " * _visible_len(prefix)
+ for chunk in wrapped[1:]:
+ lines.append(f"{continuation_prefix}{self._c(_LIGHT_GRAY, chunk)}")
+ return lines
+
+ top = self._c(_DARK_GRAY, f"{_TL}{_H_LINE * inner}{_TR}")
+ bot = self._c(_DARK_GRAY, f"{_BL}{_H_LINE * inner}{_BR}")
+
+ # Title: โ cli-anything ยท Shotcut
+ icon = self._c(_CYAN + _BOLD, "โ")
+ brand = self._c(_CYAN + _BOLD, "cli-anything")
+ dot = self._c(_DARK_GRAY, "ยท")
+ name = self._c(self.accent + _BOLD, self.display_name)
+ title = f" {icon} {brand} {dot} {name}"
+
+ ver = f" {self._c(_DARK_GRAY, f' v{self.version}')}"
+ tip = f" {self._c(_DARK_GRAY, ' Type help for commands, quit to exit')}"
+ empty = ""
+
+ meta_lines: list[str] = []
+ meta_lines.extend(_meta_lines("Install:", self.skill_install_cmd))
+ meta_lines.extend(_meta_lines("Global skill:", _display_home_path(self.global_skill_path)))
+ print(top)
+ print(_box_line(title))
+ print(_box_line(ver))
+ for line in meta_lines:
+ print(_box_line(line))
+ print(_box_line(empty))
+ print(_box_line(tip))
+ print(bot)
+ print()
+
+ # โโ Prompt โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def prompt(self, project_name: str = "", modified: bool = False,
+ context: str = "") -> str:
+ """Build a styled prompt string for prompt_toolkit or input().
+
+ Args:
+ project_name: Current project name (empty if none open).
+ modified: Whether the project has unsaved changes.
+ context: Optional extra context to show in prompt.
+
+ Returns:
+ Formatted prompt string.
+ """
+ parts = []
+
+ # Icon
+ if self._color:
+ parts.append(f"{_CYAN}โ{_RESET} ")
+ else:
+ parts.append("> ")
+
+ # Software name
+ parts.append(self._c(self.accent + _BOLD, self.software))
+
+ # Project context
+ if project_name or context:
+ ctx = context or project_name
+ mod = "*" if modified else ""
+ parts.append(f" {self._c(_DARK_GRAY, '[')}")
+ parts.append(self._c(_LIGHT_GRAY, f"{ctx}{mod}"))
+ parts.append(self._c(_DARK_GRAY, ']'))
+
+ parts.append(self._c(_GRAY, " โฏ "))
+
+ return "".join(parts)
+
+ def prompt_tokens(self, project_name: str = "", modified: bool = False,
+ context: str = ""):
+ """Build prompt_toolkit formatted text tokens for the prompt.
+
+ Use with prompt_toolkit's FormattedText for proper ANSI handling.
+
+ Returns:
+ list of (style, text) tuples for prompt_toolkit.
+ """
+ accent_hex = _ANSI_256_TO_HEX.get(self.accent, "#5fafff")
+ tokens = []
+
+ tokens.append(("class:icon", "โ "))
+ tokens.append(("class:software", self.software))
+
+ if project_name or context:
+ ctx = context or project_name
+ mod = "*" if modified else ""
+ tokens.append(("class:bracket", " ["))
+ tokens.append(("class:context", f"{ctx}{mod}"))
+ tokens.append(("class:bracket", "]"))
+
+ tokens.append(("class:arrow", " โฏ "))
+
+ return tokens
+
+ def get_prompt_style(self):
+ """Get a prompt_toolkit Style object matching the skin.
+
+ Returns:
+ prompt_toolkit.styles.Style
+ """
+ try:
+ from prompt_toolkit.styles import Style
+ except ImportError:
+ return None
+
+ accent_hex = _ANSI_256_TO_HEX.get(self.accent, "#5fafff")
+
+ return Style.from_dict({
+ "icon": "#5fdfdf bold", # cyan brand color
+ "software": f"{accent_hex} bold",
+ "bracket": "#585858",
+ "context": "#bcbcbc",
+ "arrow": "#808080",
+ # Completion menu
+ "completion-menu.completion": "bg:#303030 #bcbcbc",
+ "completion-menu.completion.current": f"bg:{accent_hex} #000000",
+ "completion-menu.meta.completion": "bg:#303030 #808080",
+ "completion-menu.meta.completion.current": f"bg:{accent_hex} #000000",
+ # Auto-suggest
+ "auto-suggest": "#585858",
+ # Bottom toolbar
+ "bottom-toolbar": "bg:#1c1c1c #808080",
+ "bottom-toolbar.text": "#808080",
+ })
+
+ # โโ Messages โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def success(self, message: str):
+ """Print a success message with green checkmark."""
+ icon = self._c(_GREEN + _BOLD, "โ")
+ print(f" {icon} {self._c(_GREEN, message)}")
+
+ def error(self, message: str):
+ """Print an error message with red cross."""
+ icon = self._c(_RED + _BOLD, "โ")
+ print(f" {icon} {self._c(_RED, message)}", file=sys.stderr)
+
+ def warning(self, message: str):
+ """Print a warning message with yellow triangle."""
+ icon = self._c(_YELLOW + _BOLD, "โ ")
+ print(f" {icon} {self._c(_YELLOW, message)}")
+
+ def info(self, message: str):
+ """Print an info message with blue dot."""
+ icon = self._c(_BLUE, "โ")
+ print(f" {icon} {self._c(_LIGHT_GRAY, message)}")
+
+ def hint(self, message: str):
+ """Print a subtle hint message."""
+ print(f" {self._c(_DARK_GRAY, message)}")
+
+ def section(self, title: str):
+ """Print a section header."""
+ print()
+ print(f" {self._c(self.accent + _BOLD, title)}")
+ print(f" {self._c(_DARK_GRAY, _H_LINE * len(title))}")
+
+ # โโ Status display โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def status(self, label: str, value: str):
+ """Print a key-value status line."""
+ lbl = self._c(_GRAY, f" {label}:")
+ val = self._c(_WHITE, f" {value}")
+ print(f"{lbl}{val}")
+
+ def status_block(self, items: dict[str, str], title: str = ""):
+ """Print a block of status key-value pairs.
+
+ Args:
+ items: Dict of label -> value pairs.
+ title: Optional title for the block.
+ """
+ if title:
+ self.section(title)
+
+ max_key = max(len(k) for k in items) if items else 0
+ for label, value in items.items():
+ lbl = self._c(_GRAY, f" {label:<{max_key}}")
+ val = self._c(_WHITE, f" {value}")
+ print(f"{lbl}{val}")
+
+ def progress(self, current: int, total: int, label: str = ""):
+ """Print a simple progress indicator.
+
+ Args:
+ current: Current step number.
+ total: Total number of steps.
+ label: Optional label for the progress.
+ """
+ pct = int(current / total * 100) if total > 0 else 0
+ bar_width = 20
+ filled = int(bar_width * current / total) if total > 0 else 0
+ bar = "โ" * filled + "โ" * (bar_width - filled)
+ text = f" {self._c(_CYAN, bar)} {self._c(_GRAY, f'{pct:3d}%')}"
+ if label:
+ text += f" {self._c(_LIGHT_GRAY, label)}"
+ print(text)
+
+ # โโ Table display โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def table(self, headers: list[str], rows: list[list[str]],
+ max_col_width: int = 40):
+ """Print a formatted table with box-drawing characters.
+
+ Args:
+ headers: Column header strings.
+ rows: List of rows, each a list of cell strings.
+ max_col_width: Maximum column width before truncation.
+ """
+ if not headers:
+ return
+
+ # Calculate column widths
+ col_widths = [min(len(h), max_col_width) for h in headers]
+ for row in rows:
+ for i, cell in enumerate(row):
+ if i < len(col_widths):
+ col_widths[i] = min(
+ max(col_widths[i], len(str(cell))), max_col_width
+ )
+
+ def pad(text: str, width: int) -> str:
+ t = str(text)[:width]
+ return t + " " * (width - len(t))
+
+ # Header
+ header_cells = [
+ self._c(_CYAN + _BOLD, pad(h, col_widths[i]))
+ for i, h in enumerate(headers)
+ ]
+ sep = self._c(_DARK_GRAY, f" {_V_LINE} ")
+ header_line = f" {sep.join(header_cells)}"
+ print(header_line)
+
+ # Separator
+ sep_parts = [self._c(_DARK_GRAY, _H_LINE * w) for w in col_widths]
+ sep_line = self._c(_DARK_GRAY, f" {'โโโ'.join([_H_LINE * w for w in col_widths])}")
+ print(sep_line)
+
+ # Rows
+ for row in rows:
+ cells = []
+ for i, cell in enumerate(row):
+ if i < len(col_widths):
+ cells.append(self._c(_LIGHT_GRAY, pad(str(cell), col_widths[i])))
+ row_sep = self._c(_DARK_GRAY, f" {_V_LINE} ")
+ print(f" {row_sep.join(cells)}")
+
+ # โโ Help display โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def help(self, commands: dict[str, str]):
+ """Print a formatted help listing.
+
+ Args:
+ commands: Dict of command -> description pairs.
+ """
+ self.section("Commands")
+ max_cmd = max(len(c) for c in commands) if commands else 0
+ for cmd, desc in commands.items():
+ cmd_styled = self._c(self.accent, f" {cmd:<{max_cmd}}")
+ desc_styled = self._c(_GRAY, f" {desc}")
+ print(f"{cmd_styled}{desc_styled}")
+ print()
+
+ # โโ Goodbye โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def print_goodbye(self):
+ """Print a styled goodbye message."""
+ print(f"\n {_ICON_SMALL} {self._c(_GRAY, 'Goodbye!')}\n")
+
+ # โโ Prompt toolkit session factory โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def create_prompt_session(self):
+ """Create a prompt_toolkit PromptSession with skin styling.
+
+ Returns:
+ A configured PromptSession, or None if prompt_toolkit unavailable.
+ """
+ try:
+ from prompt_toolkit import PromptSession
+ from prompt_toolkit.history import FileHistory
+ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
+ from prompt_toolkit.formatted_text import FormattedText
+
+ style = self.get_prompt_style()
+
+ session = PromptSession(
+ history=FileHistory(self.history_file),
+ auto_suggest=AutoSuggestFromHistory(),
+ style=style,
+ enable_history_search=True,
+ )
+ return session
+ except ImportError:
+ return None
+
+ def get_input(self, pt_session, project_name: str = "",
+ modified: bool = False, context: str = "") -> str:
+ """Get input from user using prompt_toolkit or fallback.
+
+ Args:
+ pt_session: A prompt_toolkit PromptSession (or None).
+ project_name: Current project name.
+ modified: Whether project has unsaved changes.
+ context: Optional context string.
+
+ Returns:
+ User input string (stripped).
+ """
+ if pt_session is not None:
+ from prompt_toolkit.formatted_text import FormattedText
+ tokens = self.prompt_tokens(project_name, modified, context)
+ return pt_session.prompt(FormattedText(tokens)).strip()
+ else:
+ raw_prompt = self.prompt(project_name, modified, context)
+ return input(raw_prompt).strip()
+
+ # โโ Toolbar builder โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+ def bottom_toolbar(self, items: dict[str, str]):
+ """Create a bottom toolbar callback for prompt_toolkit.
+
+ Args:
+ items: Dict of label -> value pairs to show in toolbar.
+
+ Returns:
+ A callable that returns FormattedText for the toolbar.
+ """
+ def toolbar():
+ from prompt_toolkit.formatted_text import FormattedText
+ parts = []
+ for i, (k, v) in enumerate(items.items()):
+ if i > 0:
+ parts.append(("class:bottom-toolbar.text", " โ "))
+ parts.append(("class:bottom-toolbar.text", f" {k}: "))
+ parts.append(("class:bottom-toolbar", v))
+ return FormattedText(parts)
+ return toolbar
+
+
+# โโ ANSI 256-color to hex mapping (for prompt_toolkit styles) โโโโโโโโโ
+
+_ANSI_256_TO_HEX = {
+ "\033[38;5;33m": "#0087ff", # audacity navy blue
+ "\033[38;5;35m": "#00af5f", # shotcut teal
+ "\033[38;5;39m": "#00afff", # inkscape bright blue
+ "\033[38;5;40m": "#00d700", # libreoffice green
+ "\033[38;5;55m": "#5f00af", # obs purple
+ "\033[38;5;69m": "#5f87ff", # kdenlive slate blue
+ "\033[38;5;75m": "#5fafff", # default sky blue
+ "\033[38;5;80m": "#5fd7d7", # brand cyan
+ "\033[38;5;208m": "#ff8700", # blender deep orange
+ "\033[38;5;214m": "#ffaf00", # gimp warm orange
+}
diff --git a/mailchimp/agent-harness/setup.py b/mailchimp/agent-harness/setup.py
new file mode 100644
index 000000000..b9e3c1d64
--- /dev/null
+++ b/mailchimp/agent-harness/setup.py
@@ -0,0 +1,38 @@
+import os
+from setuptools import setup, find_namespace_packages
+
+_here = os.path.abspath(os.path.dirname(__file__))
+
+with open(os.path.join(_here, "cli_anything/mailchimp/README.md"), encoding="utf-8") as fh:
+ long_description = fh.read()
+
+setup(
+ name="cli-anything-mailchimp",
+ version="0.1.0",
+ description="cli-anything harness for the Mailchimp Marketing API v3.0",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+ author="cli-anything contributors",
+ license="Apache-2.0",
+ python_requires=">=3.10",
+ packages=find_namespace_packages(include=["cli_anything.*"]),
+ package_data={"cli_anything.mailchimp": ["skills/SKILL.md", "README.md"]},
+ install_requires=[
+ "click>=8.0",
+ "requests>=2.28",
+ "prompt-toolkit>=3.0",
+ ],
+ extras_require={
+ "dev": ["pytest>=7.0", "pytest-cov", "responses>=0.23"],
+ },
+ entry_points={
+ "console_scripts": [
+ "cli-anything-mailchimp=cli_anything.mailchimp.mailchimp_cli:main",
+ ],
+ },
+ classifiers=[
+ "Programming Language :: Python :: 3",
+ "License :: OSI Approved :: Apache Software License",
+ "Operating System :: OS Independent",
+ ],
+)
diff --git a/registry.json b/registry.json
index bc84bf449..9c9390b7b 100644
--- a/registry.json
+++ b/registry.json
@@ -1086,6 +1086,25 @@
"url": "https://github.com/collectivewinca"
}
]
+ },
+ {
+ "name": "mailchimp",
+ "display_name": "Mailchimp",
+ "version": "0.1.0",
+ "description": "Mailchimp Marketing API v3.0 โ manage audiences, campaigns, reports, automations, ecommerce, templates, and more from an agent-native CLI",
+ "requires": "MAILCHIMP_API_KEY",
+ "homepage": "https://mailchimp.com/developer/marketing/",
+ "source_url": null,
+ "install_cmd": "pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=mailchimp/agent-harness",
+ "entry_point": "cli-anything-mailchimp",
+ "skill_md": "skills/cli-anything-mailchimp/SKILL.md",
+ "category": "web",
+ "contributors": [
+ {
+ "name": "iGodly",
+ "url": "https://github.com/iGodly"
+ }
+ ]
}
]
}
diff --git a/skills/cli-anything-mailchimp/SKILL.md b/skills/cli-anything-mailchimp/SKILL.md
new file mode 100644
index 000000000..c730e9f6c
--- /dev/null
+++ b/skills/cli-anything-mailchimp/SKILL.md
@@ -0,0 +1,228 @@
+---
+name: cli-anything-mailchimp
+description: CLI harness for the Mailchimp Marketing API v3.0 โ 303 commands across 30 resource groups (lists, campaigns, reports, automations, ecommerce, templates, and more). Supports JSON output and interactive REPL mode.
+---
+
+# cli-anything-mailchimp
+
+## Identity
+
+An agent-native CLI for the [Mailchimp Marketing API v3.0](https://mailchimp.com/developer/marketing/docs/fundamentals/), built on the [CLI-Anything](https://github.com/HKUDS/CLI-Anything) framework.
+
+## What This CLI Does
+
+- Manage **audiences (lists)** โ create, update, delete lists; add/update/archive members; manage merge fields, segments, tags, and webhooks.
+- Run **campaigns** โ create, schedule, send, pause, replicate, and analyse email campaigns.
+- Read **reports** โ open rates, click rates, bounce stats, unsubscribes, email activity, geographic data.
+- Control **automations** โ create and manage automated email workflows.
+- Manage **e-commerce** โ stores, orders, customers, products, carts, and promo codes.
+- Use **templates, file manager, landing pages, SMS campaigns, surveys**, and all other Marketing API resources.
+
+## Prerequisites
+
+- Python 3.10+
+- `MAILCHIMP_API_KEY` environment variable set to your API key (including datacenter suffix, e.g. `abc123-us8`)
+
+## Installation
+
+```bash
+# From the CLI-Anything repo (once merged):
+pip install git+https://github.com/HKUDS/CLI-Anything.git#subdirectory=mailchimp/agent-harness
+
+# During development:
+cd mailchimp/agent-harness && pip install -e .
+```
+
+## Command Reference
+
+### Root
+
+| Command | Description |
+|---|---|
+| `cli-anything-mailchimp ping` | Health check โ confirms API connectivity |
+| `cli-anything-mailchimp root list` | Get account info |
+| `cli-anything-mailchimp --json ` | Output any command as JSON |
+| `cli-anything-mailchimp` | Launch interactive REPL |
+
+### Lists (Audiences)
+
+| Command | Description |
+|---|---|
+| `lists list` | List all audiences |
+| `lists get ` | Get audience info |
+| `lists create --data ''` | Create audience |
+| `lists update --data ''` | Update audience |
+| `lists delete ` | Delete audience |
+| `lists list-lists-id-members ` | List members |
+| `lists get-lists-id-members-id ` | Get member by MD5 hash |
+| `lists create-lists-id-members --data ''` | Add member |
+| `lists list-lists-id-merge-fields ` | List merge fields |
+| `lists create-lists-id-merge-fields --data ''` | Add merge field |
+| `lists list-lists-id-segments ` | List segments |
+| `lists list-list-member-tags ` | List member tags |
+| `lists create-list-member-tags --data ''` | Add/remove member tags |
+| `lists list-lists-id-webhooks ` | List webhooks |
+| `lists create-lists-id-webhooks --data ''` | Add webhook |
+
+### Campaigns
+
+| Command | Description |
+|---|---|
+| `campaigns list` | List campaigns |
+| `campaigns get ` | Get campaign info |
+| `campaigns create --data ''` | Create campaign |
+| `campaigns update --data ''` | Update campaign settings |
+| `campaigns delete ` | Delete campaign |
+| `campaigns send ` | Send campaign immediately |
+| `campaigns schedule --data ''` | Schedule campaign |
+| `campaigns cancel-send ` | Cancel scheduled send |
+| `campaigns pause ` | Pause RSS campaign |
+| `campaigns resume ` | Resume RSS campaign |
+| `campaigns replicate ` | Duplicate campaign |
+| `campaigns list-content ` | Get campaign content |
+| `campaigns list-send-checklist ` | Pre-send checklist |
+
+### Reports
+
+| Command | Description |
+|---|---|
+| `reports list` | List all campaign reports |
+| `reports get ` | Get campaign summary report |
+| `reports list-email-activity ` | Per-subscriber open/click activity |
+| `reports list-click-details ` | Link click breakdown |
+| `reports list-open-details ` | Per-subscriber opens |
+| `reports list-unsubscribed ` | Unsubscribers |
+| `reports list-locations ` | Geographic breakdown |
+| `reports list-domain-performance ` | Per-domain stats |
+
+### Automations
+
+| Command | Description |
+|---|---|
+| `automations list` | List automations |
+| `automations get ` | Get automation info |
+| `automations create --data ''` | Create automation |
+| `automations pause ` | Pause automation |
+| `automations start ` | Start automation |
+| `automations archive ` | Archive automation |
+| `automations list-emails ` | List automation emails |
+
+### E-commerce
+
+| Command | Description |
+|---|---|
+| `ecommerce list-ecommerce-stores` | List stores |
+| `ecommerce get ` | Get store info |
+| `ecommerce create --data ''` | Add store |
+| `ecommerce list-ecommerce-stores-id-orders ` | List orders |
+| `ecommerce list-ecommerce-stores-id-products ` | List products |
+| `ecommerce list-ecommerce-stores-id-customers ` | List customers |
+| `ecommerce list-ecommerce-stores-id-carts ` | List carts |
+| `ecommerce list-ecommerce-stores-id-promocodes ` | List promo codes |
+
+### Other Resources
+
+| Group | Description |
+|---|---|
+| `templates` | Email templates (list, get, create, update, delete) |
+| `template-folders` | Template folders |
+| `campaign-folders` | Campaign folders |
+| `file-manager` | Files and folders in the file manager |
+| `landing-pages` | Landing pages (list, create, publish, unpublish) |
+| `sms-campaigns` | SMS campaigns (10 operations) |
+| `surveys` | Surveys (list, get, publish) |
+| `reporting` | Facebook ad and landing page reporting |
+| `search-campaigns` | Search campaigns by query |
+| `search-members` | Search members across all audiences |
+| `batches` | Batch API operations |
+| `batch-webhooks` | Batch operation webhooks |
+| `verified-domains` | Email domain verification |
+| `authorized-apps` | OAuth connected apps |
+| `connected-sites` | Connected site integrations |
+| `conversations` | Inbox conversations |
+| `activity-feed` | Account activity feed |
+| `account-exports` | Account data exports |
+
+## JSON Output
+
+All commands support `--json` at the root level:
+
+```bash
+# List all audiences as JSON
+cli-anything-mailchimp --json lists list
+
+# Get a campaign report as JSON
+cli-anything-mailchimp --json reports get abc123def
+
+# Pipe to jq โ use the native Mailchimp field name for the resource
+cli-anything-mailchimp --json lists list | jq '.lists[].name'
+cli-anything-mailchimp --json campaigns list | jq '.campaigns[].id'
+```
+
+**Envelope shapes** (native Mailchimp API response โ use the resource-specific key):
+
+```json
+// List endpoints โ key matches the resource name (lists, campaigns, members, etc.)
+{"lists": [...], "total_items": 42, "_links": [...]}
+{"campaigns": [...], "total_items": 10, "_links": [...]}
+
+// Single resource GET / POST / PATCH
+{"id": "abc123", "name": "My List", ...}
+
+// DELETE
+{"ok": true, "message": "Deleted."}
+
+// Error
+{"ok": false, "message": "Resource Not Found: ...", "data": {...}}
+```
+
+## Common Agent Patterns
+
+```bash
+# Get account health
+cli-anything-mailchimp --json ping | jq '.health_status'
+
+# List all audience IDs and names
+cli-anything-mailchimp --json lists list | jq '.lists[] | {id, name}'
+
+# Find all subscribed members in an audience
+cli-anything-mailchimp --json lists list-lists-id-members --status subscribed | jq '.members[].email_address'
+
+# Create a campaign and get its send checklist
+cli-anything-mailchimp --json campaigns create --data '{"type":"regular","settings":{"subject_line":"Hello","from_name":"Me","reply_to":"me@example.com"}}' | jq '.id'
+cli-anything-mailchimp --json campaigns list-send-checklist | jq '.items[] | select(.result == false)'
+
+# Get unsubscribes for a sent campaign
+cli-anything-mailchimp --json reports list-unsubscribed | jq '.unsubscribes[].email_address'
+
+# Add a member to an audience (subscriber hash = MD5 of lowercased email)
+cli-anything-mailchimp --json lists create-members --data '{"email_address":"user@example.com","status":"subscribed"}'
+
+# Search for a member across all audiences
+cli-anything-mailchimp --json search-members list --query "user@example.com" | jq '.exact_matches.members[]'
+```
+
+## Interactive REPL
+
+Run `cli-anything-mailchimp` with no arguments to enter the REPL:
+
+```
+โ cli-anything ยท Mailchimp
+ v0.1.0
+ Type help for commands, quit to exit
+
+โ mailchimp โฏ ping
+ โ {"health_status": "Everything's Chimpy!"}
+
+โ mailchimp โฏ --json lists list
+{"lists": [...], "total_items": 3, "_links": [...]}
+
+โ mailchimp โฏ quit
+```
+
+## Notes
+
+- **Subscriber hash**: Mailchimp identifies members by the MD5 hash of their lowercased email. Compute with `python -c "import hashlib; email='email@example.com'; print(hashlib.md5(email.strip().lower().encode()).hexdigest())"`.
+- **Body payloads**: All POST/PATCH/PUT commands accept `--data ''`. See [Mailchimp API docs](https://mailchimp.com/developer/marketing/api/) for the schema of each endpoint.
+- **Datacenter**: Your API key ends in `-us8`, `-eu2`, etc. The CLI extracts this automatically โ include it in `MAILCHIMP_API_KEY`.
+- **Rate limits**: The Marketing API rate-limits at 10 concurrent connections and a rolling per-account limit. For bulk operations, use the `batches` group.