deepflow-opendesk-cli 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/PKG-INFO +5 -1
  2. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/README.md +4 -0
  3. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/pyproject.toml +1 -1
  4. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/setup.py +1 -1
  5. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/__init__.py +1 -1
  6. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/cli.py +76 -0
  7. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/schema.py +9 -0
  8. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli.egg-info/PKG-INFO +5 -1
  9. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/tests/test_cli.py +44 -0
  10. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/tests/test_schema.py +47 -0
  11. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/setup.cfg +0 -0
  12. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/__main__.py +0 -0
  13. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/batch.py +0 -0
  14. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/client.py +0 -0
  15. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/profiles.py +0 -0
  16. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli/workflows.py +0 -0
  17. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli.egg-info/SOURCES.txt +0 -0
  18. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli.egg-info/dependency_links.txt +0 -0
  19. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli.egg-info/entry_points.txt +0 -0
  20. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli.egg-info/requires.txt +0 -0
  21. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/src/deepflow_opendesk_cli.egg-info/top_level.txt +0 -0
  22. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/tests/test_client.py +0 -0
  23. {deepflow_opendesk_cli-0.1.0 → deepflow_opendesk_cli-0.1.2}/tests/test_profiles.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepflow-opendesk-cli
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Command-line client for OpenDesk admin configuration APIs.
5
5
  Author: DeepFlow AI
6
6
  Project-URL: Repository, https://github.com/DeepFlowAI/opendesk-dev
@@ -41,6 +41,7 @@ Included examples:
41
41
  - Satisfaction and welcome-message settings
42
42
  - Voice flows, ticket workflows, inbound/session routing rules
43
43
  - Queue policies
44
+ - Outbound task templates and outbound scripts
44
45
  - Optional tenant, SIP trunk, and phone-number configuration endpoints when extensions are loaded
45
46
 
46
47
  ## Install For Development
@@ -85,6 +86,9 @@ deepflow_opendesk_cli employees list
85
86
  deepflow_opendesk_cli channels list
86
87
  deepflow_opendesk_cli routing session list
87
88
  deepflow_opendesk_cli queue policies
89
+ deepflow_opendesk_cli outbound-templates list
90
+ deepflow_opendesk_cli outbound-templates get-script 12
91
+ deepflow_opendesk_cli outbound-templates set-script 12 --json-file script.json
88
92
  ```
89
93
 
90
94
  Equivalent module invocation:
@@ -19,6 +19,7 @@ Included examples:
19
19
  - Satisfaction and welcome-message settings
20
20
  - Voice flows, ticket workflows, inbound/session routing rules
21
21
  - Queue policies
22
+ - Outbound task templates and outbound scripts
22
23
  - Optional tenant, SIP trunk, and phone-number configuration endpoints when extensions are loaded
23
24
 
24
25
  ## Install For Development
@@ -63,6 +64,9 @@ deepflow_opendesk_cli employees list
63
64
  deepflow_opendesk_cli channels list
64
65
  deepflow_opendesk_cli routing session list
65
66
  deepflow_opendesk_cli queue policies
67
+ deepflow_opendesk_cli outbound-templates list
68
+ deepflow_opendesk_cli outbound-templates get-script 12
69
+ deepflow_opendesk_cli outbound-templates set-script 12 --json-file script.json
66
70
  ```
67
71
 
68
72
  Equivalent module invocation:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deepflow-opendesk-cli"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Command-line client for OpenDesk admin configuration APIs."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -7,7 +7,7 @@ from setuptools import find_packages, setup
7
7
 
