{"_id":"@attunesolutions/piece-echoback","_rev":"2-d390b687c774f747f4dcf14031ec4cac","name":"@attunesolutions/piece-echoback","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@attunesolutions/piece-echoback","version":"0.0.1","_id":"@attunesolutions/piece-echoback@0.0.1","maintainers":[{"name":"sgsimpson","email":"scott@simpson.kiwi"}],"dist":{"shasum":"1ca91af18e6770c8522b7b0b81f2d9c3d98196cd","tarball":"https://registry.npmjs.org/@attunesolutions/piece-echoback/-/piece-echoback-0.0.1.tgz","fileCount":3,"integrity":"sha512-WLGiv4KU9RpqNPfzJpQnIGPcc9a9eeSIwhxnGjZEyrj6ZfOAc54Y221gHPMCJtIhWJR6+oQ9320yLydEdGPN9g==","signatures":[{"sig":"MEUCIQCaVNckrNofEahkVLJpN5cm1XGrWdOFFnUtgthiVuZLoAIgfWeMeDiLDhFa+xnbaB9o0C4iDQnZ3332CUauZRdo3Cs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":106426},"main":"./src/index.js","type":"commonjs","gitHead":"dbdb1ccc6f58535a3596f0017a495a8b6dd6d4e2","_npmUser":{"name":"sgsimpson","email":"scott@simpson.kiwi"},"_npmVersion":"10.9.4","directories":{},"_nodeVersion":"22.22.0","dependencies":{},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/piece-echoback_0.0.1_1785803633660_0.5294060652925137","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@attunesolutions/piece-echoback","version":"0.0.2","description":"Activepieces piece for the self-hosted echoback transcription service.","license":"MIT","homepage":"https://github.com/AttuneSolutions/echoback","repository":{"type":"git","url":"git+https://github.com/AttuneSolutions/activepieces.git","directory":"packages/pieces/community/echoback"},"keywords":["activepieces","activepieces-piece","transcription","whisper","voicemail"],"type":"commonjs","main":"./src/index.js","dependencies":{},"gitHead":"afca3aa4f96612d91e8d26e36a162d5cbed1e69d","_id":"@attunesolutions/piece-echoback@0.0.2","bugs":{"url":"https://github.com/AttuneSolutions/activepieces/issues"},"_nodeVersion":"24.18.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-v+Xhl+l4oxtXROshxI68WOsL1oZzLu9gxRl3ZReT7KDKMWo1FlkmKR5ssPPeBq4ZPTLfj5mqHXS7XGDaIpbLiA==","shasum":"fc6f7f3138cbbeb74afa602a2d02dc1bacb6c653","tarball":"https://registry.npmjs.org/@attunesolutions/piece-echoback/-/piece-echoback-0.0.2.tgz","fileCount":4,"unpackedSize":110533,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attunesolutions%2fpiece-echoback@0.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDgPOVeOcdKrhM7oEaeJHzs+hinfCeVBFMreVeAgdXoRAiEA1VNfI7hT6ROMmYlRYGh2ho+C5Zvib30/JHNrgY15cbU="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:9f03ba88-9a5b-4862-8f24-b7aae46c8226"}},"directories":{},"maintainers":[{"name":"sgsimpson","email":"scott@simpson.kiwi"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/piece-echoback_0.0.2_1785808529770_0.32746510168390097"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T00:33:53.370Z","modified":"2026-08-04T01:55:30.313Z","0.0.1":"2026-08-04T00:33:53.805Z","0.0.2":"2026-08-04T01:55:29.953Z"},"maintainers":[{"name":"sgsimpson","email":"scott@simpson.kiwi"}],"readme":"# @attunesolutions/piece-echoback\n\nAn [Activepieces](https://www.activepieces.com) piece that submits voicemail audio to a\nself-hosted [echoback](https://github.com/AttuneSolutions/echoback) transcription service,\npauses the flow while whisper.cpp works, and resumes it with the transcript.\n\nTranscription is asynchronous: echoback accepts the audio, returns a job id, and calls back\nwhen the text is ready. The flow run is suspended in between, so it holds no worker.\n\n## Install\n\nSelf-hosted Activepieces, as a custom piece:\n\n```bash\nnpm install @attunesolutions/piece-echoback\n```\n\nOr install it from the Activepieces admin UI (**Platform Admin → Pieces → Install piece**)\nby npm package name:\n\n```\n@attunesolutions/piece-echoback\n```\n\nRequires Activepieces `0.36.1` or later, and a reachable echoback instance.\n\n## Connection\n\n| Field | Description |\n| --- | --- |\n| Base URL | echoback's public URL, e.g. `https://echoback.example.com` |\n| API token | bearer token echoback accepts on `POST /jobs` and `GET /jobs/{id}` |\n\n## Action\n\n**Transcribe Voicemail and Wait** — runs twice:\n\n1. `BEGIN`: creates a `WEBHOOK` waitpoint, `POST`s the audio to `/jobs` with the waitpoint's\n   resume URL as `callback_url`, then pauses the run. The step's intermediate output is\n   echoback's `202` body (`job_id`, `job_ref`, `status`, `status_url`).\n2. `RESUME`: reads **only** `job_id` from the callback body, re-fetches\n   `GET /jobs/{job_id}` with the bearer token, and returns the whole job — `text`,\n   `duration_ms`, `job_ref`, timestamps.\n\nThe re-fetch is deliberate. The Activepieces resume endpoint is unauthenticated by design\n(the resume URL *is* the capability), so a leaked URL can wake the flow but cannot forge\nwhat the flow believes was said. `X-Signature` is not verified — the resume payload is\nalready-parsed JSON, so the exact signed bytes are not recoverable.\n\nStatuses `transcribed`, `done` and `callback_failed` all carry a transcript and count as\nsuccess. Anything else throws, producing a failed step that honours the flow's\n`continueOnFailure` / `retryOnFailure` settings.\n\n## Setup\n\nActivepieces side:\n\n| Setting | Value |\n| --- | --- |\n| `AP_FRONTEND_URL` | this instance's **externally reachable** URL. Left at the localhost default, echoback rejects the submission with `400 CALLBACK_HOST_NOT_ALLOWED`. The piece catches the loopback case before submitting and says so. |\n| `AP_WORKER_CONCURRENCY` | pausing releases the worker while transcribing; with the recommended `1`, that is the difference between one voicemail and every flow on the instance stalling. |\n\nEchoback side: `HOST_URL` set to its public URL, `CALLBACK_ALLOWED_HOSTS` containing the\nActivepieces host, `WEBHOOK_ATTEMPTS=8`.\n\n## Known limitations\n\n- **Loop On Items is unsupported.** Waitpoints are keyed on `(flowRunId, stepName)`, so a\n  second iteration of the same step in the same run may collide with the first. Use one\n  run (or a sub-flow) per voicemail.\n- **Stranded runs.** If echoback exhausts its ~4¼ minutes of delivery retries (i.e.\n  Activepieces was down for longer), the run stays paused until\n  `AP_PAUSED_FLOW_TIMEOUT_DAYS` expires. The transcript is still fetchable from\n  `GET /jobs/{job_id}` until echoback's retention window (default 60 minutes) closes. A\n  flow-level dead-man's switch is the only mitigation.\n- **Cross-job confusion (accepted).** Someone holding a leaked resume URL for job A who\n  also knows a valid job B can resume A's flow with `job_id: B` and get B's transcript.\n  Resume query params come from the request, so there is no trustworthy way to pin the\n  submitted job id across the pause.\n\n## License\n\nMIT\n","readmeFilename":"README.md","description":"Activepieces piece for the self-hosted echoback transcription service.","homepage":"https://github.com/AttuneSolutions/echoback","keywords":["activepieces","activepieces-piece","transcription","whisper","voicemail"],"repository":{"type":"git","url":"git+https://github.com/AttuneSolutions/activepieces.git","directory":"packages/pieces/community/echoback"},"bugs":{"url":"https://github.com/AttuneSolutions/activepieces/issues"},"license":"MIT"}