{"id":38064401,"url":"https://github.com/giubacc/chatterbox","last_synced_at":"2026-01-16T20:33:38.514Z","repository":{"id":50470096,"uuid":"519121377","full_name":"giubacc/chatterbox","owner":"giubacc","description":"write complex conversations with an endpoint","archived":false,"fork":false,"pushed_at":"2024-08-01T07:22:44.000Z","size":50,"stargazers_count":4,"open_issues_count":3,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-01T18:33:44.971Z","etag":null,"topics":["prober","rest","rest-api","s3"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giubacc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-29T07:26:29.000Z","updated_at":"2024-08-01T07:33:29.000Z","dependencies_parsed_at":"2024-04-17T08:33:05.732Z","dependency_job_id":"b854dff5-910c-416e-9af9-273a1a727f4d","html_url":"https://github.com/giubacc/chatterbox","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/giubacc/chatterbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giubacc%2Fchatterbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giubacc%2Fchatterbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giubacc%2Fchatterbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giubacc%2Fchatterbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giubacc","download_url":"https://codeload.github.com/giubacc/chatterbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giubacc%2Fchatterbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28482267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["prober","rest","rest-api","s3"],"created_at":"2026-01-16T20:33:38.429Z","updated_at":"2026-01-16T20:33:38.507Z","avatar_url":"https://github.com/giubacc.png","language":"C++","readme":"# chatterbox\n\n![License](https://img.shields.io/github/license/giubacc/chatterbox)\n![Lint](https://github.com/giubacc/chatterbox/actions/workflows/lint.yaml/badge.svg)\n![Builder Image](https://github.com/giubacc/chatterbox/actions/workflows/build-builder.yaml/badge.svg)\n![Build](https://github.com/giubacc/chatterbox/actions/workflows/build-chatterbox.yaml/badge.svg)\n\u003ch1 align=\"left\"\u003e\u003cimg alt=\"chatterbox-logo\" src=\"./assets/images/cbox-logo.png\"/\u003e\n\u003c/h1\u003e\n\nchatterbox is a tool for chatting with a REST endpoint.\n\nYou write conversations using a `yaml` formalism describing an arbitrary\ncomplex interaction between chatterbox and the endpoint.\n\nchatterbox keeps a state during the execution of a conversation so that\nyou can use the collected responses and use those to feed the\nsubsequent inputs.\n\nchatterbox could be useful to you when you have to:\n\n- Prototype RESTful protocols.\n- Quickly build a complex interaction with an endpoint.\n- Debug/test your endpoint when APIs are not available.\n\nchatterbox embeds a JavaScript interpreter: [V8](https://v8.dev/)\nso the user can benefit from scripting capabilities.\nA JavaScript context is kept during the entire conversation;\nthis allows to maintain an arbitrary state.\n\n## quick example\n\nThe following example describes a conversation against an **S3** service\nrunning on `localhost:7480`.\nThe interaction uses 3 distinct requests to realize an **object multipart\nupload** using the S3 APIs:\n\n- [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)\n- [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html)\n- [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)\n\nEvery request is authenticated using the\n[AWS Signature Version 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html).\n\n```yaml\nconversations:\n- host: localhost:7480\n  auth:\n    accessKey: test\n    secretKey: test\n  requests:\n    - method: POST\n      id: req1\n      enabled: true\n      uri: my-bucket/my-object.mp\n      queryString: uploads\n      auth: aws_v4\n    - method: PUT\n      id: req2\n      enabled: true\n      uri: my-bucket/my-object.mp\n      queryString: partNumber=1\u0026uploadId={{req1.response.body.UploadId}}\n      data: \"some-test-data-1\"\n      auth: aws_v4\n    - method: POST\n      enabled: true\n      uri: my-bucket/my-object.mp\n      queryString: format=json\u0026uploadId={{req1.response.body.UploadId}}\n      auth: aws_v4\n      data: |\n        \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n        \u003cCompleteMultipartUpload xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"\u003e\n          \u003cPart\u003e\n              \u003cETag\u003e{{req2.response.headers.ETag}}\u003c/ETag\u003e\n              \u003cPartNumber\u003e1\u003c/PartNumber\u003e\n          \u003c/Part\u003e\n        \u003c/CompleteMultipartUpload\u003e\n```\n\nThe second request is making use of the `UploadId` property\nobtained from the response's body in the first request:\n\n```yaml\nqueryString: partNumber=1\u0026uploadId={{req1.response.body.UploadId}}\n```\n\nThe syntax:\n\n```script\n{{req1.*}}\n```\n\ndenotes a path starting from the node identified with `id: req1` in the output `yaml`.\n\nAny property added in the output `yaml` during the conversation can be\nreferenced in any subsequent property using the `{{.id.*}}` syntax.\n\n## documentation\n\n- [Build instructions](docs/build.md)\n- [Usage instructions](docs/usage.md)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiubacc%2Fchatterbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiubacc%2Fchatterbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiubacc%2Fchatterbox/lists"}