8
8
  setup(
9
9
  name="deepflow-opendesk-cli",
10
- version="0.1.0",
10
+ version="0.1.2",
11
11
  description="Command-line client for OpenDesk admin configuration APIs.",
12
12
  long_description=Path("README.md").read_text(encoding="utf-8"),
13
13
  long_description_content_type="text/markdown",
@@ -1,3 +1,3 @@
1
1
  """OpenDesk admin configuration API CLI."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.2"
@@ -107,6 +107,7 @@ def build_parser() -> argparse.ArgumentParser:
107
107
  add_queue_parser(subparsers)
108
108
  add_voice_flows_parser(subparsers)
109
109
  add_ticket_workflows_parser(subparsers)
110
+ add_outbound_templates_parser(subparsers)
110
111
 
111
112
  batch = subparsers.add_parser("batch", help="Run JSONL configuration operations.")
112
113
  batch_sub = batch.add_subparsers(dest="batch_action", required=True)
@@ -272,6 +273,34 @@ def add_ticket_workflows_parser(subparsers: argparse._SubParsersAction[argparse.
272
273
  workflows.set_defaults(handler=handle_ticket_workflows)
273
274
 
274
275
 
276
+ def add_outbound_templates_parser(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
277
+ templates = subparsers.add_parser(
278
+ "outbound-templates",
279
+ help="Outbound task template and outbound script commands.",
280
+ )
281
+ templates_sub = templates.add_subparsers(dest="outbound_templates_action", required=True)
282
+ list_cmd = templates_sub.add_parser("list")
283
+ list_cmd.add_argument("--q", help="Filter templates by name.")
284
+ list_cmd.add_argument("--page", type=int, default=1)
285
+ list_cmd.add_argument("--per-page", type=int, default=20)
286
+ get_cmd = templates_sub.add_parser("get")
287
+ get_cmd.add_argument("template_id", type=int)
288
+ create_cmd = templates_sub.add_parser("create")
289
+ add_json_args(create_cmd)
290
+ update_cmd = templates_sub.add_parser("update")
291
+ update_cmd.add_argument("template_id", type=int)
292
+ add_json_args(update_cmd)
293
+ delete_cmd = templates_sub.add_parser("delete")
294
+ delete_cmd.add_argument("template_id", type=int)
295
+ delete_cmd.add_argument("--yes", action="store_true", help="Confirm destructive delete.")
296
+ get_script = templates_sub.add_parser("get-script")
297
+ get_script.add_argument("template_id", type=int)
298
+ set_script = templates_sub.add_parser("set-script")
299
+ set_script.add_argument("template_id", type=int)
300
+ add_json_args(set_script)
301
+ templates.set_defaults(handler=handle_outbound_templates)
302
+
303
+
275
304
  def handle_schema(args: argparse.Namespace) -> int:
276
305
  """Handle schema commands."""
277
306
  if args.schema_action == "fetch":
@@ -465,6 +494,53 @@ def handle_ticket_workflows(args: argparse.Namespace) -> int:
465
494
  return simple_request(args, "GET", "/api/v1/ticket-workflows")
466
495
 
467
496
 
497
+ def handle_outbound_templates(args: argparse.Namespace) -> int:
498
+ """Handle outbound task template and script commands."""
499
+ action = args.outbound_templates_action
500
+ if action == "list":
501
+ query: dict[str, Any] = {"page": args.page, "per_page": args.per_page}
502
+ if args.q:
503
+ query["q"] = args.q
504
+ return simple_request(args, "GET", "/api/v1/engagement/outbound-task-templates", query=query)
505
+ if action == "get":
506
+ return simple_request(
507
+ args, "GET", f"/api/v1/engagement/outbound-task-templates/{args.template_id}"
508
+ )
509
+ if action == "create":
510
+ return simple_request(
511
+ args, "POST", "/api/v1/engagement/outbound-task-templates", body=optional_payload(args)
512
+ )
513
+ if action == "update":
514
+ return simple_request(
515
+ args,
516
+ "PUT",
517
+ f"/api/v1/engagement/outbound-task-templates/{args.template_id}",
518
+ body=optional_payload(args),
519
+ )
520
+ if action == "delete":
521
+ result = execute_request(
522
+ args,
523
+ "DELETE",
524
+ f"/api/v1/engagement/outbound-task-templates/{args.template_id}",
525
+ yes=bool(args.yes),
526
+ )
527
+ return finish_http(args, result)
528
+ if action == "get-script":
529
+ return simple_request(
530
+ args,
531
+ "GET",
532
+ f"/api/v1/engagement/outbound-task-templates/{args.template_id}/script",
533
+ )
534
+ if action == "set-script":
535
+ return simple_request(
536
+ args,
537
+ "PUT",
538
+ f"/api/v1/engagement/outbound-task-templates/{args.template_id}/script",
539
+ body=optional_payload(args),
540
+ )
541
+ raise CliError(f"Unknown outbound-templates action: {action}")
542
+
543
+
468
544
  def handle_batch(args: argparse.Namespace) -> int:
469
545
  """Handle batch commands."""
470
546
  operations = load_jsonl(args.file)
@@ -49,6 +49,8 @@ INCLUDE_PATHS = (
49
49
  "/api/v1/upload/channel-logo",
50
50
  "/api/v1/upload/channel-favicon",
51
51
  "/api/v1/call-center/phone-numbers*",
52
+ "/api/v1/engagement/outbound-task-templates",
53
+ "/api/v1/engagement/outbound-task-templates/*",
52
54
  )
53
55
 
54
56
  EXCLUDE_PATHS = (
@@ -94,6 +96,13 @@ CURATED_ALIASES: dict[tuple[str, str], str] = {
94
96
  ("GET", "/api/v1/queue/policies"): "queue.policies",
95
97
  ("GET", "/api/v1/voice-flows"): "voice_flows.list",
96
98
  ("GET", "/api/v1/ticket-workflows"): "ticket_workflows.list",
99
+ ("GET", "/api/v1/engagement/outbound-task-templates"): "outbound_templates.list",
100
+ ("POST", "/api/v1/engagement/outbound-task-templates"): "outbound_templates.create",
101
+ ("GET", "/api/v1/engagement/outbound-task-templates/{template_id}"): "outbound_templates.get",
102
+ ("PUT", "/api/v1/engagement/outbound-task-templates/{template_id}"): "outbound_templates.update",
103
+ ("DELETE", "/api/v1/engagement/outbound-task-templates/{template_id}"): "outbound_templates.delete",
104
+ ("GET", "/api/v1/engagement/outbound-task-templates/{template_id}/script"): "outbound_templates.get_script",
105
+ ("PUT", "/api/v1/engagement/outbound-task-templates/{template_id}/script"): "outbound_templates.set_script",
97
106
  }
98
107
 
99
108
  HTTP_METHODS = {"GET", "POST", "PUT", "PATCH", "DELETE"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepflow-opendesk-cli
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Command-line client for OpenDesk admin configuration APIs.
5
5
  Author: DeepFlow AI
6
6
  Project-URL: Repository, https://github.com/DeepFlowAI/opendesk-dev
@@ -41,6 +41,7 @@ Included examples:
41
41
  - Satisfaction and welcome-message settings
42
42
  - Voice flows, ticket workflows, inbound/session routing rules
43
43
  - Queue policies
44
+ - Outbound task templates and outbound scripts
44
45
  - Optional tenant, SIP trunk, and phone-number configuration endpoints when extensions are loaded
45
46
 
46
47
  ## Install For Development
@@ -85,6 +86,9 @@ deepflow_opendesk_cli employees list
85
86
  deepflow_opendesk_cli channels list
86
87
  deepflow_opendesk_cli routing session list
87
88
  deepflow_opendesk_cli queue policies
89
+ deepflow_opendesk_cli outbound-templates list
90
+ deepflow_opendesk_cli outbound-templates get-script 12
91
+ deepflow_opendesk_cli outbound-templates set-script 12 --json-file script.json
88
92
  ```
89
93
 
90
94
  Equivalent module invocation:
@@ -108,3 +108,47 @@ def test_auth_login_saves_profile(monkeypatch, capsys, tmp_path) -> None:
108
108
  assert json.loads(captured.out)["data"]["access_token"] == "token-1"
109
109
  saved = json.loads((tmp_path / "default" / "profile.json").read_text(encoding="utf-8"))
110
110
  assert saved["token"] == "token-1"
111
+
112
+
113
+ def test_outbound_templates_get_script(monkeypatch, capsys) -> None:
114
+ calls = []
115
+
116
+ def fake_request(self, method, path, **kwargs):
117
+ calls.append((method, path, kwargs))
118
+ return HttpResult(
119
+ ok=True,
120
+ status=200,
121
+ method=method,
122
+ path=path,
123
+ url="http://test",
124
+ data={"template_id": 12, "has_script": True, "script": {"version": 1, "nodes": []}},
125
+ )
126
+
127
+ monkeypatch.setattr(OpenDeskClient, "request", fake_request)
128
+
129
+ exit_code = main(["outbound-templates", "get-script", "12"])
130
+
131
+ captured = capsys.readouterr()
132
+ assert exit_code == 0
133
+ assert json.loads(captured.out)["data"]["template_id"] == 12
134
+ assert calls[0][0] == "GET"
135
+ assert calls[0][1] == "/api/v1/engagement/outbound-task-templates/12/script"
136
+
137
+
138
+ def test_outbound_templates_set_script(monkeypatch, capsys, tmp_path) -> None:
139
+ calls = []
140
+ script_file = tmp_path / "script.json"
141
+ script_file.write_text(json.dumps({"script": {"version": 1, "nodes": [{"id": "start", "type": "start", "title": "开始"}]}}), encoding="utf-8")
142
+
143
+ def fake_request(self, method, path, **kwargs):
144
+ calls.append((method, path, kwargs))
145
+ return HttpResult(ok=True, status=200, method=method, path=path, url="http://test", data={"ok": True})
146
+
147
+ monkeypatch.setattr(OpenDeskClient, "request", fake_request)
148
+
149
+ exit_code = main(["outbound-templates", "set-script", "12", "--json-file", str(script_file)])
150
+
151
+ assert exit_code == 0
152
+ assert calls[0][0] == "PUT"
153
+ assert calls[0][1] == "/api/v1/engagement/outbound-task-templates/12/script"
154
+ assert calls[0][2]["body"]["script"]["version"] == 1
@@ -71,6 +71,48 @@ SAMPLE_SCHEMA = {
71
71
  "responses": {"200": {"content": {"application/json": {"schema": {"type": "object"}}}}},
72
72
  }
73
73
  },
74
+ "/api/v1/engagement/outbound-task-templates": {
75
+ "get": {
76
+ "tags": ["Engagement"],
77
+ "operationId": "list_outbound_task_templates_api_v1_engagement_outbound_task_templates_get",
78
+ "summary": "List Outbound Task Templates",
79
+ "responses": {"200": {"content": {"application/json": {"schema": {"type": "object"}}}}},
80
+ },
81
+ "post": {
82
+ "tags": ["Engagement"],
83
+ "operationId": "create_outbound_task_template_api_v1_engagement_outbound_task_templates_post",
84
+ "summary": "Create Outbound Task Template",
85
+ "responses": {"201": {"content": {"application/json": {"schema": {"type": "object"}}}}},
86
+ },
87
+ },
88
+ "/api/v1/engagement/outbound-task-templates/{template_id}/script": {
89
+ "get": {
90
+ "tags": ["Engagement"],
91
+ "operationId": "get_outbound_task_template_script_api_v1_engagement_outbound_task_templates__template_id__script_get",
92
+ "summary": "Get Outbound Task Template Script",
93
+ "parameters": [
94
+ {"name": "template_id", "in": "path", "required": True, "schema": {"type": "integer"}}
95
+ ],
96
+ "responses": {"200": {"content": {"application/json": {"schema": {"type": "object"}}}}},
97
+ },
98
+ "put": {
99
+ "tags": ["Engagement"],
100
+ "operationId": "update_outbound_task_template_script_api_v1_engagement_outbound_task_templates__template_id__script_put",
101
+ "summary": "Update Outbound Task Template Script",
102
+ "parameters": [
103
+ {"name": "template_id", "in": "path", "required": True, "schema": {"type": "integer"}}
104
+ ],
105
+ "responses": {"200": {"content": {"application/json": {"schema": {"type": "object"}}}}},
106
+ },
107
+ },
108
+ "/api/v1/engagement/outbound-tasks": {
109
+ "get": {
110
+ "tags": ["Engagement"],
111
+ "operationId": "list_outbound_tasks_api_v1_engagement_outbound_tasks_get",
112
+ "summary": "List Outbound Tasks",
113
+ "responses": {"200": {"content": {"application/json": {"schema": {"type": "object"}}}}},
114
+ }
115
+ },
74
116
  },
75
117
  }
76
118
 
@@ -83,8 +125,13 @@ def test_build_catalog_filters_to_admin_config_endpoints() -> None:
83
125
  assert "fields.list" in keys
84
126
  assert "fields.create" in keys
85
127
  assert "queue.policies" in keys
128
+ assert "outbound_templates.list" in keys
129
+ assert "outbound_templates.create" in keys
130
+ assert "outbound_templates.get_script" in keys
131
+ assert "outbound_templates.set_script" in keys
86
132
  assert "tickets.query" not in keys
87
133
  assert all(endpoint.path != "/api/v1/queue/state" for endpoint in catalog)
134
+ assert all(endpoint.path != "/api/v1/engagement/outbound-tasks" for endpoint in catalog)
88
135
 
89
136
 
90
137
  def test_get_endpoint_accepts_key_and_operation_id() -> None: