n8n-nodes-soniox-api 0.2.0
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.
- package/LICENSE +21 -0
- package/README.md +196 -0
- package/dist/credentials/SonioxApi.credentials.d.ts +10 -0
- package/dist/credentials/SonioxApi.credentials.js +45 -0
- package/dist/credentials/soniox.svg +11 -0
- package/dist/nodes/Soniox/GenericFunctions.d.ts +3 -0
- package/dist/nodes/Soniox/GenericFunctions.js +77 -0
- package/dist/nodes/Soniox/Soniox.node.d.ts +5 -0
- package/dist/nodes/Soniox/Soniox.node.js +207 -0
- package/dist/nodes/Soniox/constants.d.ts +48 -0
- package/dist/nodes/Soniox/constants.js +51 -0
- package/dist/nodes/Soniox/descriptions/FileDescription.d.ts +3 -0
- package/dist/nodes/Soniox/descriptions/FileDescription.js +121 -0
- package/dist/nodes/Soniox/descriptions/ModelDescription.d.ts +3 -0
- package/dist/nodes/Soniox/descriptions/ModelDescription.js +26 -0
- package/dist/nodes/Soniox/descriptions/TranscriptionDescription.d.ts +3 -0
- package/dist/nodes/Soniox/descriptions/TranscriptionDescription.js +152 -0
- package/dist/nodes/Soniox/soniox.svg +11 -0
- package/index.js +2 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Konstantin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# n8n-nodes-soniox-api
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/n8n-nodes-soniox-api)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://docs.n8n.io/integrations/community-nodes/)
|
|
6
|
+
|
|
7
|
+
This is an n8n community node that integrates [Soniox Speech-to-Text API](https://soniox.com/) — a high-accuracy speech recognition system.
|
|
8
|
+
|
|
9
|
+
[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.
|
|
10
|
+
|
|
11
|
+
[Installation](#installation) ·
|
|
12
|
+
[Operations](#operations) ·
|
|
13
|
+
[Credentials](#credentials) ·
|
|
14
|
+
[Usage](#usage) ·
|
|
15
|
+
[Resources](#resources)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### n8n Community Nodes
|
|
20
|
+
|
|
21
|
+
1. Go to **Settings → Community Nodes** in your n8n instance
|
|
22
|
+
2. Click **Install** and enter: `n8n-nodes-soniox-api`
|
|
23
|
+
3. Click **Install**
|
|
24
|
+
4. Restart n8n to load the node
|
|
25
|
+
|
|
26
|
+
### Manual Installation
|
|
27
|
+
|
|
28
|
+
To get started locally, install the node in your n8n root directory:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd ~/.n8n
|
|
32
|
+
npm install n8n-nodes-soniox-api
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For Docker-based n8n installations, add the package to your n8n installation:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
docker exec -it n8n npm install n8n-nodes-soniox-api
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Development
|
|
42
|
+
|
|
43
|
+
For local development and testing:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git clone https://github.com/mazixs/n8n-nodes-soniox-api.git
|
|
47
|
+
cd n8n-nodes-soniox-api
|
|
48
|
+
npm install
|
|
49
|
+
npm run build
|
|
50
|
+
npm link
|
|
51
|
+
|
|
52
|
+
# Link to your n8n installation
|
|
53
|
+
cd ~/.n8n
|
|
54
|
+
npm link n8n-nodes-soniox-api
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Operations
|
|
58
|
+
|
|
59
|
+
This node supports the following operations:
|
|
60
|
+
|
|
61
|
+
### File Operations
|
|
62
|
+
- **Upload** — Upload audio files (multipart/form-data support)
|
|
63
|
+
- **Get** — Retrieve file by ID
|
|
64
|
+
- **Get All** — List all files (with pagination)
|
|
65
|
+
- **Delete** — Delete a file
|
|
66
|
+
|
|
67
|
+
### Transcription Operations
|
|
68
|
+
- **Create** — Create transcription with configurable parameters:
|
|
69
|
+
- Model selection
|
|
70
|
+
- Language hints
|
|
71
|
+
- Speaker diarization
|
|
72
|
+
- Non-final results
|
|
73
|
+
- **Get** — Retrieve transcription result by ID
|
|
74
|
+
- **Get All** — List all transcriptions (with pagination)
|
|
75
|
+
|
|
76
|
+
### Model Operations
|
|
77
|
+
- **Get All** — List available speech recognition models
|
|
78
|
+
|
|
79
|
+
## Credentials
|
|
80
|
+
|
|
81
|
+
### Setting up Credentials
|
|
82
|
+
|
|
83
|
+
1. In n8n, navigate to **Credentials → Add Credential → Soniox API**
|
|
84
|
+
2. Enter your credentials:
|
|
85
|
+
- **API Key**: Get your API key from [console.soniox.com](https://console.soniox.com/)
|
|
86
|
+
- **API URL**: `https://api.soniox.com/v1` (default)
|
|
87
|
+
3. Click **Save**
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
### Basic Workflow Example
|
|
92
|
+
|
|
93
|
+
Here's a simple workflow to upload an audio file and transcribe it:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
[Read Binary File]
|
|
97
|
+
↓
|
|
98
|
+
[Soniox: File Upload]
|
|
99
|
+
↓
|
|
100
|
+
[Soniox: Transcription Create]
|
|
101
|
+
↓
|
|
102
|
+
[Soniox: Transcription Get]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Node Configuration
|
|
106
|
+
|
|
107
|
+
**1. Read Binary File**
|
|
108
|
+
- Property Name: `data`
|
|
109
|
+
- File Path: `/path/to/audio.mp3`
|
|
110
|
+
|
|
111
|
+
**2. Soniox: File Upload**
|
|
112
|
+
- Resource: `File`
|
|
113
|
+
- Operation: `Upload`
|
|
114
|
+
- Binary Property: `data`
|
|
115
|
+
|
|
116
|
+
**3. Soniox: Transcription Create**
|
|
117
|
+
- Resource: `Transcription`
|
|
118
|
+
- Operation: `Create`
|
|
119
|
+
- File ID: `{{ $json.fileId }}`
|
|
120
|
+
- Model: `en_v2_lowlatency`
|
|
121
|
+
|
|
122
|
+
**4. Soniox: Transcription Get**
|
|
123
|
+
- Resource: `Transcription`
|
|
124
|
+
- Operation: `Get`
|
|
125
|
+
- Transcription ID: `{{ $json.transcriptionId }}`
|
|
126
|
+
|
|
127
|
+
## Features
|
|
128
|
+
|
|
129
|
+
- ✅ **Retry Logic** — Automatic retry with exponential backoff for failed requests
|
|
130
|
+
- ✅ **Rate Limiting** — Smart handling of 429 responses with Retry-After headers
|
|
131
|
+
- ✅ **Timeout Control** — Configurable timeouts for API and file upload operations
|
|
132
|
+
- ✅ **Type Safety** — Full TypeScript implementation with n8n-workflow types
|
|
133
|
+
- ✅ **Error Handling** — Comprehensive error messages for debugging
|
|
134
|
+
|
|
135
|
+
## Resources
|
|
136
|
+
|
|
137
|
+
- [n8n community nodes documentation](https://docs.n8n.io/integrations/community-nodes/)
|
|
138
|
+
- [Soniox API Documentation](https://soniox.com/docs/stt/api-reference)
|
|
139
|
+
- [Soniox Console](https://console.soniox.com/)
|
|
140
|
+
|
|
141
|
+
## Development
|
|
142
|
+
|
|
143
|
+
### Build
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npm install
|
|
147
|
+
npm run build
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Lint
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm run lint
|
|
154
|
+
npm run lintfix # Auto-fix issues
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Testing
|
|
158
|
+
|
|
159
|
+
Link the node to your n8n installation:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npm run build && npm link
|
|
163
|
+
cd ~/.n8n && npm link n8n-nodes-soniox-api
|
|
164
|
+
n8n start
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Then test the node in your n8n workflows.
|
|
168
|
+
|
|
169
|
+
## Version History
|
|
170
|
+
|
|
171
|
+
See [CHANGELOG.md](./CHANGELOG.md) for detailed release notes.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
[MIT](LICENSE.md)
|
|
176
|
+
|
|
177
|
+
## Contributing
|
|
178
|
+
|
|
179
|
+
Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
|
180
|
+
|
|
181
|
+
## Author
|
|
182
|
+
|
|
183
|
+
**mazix**
|
|
184
|
+
- GitHub: [@mazixs](https://github.com/mazixs)
|
|
185
|
+
- npm: [n8n-nodes-soniox-api](https://www.npmjs.com/package/n8n-nodes-soniox-api)
|
|
186
|
+
|
|
187
|
+
## Support
|
|
188
|
+
|
|
189
|
+
If you encounter issues or have questions:
|
|
190
|
+
1. Check the [documentation](./docs)
|
|
191
|
+
2. Search [existing issues](https://github.com/mazixs/n8n-nodes-soniox-api/issues)
|
|
192
|
+
3. Create a [new issue](https://github.com/mazixs/n8n-nodes-soniox-api/issues/new) if needed
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
**Made with ❤️ for the n8n community**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class SonioxApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
icon: any;
|
|
7
|
+
properties: INodeProperties[];
|
|
8
|
+
authenticate: IAuthenticateGeneric;
|
|
9
|
+
test: ICredentialTestRequest;
|
|
10
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SonioxApi = void 0;
|
|
4
|
+
class SonioxApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'sonioxApi';
|
|
7
|
+
this.displayName = 'Soniox API';
|
|
8
|
+
this.documentationUrl = 'https://soniox.com/docs/stt/get-started';
|
|
9
|
+
this.icon = 'file:soniox.svg';
|
|
10
|
+
this.properties = [
|
|
11
|
+
{
|
|
12
|
+
displayName: 'API Key',
|
|
13
|
+
name: 'apiKey',
|
|
14
|
+
type: 'string',
|
|
15
|
+
typeOptions: { password: true },
|
|
16
|
+
default: '',
|
|
17
|
+
required: true,
|
|
18
|
+
description: 'The Soniox API key for authentication',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'API URL',
|
|
22
|
+
name: 'apiUrl',
|
|
23
|
+
type: 'string',
|
|
24
|
+
default: 'https://api.soniox.com/v1',
|
|
25
|
+
description: 'The base URL for Soniox API',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
this.authenticate = {
|
|
29
|
+
type: 'generic',
|
|
30
|
+
properties: {
|
|
31
|
+
headers: {
|
|
32
|
+
'Authorization': '={{`Bearer ${$credentials.apiKey}`}}',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
this.test = {
|
|
37
|
+
request: {
|
|
38
|
+
baseURL: '={{$credentials.apiUrl}}',
|
|
39
|
+
url: '/models',
|
|
40
|
+
method: 'GET',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.SonioxApi = SonioxApi;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg viewBox="-5 -15 110 50" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<title>Soniox</title>
|
|
3
|
+
<g fill="#FFFFFF">
|
|
4
|
+
<path d="m0 14.866 2.1606-3.5214c1.8927 1.2576 3.9669 1.8995 5.6694 1.8995 1.0025 0 1.4606-0.3036 1.4606-0.8847v-0.0607c0-0.6419-0.9161-0.9194-2.6532-1.4138-3.2582-0.8587-5.8509-1.9602-5.8509-5.2995v-0.06938c0-3.5214 2.8088-5.4903 6.6114-5.4903 2.4112 0 4.9089 0.70255 6.8016 1.9342l-1.9791 3.6775c-1.7112-0.95408-3.5693-1.5352-4.8744-1.5352-0.88152 0-1.3396 0.33827-1.3396 0.79796v0.06071c0 0.64184 0.94202 0.95409 2.6792 1.4745 3.2582 0.91939 5.8509 2.0556 5.8509 5.2735v0.0607c0 3.6515-2.7137 5.551-6.741 5.551-2.7656-0.0087-5.5052-0.798-7.7955-2.4546z"/>
|
|
5
|
+
<path d="m16.135 8.7342v-0.06071c0-4.7184 3.8372-8.6735 9.1436-8.6735 5.2719 0 9.0832 3.8944 9.0832 8.6127v0.06072c0 4.7184-3.8372 8.6735-9.1437 8.6735-5.2718 0-9.0831-3.8944-9.0831-8.6128zm12.583 0v-0.06071c0-2.0209-1.4606-3.7383-3.5088-3.7383-2.1001 0-3.4483 1.6826-3.4483 3.6775v0.06072c0 2.0209 1.4605 3.7383 3.5088 3.7383 2.1087 0 3.4483-1.6827 3.4483-3.6776z"/>
|
|
6
|
+
<path d="m36.877 0.36428h5.7904v2.3332c1.063-1.3791 2.5927-2.6974 4.9348-2.6974 3.5089 0 5.609 2.3332 5.609 6.0974v10.85h-5.7905v-8.977c0-1.8041-0.942-2.7929-2.3161-2.7929-1.4001 0-2.4372 0.9801-2.4372 2.7929v8.977h-5.7904z"/>
|
|
7
|
+
<path d="m55.951 0.36426h5.7904v16.584h-5.7904z"/>
|
|
8
|
+
<path d="m64.29 8.7342v-0.06071c0-4.7184 3.8373-8.6735 9.1437-8.6735 5.2719 0 9.0832 3.8944 9.0832 8.6127v0.06072c0 4.7184-3.8372 8.6735-9.1437 8.6735-5.2719 0-9.0832-3.8944-9.0832-8.6128zm12.592 0v-0.06071c0-2.0209-1.4605-3.7383-3.5088-3.7383-2.1001 0-3.4483 1.6826-3.4483 3.6775v0.06072c0 2.0209 1.4606 3.7383 3.5088 3.7383 2.1088 0 3.4483-1.6827 3.4483-3.6776z"/>
|
|
9
|
+
<path d="m88.082 8.578-5.4533-8.2138h6.2484l2.4372 4.0765 2.4371-4.0765h6.1275l-5.4274 8.1791 5.5484 8.3959h-6.2225l-2.5582-4.2587-2.5927 4.2587h-6.0929z"/>
|
|
10
|
+
</g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { IExecuteFunctions, IHookFunctions, ILoadOptionsFunctions, IDataObject, IHttpRequestMethods } from 'n8n-workflow';
|
|
2
|
+
export declare function sonioxApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject, qs?: IDataObject, uri?: string, option?: IDataObject): Promise<any>;
|
|
3
|
+
export declare function sonioxApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject, qs?: IDataObject): Promise<any>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sonioxApiRequest = sonioxApiRequest;
|
|
4
|
+
exports.sonioxApiRequestAllItems = sonioxApiRequestAllItems;
|
|
5
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
|
+
const constants_1 = require("./constants");
|
|
7
|
+
/**
|
|
8
|
+
* Задержка с exponential backoff
|
|
9
|
+
*/
|
|
10
|
+
async function delay(attempt) {
|
|
11
|
+
const delayMs = Math.min(constants_1.RETRY_CONFIG.BASE_DELAY * Math.pow(constants_1.RETRY_CONFIG.BACKOFF_MULTIPLIER, attempt), constants_1.RETRY_CONFIG.MAX_DELAY);
|
|
12
|
+
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
13
|
+
}
|
|
14
|
+
async function sonioxApiRequest(method, endpoint, body = {}, qs = {}, uri, option = {}) {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
const credentials = await this.getCredentials('sonioxApi');
|
|
17
|
+
const options = {
|
|
18
|
+
method,
|
|
19
|
+
qs,
|
|
20
|
+
uri: uri || `${credentials.apiUrl}${endpoint}`,
|
|
21
|
+
json: true,
|
|
22
|
+
timeout: option.formData ? constants_1.TIMEOUTS.FILE_UPLOAD : constants_1.TIMEOUTS.API_REQUEST,
|
|
23
|
+
};
|
|
24
|
+
// Headers - Authorization будет добавлен через credentials.authenticate
|
|
25
|
+
options.headers = {};
|
|
26
|
+
// Handle multipart/form-data (для file upload)
|
|
27
|
+
if (option.formData) {
|
|
28
|
+
options.formData = option.formData;
|
|
29
|
+
// Content-Type устанавливается автоматически для multipart
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Обычный JSON request
|
|
33
|
+
options.body = body;
|
|
34
|
+
options.headers['Content-Type'] = constants_1.CONTENT_TYPES.JSON;
|
|
35
|
+
}
|
|
36
|
+
// Retry логика с exponential backoff
|
|
37
|
+
let lastError;
|
|
38
|
+
for (let attempt = 0; attempt <= constants_1.RETRY_CONFIG.MAX_RETRIES; attempt++) {
|
|
39
|
+
try {
|
|
40
|
+
return await this.helpers.requestWithAuthentication.call(this, 'sonioxApi', options);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
lastError = error;
|
|
44
|
+
const statusCode = error.statusCode || ((_a = error.response) === null || _a === void 0 ? void 0 : _a.statusCode);
|
|
45
|
+
// Проверяем, нужен ли retry
|
|
46
|
+
const shouldRetry = attempt < constants_1.RETRY_CONFIG.MAX_RETRIES &&
|
|
47
|
+
(constants_1.RETRYABLE_STATUS_CODES.includes(statusCode) || error.code === 'ETIMEDOUT' || error.code === 'ECONNRESET');
|
|
48
|
+
if (!shouldRetry) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
// Обработка rate limiting (429)
|
|
52
|
+
if (statusCode === 429) {
|
|
53
|
+
const retryAfter = (_b = error.response) === null || _b === void 0 ? void 0 : _b.headers['retry-after'];
|
|
54
|
+
if (retryAfter) {
|
|
55
|
+
const waitMs = parseInt(retryAfter, 10) * 1000;
|
|
56
|
+
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Exponential backoff для остальных ошибок
|
|
61
|
+
await delay(attempt);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), lastError);
|
|
65
|
+
}
|
|
66
|
+
async function sonioxApiRequestAllItems(method, endpoint, body = {}, qs = {}) {
|
|
67
|
+
const returnData = [];
|
|
68
|
+
let responseData;
|
|
69
|
+
qs.limit = constants_1.API_LIMITS.PAGINATION_LIMIT;
|
|
70
|
+
qs.offset = 0;
|
|
71
|
+
do {
|
|
72
|
+
responseData = await sonioxApiRequest.call(this, method, endpoint, body, qs);
|
|
73
|
+
returnData.push(...responseData.items);
|
|
74
|
+
qs.offset = qs.offset + qs.limit;
|
|
75
|
+
} while (responseData.items.length !== 0);
|
|
76
|
+
return returnData;
|
|
77
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Soniox = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const FileDescription_1 = require("./descriptions/FileDescription");
|
|
6
|
+
const TranscriptionDescription_1 = require("./descriptions/TranscriptionDescription");
|
|
7
|
+
const ModelDescription_1 = require("./descriptions/ModelDescription");
|
|
8
|
+
const GenericFunctions_1 = require("./GenericFunctions");
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
class Soniox {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.description = {
|
|
13
|
+
displayName: 'Soniox',
|
|
14
|
+
name: 'soniox',
|
|
15
|
+
icon: 'file:soniox.svg',
|
|
16
|
+
group: ['transform'],
|
|
17
|
+
version: 1,
|
|
18
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
19
|
+
description: 'Interact with Soniox Speech-to-Text API',
|
|
20
|
+
defaults: {
|
|
21
|
+
name: 'Soniox',
|
|
22
|
+
},
|
|
23
|
+
inputs: ['main'],
|
|
24
|
+
outputs: ['main'],
|
|
25
|
+
credentials: [
|
|
26
|
+
{
|
|
27
|
+
name: 'sonioxApi',
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
properties: [
|
|
32
|
+
{
|
|
33
|
+
displayName: 'Resource',
|
|
34
|
+
name: 'resource',
|
|
35
|
+
type: 'options',
|
|
36
|
+
noDataExpression: true,
|
|
37
|
+
options: [
|
|
38
|
+
{
|
|
39
|
+
name: 'File',
|
|
40
|
+
value: 'file',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Model',
|
|
44
|
+
value: 'model',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Transcription',
|
|
48
|
+
value: 'transcription',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
default: 'transcription',
|
|
52
|
+
},
|
|
53
|
+
...FileDescription_1.fileOperations,
|
|
54
|
+
...FileDescription_1.fileFields,
|
|
55
|
+
...TranscriptionDescription_1.transcriptionOperations,
|
|
56
|
+
...TranscriptionDescription_1.transcriptionFields,
|
|
57
|
+
...ModelDescription_1.modelOperations,
|
|
58
|
+
...ModelDescription_1.modelFields,
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async execute() {
|
|
63
|
+
const items = this.getInputData();
|
|
64
|
+
const returnData = [];
|
|
65
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
66
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
67
|
+
for (let i = 0; i < items.length; i++) {
|
|
68
|
+
try {
|
|
69
|
+
if (resource === 'file') {
|
|
70
|
+
if (operation === 'upload') {
|
|
71
|
+
// 1. Получить параметры
|
|
72
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
|
73
|
+
const fileName = this.getNodeParameter('fileName', i, '');
|
|
74
|
+
// 2. Валидация binary data
|
|
75
|
+
const itemBinary = items[i].binary;
|
|
76
|
+
if (!itemBinary) {
|
|
77
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No binary data exists on input item. Please connect a node that provides binary data.', { itemIndex: i });
|
|
78
|
+
}
|
|
79
|
+
const binaryData = itemBinary[binaryPropertyName];
|
|
80
|
+
if (!binaryData) {
|
|
81
|
+
const availableProperties = Object.keys(itemBinary);
|
|
82
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Binary property "${binaryPropertyName}" not found. Available: ${availableProperties.join(', ')}`, { itemIndex: i });
|
|
83
|
+
}
|
|
84
|
+
// 3. Получить Buffer из binary data
|
|
85
|
+
const buffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
|
|
86
|
+
// 4. Определить имя файла
|
|
87
|
+
const uploadFileName = fileName || binaryData.fileName || 'file';
|
|
88
|
+
// 5. Подготовить formData для multipart/form-data
|
|
89
|
+
const formData = {
|
|
90
|
+
file: {
|
|
91
|
+
value: buffer,
|
|
92
|
+
options: {
|
|
93
|
+
filename: uploadFileName,
|
|
94
|
+
contentType: binaryData.mimeType || constants_1.CONTENT_TYPES.BINARY,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
// 6. Upload через API
|
|
99
|
+
const response = await GenericFunctions_1.sonioxApiRequest.call(this, 'POST', '/files', {}, {}, undefined, { formData });
|
|
100
|
+
// 7. Вернуть результат
|
|
101
|
+
returnData.push({
|
|
102
|
+
json: {
|
|
103
|
+
fileId: response.file_id,
|
|
104
|
+
fileName: uploadFileName,
|
|
105
|
+
mimeType: binaryData.mimeType,
|
|
106
|
+
fileSize: binaryData.fileSize,
|
|
107
|
+
uploadedAt: new Date().toISOString(),
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else if (operation === 'get') {
|
|
112
|
+
const fileId = this.getNodeParameter('fileId', i);
|
|
113
|
+
const response = await GenericFunctions_1.sonioxApiRequest.call(this, 'GET', `/files/${fileId}`);
|
|
114
|
+
returnData.push({ json: response });
|
|
115
|
+
}
|
|
116
|
+
else if (operation === 'getAll') {
|
|
117
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
118
|
+
let responseData;
|
|
119
|
+
if (returnAll) {
|
|
120
|
+
responseData = await GenericFunctions_1.sonioxApiRequestAllItems.call(this, 'GET', '/files');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const limit = this.getNodeParameter('limit', i);
|
|
124
|
+
responseData = await GenericFunctions_1.sonioxApiRequest.call(this, 'GET', '/files', {}, { limit });
|
|
125
|
+
}
|
|
126
|
+
const fileItems = Array.isArray(responseData) ? responseData : responseData.items || [];
|
|
127
|
+
fileItems.forEach((item) => {
|
|
128
|
+
returnData.push({ json: item });
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else if (operation === 'delete') {
|
|
132
|
+
const fileId = this.getNodeParameter('fileId', i);
|
|
133
|
+
await GenericFunctions_1.sonioxApiRequest.call(this, 'DELETE', `/files/${fileId}`);
|
|
134
|
+
returnData.push({
|
|
135
|
+
json: {
|
|
136
|
+
success: true,
|
|
137
|
+
fileId,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if (resource === 'transcription') {
|
|
143
|
+
if (operation === 'create') {
|
|
144
|
+
const fileId = this.getNodeParameter('fileId', i);
|
|
145
|
+
const model = this.getNodeParameter('model', i, '');
|
|
146
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
147
|
+
const body = {
|
|
148
|
+
file_id: fileId,
|
|
149
|
+
};
|
|
150
|
+
if (model) {
|
|
151
|
+
body.model = model;
|
|
152
|
+
}
|
|
153
|
+
if (additionalFields.language) {
|
|
154
|
+
body.language = additionalFields.language;
|
|
155
|
+
}
|
|
156
|
+
if (additionalFields.enableSpeakerDiarization) {
|
|
157
|
+
body.enable_speaker_diarization = additionalFields.enableSpeakerDiarization;
|
|
158
|
+
}
|
|
159
|
+
if (additionalFields.includeNonFinal) {
|
|
160
|
+
body.include_nonfinal = additionalFields.includeNonFinal;
|
|
161
|
+
}
|
|
162
|
+
const response = await GenericFunctions_1.sonioxApiRequest.call(this, 'POST', '/transcriptions', body);
|
|
163
|
+
returnData.push({ json: response });
|
|
164
|
+
}
|
|
165
|
+
else if (operation === 'get') {
|
|
166
|
+
const transcriptionId = this.getNodeParameter('transcriptionId', i);
|
|
167
|
+
const response = await GenericFunctions_1.sonioxApiRequest.call(this, 'GET', `/transcriptions/${transcriptionId}`);
|
|
168
|
+
returnData.push({ json: response });
|
|
169
|
+
}
|
|
170
|
+
else if (operation === 'getAll') {
|
|
171
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
172
|
+
let responseData;
|
|
173
|
+
if (returnAll) {
|
|
174
|
+
responseData = await GenericFunctions_1.sonioxApiRequestAllItems.call(this, 'GET', '/transcriptions');
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
const limit = this.getNodeParameter('limit', i);
|
|
178
|
+
responseData = await GenericFunctions_1.sonioxApiRequest.call(this, 'GET', '/transcriptions', {}, { limit });
|
|
179
|
+
}
|
|
180
|
+
const transcriptionItems = Array.isArray(responseData) ? responseData : responseData.items || [];
|
|
181
|
+
transcriptionItems.forEach((item) => {
|
|
182
|
+
returnData.push({ json: item });
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (resource === 'model') {
|
|
187
|
+
if (operation === 'getAll') {
|
|
188
|
+
const response = await GenericFunctions_1.sonioxApiRequest.call(this, 'GET', '/models');
|
|
189
|
+
const models = Array.isArray(response) ? response : response.models || [];
|
|
190
|
+
models.forEach((model) => {
|
|
191
|
+
returnData.push({ json: model });
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
if (this.continueOnFail()) {
|
|
198
|
+
returnData.push({ json: { error: error.message } });
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return [returnData];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
exports.Soniox = Soniox;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Константы для Soniox API
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Лимиты API
|
|
6
|
+
*/
|
|
7
|
+
export declare const API_LIMITS: {
|
|
8
|
+
/** Максимальное количество элементов на запрос */
|
|
9
|
+
MAX_ITEMS_PER_REQUEST: number;
|
|
10
|
+
/** Количество элементов по умолчанию */
|
|
11
|
+
DEFAULT_LIMIT: number;
|
|
12
|
+
/** Лимит для пагинации */
|
|
13
|
+
PAGINATION_LIMIT: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* MIME типы
|
|
17
|
+
*/
|
|
18
|
+
export declare const CONTENT_TYPES: {
|
|
19
|
+
JSON: string;
|
|
20
|
+
BINARY: string;
|
|
21
|
+
FORM_DATA: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Настройки retry для API запросов
|
|
25
|
+
*/
|
|
26
|
+
export declare const RETRY_CONFIG: {
|
|
27
|
+
/** Максимальное количество попыток */
|
|
28
|
+
MAX_RETRIES: number;
|
|
29
|
+
/** Базовая задержка в мс */
|
|
30
|
+
BASE_DELAY: number;
|
|
31
|
+
/** Максимальная задержка в мс */
|
|
32
|
+
MAX_DELAY: number;
|
|
33
|
+
/** Множитель для exponential backoff */
|
|
34
|
+
BACKOFF_MULTIPLIER: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Таймауты
|
|
38
|
+
*/
|
|
39
|
+
export declare const TIMEOUTS: {
|
|
40
|
+
/** Таймаут для API запросов в мс */
|
|
41
|
+
API_REQUEST: number;
|
|
42
|
+
/** Таймаут для загрузки файлов в мс */
|
|
43
|
+
FILE_UPLOAD: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* HTTP коды статуса, которые требуют retry
|
|
47
|
+
*/
|
|
48
|
+
export declare const RETRYABLE_STATUS_CODES: number[];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Константы для Soniox API
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RETRYABLE_STATUS_CODES = exports.TIMEOUTS = exports.RETRY_CONFIG = exports.CONTENT_TYPES = exports.API_LIMITS = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Лимиты API
|
|
9
|
+
*/
|
|
10
|
+
exports.API_LIMITS = {
|
|
11
|
+
/** Максимальное количество элементов на запрос */
|
|
12
|
+
MAX_ITEMS_PER_REQUEST: 100,
|
|
13
|
+
/** Количество элементов по умолчанию */
|
|
14
|
+
DEFAULT_LIMIT: 50,
|
|
15
|
+
/** Лимит для пагинации */
|
|
16
|
+
PAGINATION_LIMIT: 100,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* MIME типы
|
|
20
|
+
*/
|
|
21
|
+
exports.CONTENT_TYPES = {
|
|
22
|
+
JSON: 'application/json',
|
|
23
|
+
BINARY: 'application/octet-stream',
|
|
24
|
+
FORM_DATA: 'multipart/form-data',
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Настройки retry для API запросов
|
|
28
|
+
*/
|
|
29
|
+
exports.RETRY_CONFIG = {
|
|
30
|
+
/** Максимальное количество попыток */
|
|
31
|
+
MAX_RETRIES: 3,
|
|
32
|
+
/** Базовая задержка в мс */
|
|
33
|
+
BASE_DELAY: 1000,
|
|
34
|
+
/** Максимальная задержка в мс */
|
|
35
|
+
MAX_DELAY: 10000,
|
|
36
|
+
/** Множитель для exponential backoff */
|
|
37
|
+
BACKOFF_MULTIPLIER: 2,
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Таймауты
|
|
41
|
+
*/
|
|
42
|
+
exports.TIMEOUTS = {
|
|
43
|
+
/** Таймаут для API запросов в мс */
|
|
44
|
+
API_REQUEST: 30000,
|
|
45
|
+
/** Таймаут для загрузки файлов в мс */
|
|
46
|
+
FILE_UPLOAD: 60000,
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* HTTP коды статуса, которые требуют retry
|
|
50
|
+
*/
|
|
51
|
+
exports.RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504];
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fileFields = exports.fileOperations = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
exports.fileOperations = [
|
|
6
|
+
{
|
|
7
|
+
displayName: 'Operation',
|
|
8
|
+
name: 'operation',
|
|
9
|
+
type: 'options',
|
|
10
|
+
noDataExpression: true,
|
|
11
|
+
displayOptions: {
|
|
12
|
+
show: {
|
|
13
|
+
resource: ['file'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
options: [
|
|
17
|
+
{
|
|
18
|
+
name: 'Upload',
|
|
19
|
+
value: 'upload',
|
|
20
|
+
description: 'Upload an audio file',
|
|
21
|
+
action: 'Upload a file',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Get',
|
|
25
|
+
value: 'get',
|
|
26
|
+
description: 'Get a file by ID',
|
|
27
|
+
action: 'Get a file',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Get All',
|
|
31
|
+
value: 'getAll',
|
|
32
|
+
description: 'Get all files',
|
|
33
|
+
action: 'Get all files',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Delete',
|
|
37
|
+
value: 'delete',
|
|
38
|
+
description: 'Delete a file',
|
|
39
|
+
action: 'Delete a file',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
default: 'upload',
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
exports.fileFields = [
|
|
46
|
+
// Upload operation
|
|
47
|
+
{
|
|
48
|
+
displayName: 'Binary Property',
|
|
49
|
+
name: 'binaryPropertyName',
|
|
50
|
+
type: 'string',
|
|
51
|
+
default: 'data',
|
|
52
|
+
required: true,
|
|
53
|
+
displayOptions: {
|
|
54
|
+
show: {
|
|
55
|
+
resource: ['file'],
|
|
56
|
+
operation: ['upload'],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
description: 'Name of the binary property containing the file',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
displayName: 'File Name',
|
|
63
|
+
name: 'fileName',
|
|
64
|
+
type: 'string',
|
|
65
|
+
default: '',
|
|
66
|
+
displayOptions: {
|
|
67
|
+
show: {
|
|
68
|
+
resource: ['file'],
|
|
69
|
+
operation: ['upload'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
description: 'Name of the file to upload',
|
|
73
|
+
},
|
|
74
|
+
// Get/Delete operations
|
|
75
|
+
{
|
|
76
|
+
displayName: 'File ID',
|
|
77
|
+
name: 'fileId',
|
|
78
|
+
type: 'string',
|
|
79
|
+
default: '',
|
|
80
|
+
required: true,
|
|
81
|
+
displayOptions: {
|
|
82
|
+
show: {
|
|
83
|
+
resource: ['file'],
|
|
84
|
+
operation: ['get', 'delete'],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
description: 'The ID of the file',
|
|
88
|
+
},
|
|
89
|
+
// Get All operation
|
|
90
|
+
{
|
|
91
|
+
displayName: 'Return All',
|
|
92
|
+
name: 'returnAll',
|
|
93
|
+
type: 'boolean',
|
|
94
|
+
displayOptions: {
|
|
95
|
+
show: {
|
|
96
|
+
resource: ['file'],
|
|
97
|
+
operation: ['getAll'],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
default: false,
|
|
101
|
+
description: 'Whether to return all results or only up to a given limit',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
displayName: 'Limit',
|
|
105
|
+
name: 'limit',
|
|
106
|
+
type: 'number',
|
|
107
|
+
displayOptions: {
|
|
108
|
+
show: {
|
|
109
|
+
resource: ['file'],
|
|
110
|
+
operation: ['getAll'],
|
|
111
|
+
returnAll: [false],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
typeOptions: {
|
|
115
|
+
minValue: 1,
|
|
116
|
+
maxValue: constants_1.API_LIMITS.MAX_ITEMS_PER_REQUEST,
|
|
117
|
+
},
|
|
118
|
+
default: constants_1.API_LIMITS.DEFAULT_LIMIT,
|
|
119
|
+
description: 'Max number of results to return',
|
|
120
|
+
},
|
|
121
|
+
];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modelFields = exports.modelOperations = void 0;
|
|
4
|
+
exports.modelOperations = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Operation',
|
|
7
|
+
name: 'operation',
|
|
8
|
+
type: 'options',
|
|
9
|
+
noDataExpression: true,
|
|
10
|
+
displayOptions: {
|
|
11
|
+
show: {
|
|
12
|
+
resource: ['model'],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
name: 'Get All',
|
|
18
|
+
value: 'getAll',
|
|
19
|
+
description: 'Get all available models',
|
|
20
|
+
action: 'Get all models',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
default: 'getAll',
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
exports.modelFields = [];
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transcriptionFields = exports.transcriptionOperations = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
exports.transcriptionOperations = [
|
|
6
|
+
{
|
|
7
|
+
displayName: 'Operation',
|
|
8
|
+
name: 'operation',
|
|
9
|
+
type: 'options',
|
|
10
|
+
noDataExpression: true,
|
|
11
|
+
displayOptions: {
|
|
12
|
+
show: {
|
|
13
|
+
resource: ['transcription'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
options: [
|
|
17
|
+
{
|
|
18
|
+
name: 'Create',
|
|
19
|
+
value: 'create',
|
|
20
|
+
description: 'Create a transcription',
|
|
21
|
+
action: 'Create a transcription',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Get',
|
|
25
|
+
value: 'get',
|
|
26
|
+
description: 'Get a transcription',
|
|
27
|
+
action: 'Get a transcription',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Get All',
|
|
31
|
+
value: 'getAll',
|
|
32
|
+
description: 'Get all transcriptions',
|
|
33
|
+
action: 'Get all transcriptions',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
default: 'create',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
exports.transcriptionFields = [
|
|
40
|
+
// Create operation
|
|
41
|
+
{
|
|
42
|
+
displayName: 'File ID',
|
|
43
|
+
name: 'fileId',
|
|
44
|
+
type: 'string',
|
|
45
|
+
default: '',
|
|
46
|
+
required: true,
|
|
47
|
+
displayOptions: {
|
|
48
|
+
show: {
|
|
49
|
+
resource: ['transcription'],
|
|
50
|
+
operation: ['create'],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
description: 'The ID of the file to transcribe',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
displayName: 'Model',
|
|
57
|
+
name: 'model',
|
|
58
|
+
type: 'string',
|
|
59
|
+
default: '',
|
|
60
|
+
displayOptions: {
|
|
61
|
+
show: {
|
|
62
|
+
resource: ['transcription'],
|
|
63
|
+
operation: ['create'],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
description: 'The model to use for transcription',
|
|
67
|
+
placeholder: 'e.g., en_v2_lowlatency',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
displayName: 'Additional Fields',
|
|
71
|
+
name: 'additionalFields',
|
|
72
|
+
type: 'collection',
|
|
73
|
+
placeholder: 'Add Field',
|
|
74
|
+
default: {},
|
|
75
|
+
displayOptions: {
|
|
76
|
+
show: {
|
|
77
|
+
resource: ['transcription'],
|
|
78
|
+
operation: ['create'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
options: [
|
|
82
|
+
{
|
|
83
|
+
displayName: 'Language',
|
|
84
|
+
name: 'language',
|
|
85
|
+
type: 'string',
|
|
86
|
+
default: '',
|
|
87
|
+
description: 'Language code (e.g., en, es, fr)',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
displayName: 'Enable Speaker Diarization',
|
|
91
|
+
name: 'enableSpeakerDiarization',
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
default: false,
|
|
94
|
+
description: 'Whether to enable speaker diarization',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
displayName: 'Include Non-Final',
|
|
98
|
+
name: 'includeNonFinal',
|
|
99
|
+
type: 'boolean',
|
|
100
|
+
default: false,
|
|
101
|
+
description: 'Whether to include non-final results',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
// Get operation
|
|
106
|
+
{
|
|
107
|
+
displayName: 'Transcription ID',
|
|
108
|
+
name: 'transcriptionId',
|
|
109
|
+
type: 'string',
|
|
110
|
+
default: '',
|
|
111
|
+
required: true,
|
|
112
|
+
displayOptions: {
|
|
113
|
+
show: {
|
|
114
|
+
resource: ['transcription'],
|
|
115
|
+
operation: ['get'],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
description: 'The ID of the transcription',
|
|
119
|
+
},
|
|
120
|
+
// Get All operation
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Return All',
|
|
123
|
+
name: 'returnAll',
|
|
124
|
+
type: 'boolean',
|
|
125
|
+
displayOptions: {
|
|
126
|
+
show: {
|
|
127
|
+
resource: ['transcription'],
|
|
128
|
+
operation: ['getAll'],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
default: false,
|
|
132
|
+
description: 'Whether to return all results or only up to a given limit',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
displayName: 'Limit',
|
|
136
|
+
name: 'limit',
|
|
137
|
+
type: 'number',
|
|
138
|
+
displayOptions: {
|
|
139
|
+
show: {
|
|
140
|
+
resource: ['transcription'],
|
|
141
|
+
operation: ['getAll'],
|
|
142
|
+
returnAll: [false],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
typeOptions: {
|
|
146
|
+
minValue: 1,
|
|
147
|
+
maxValue: constants_1.API_LIMITS.MAX_ITEMS_PER_REQUEST,
|
|
148
|
+
},
|
|
149
|
+
default: constants_1.API_LIMITS.DEFAULT_LIMIT,
|
|
150
|
+
description: 'Max number of results to return',
|
|
151
|
+
},
|
|
152
|
+
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg viewBox="-5 -15 110 50" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<title>Soniox</title>
|
|
3
|
+
<g fill="#FFFFFF">
|
|
4
|
+
<path d="m0 14.866 2.1606-3.5214c1.8927 1.2576 3.9669 1.8995 5.6694 1.8995 1.0025 0 1.4606-0.3036 1.4606-0.8847v-0.0607c0-0.6419-0.9161-0.9194-2.6532-1.4138-3.2582-0.8587-5.8509-1.9602-5.8509-5.2995v-0.06938c0-3.5214 2.8088-5.4903 6.6114-5.4903 2.4112 0 4.9089 0.70255 6.8016 1.9342l-1.9791 3.6775c-1.7112-0.95408-3.5693-1.5352-4.8744-1.5352-0.88152 0-1.3396 0.33827-1.3396 0.79796v0.06071c0 0.64184 0.94202 0.95409 2.6792 1.4745 3.2582 0.91939 5.8509 2.0556 5.8509 5.2735v0.0607c0 3.6515-2.7137 5.551-6.741 5.551-2.7656-0.0087-5.5052-0.798-7.7955-2.4546z"/>
|
|
5
|
+
<path d="m16.135 8.7342v-0.06071c0-4.7184 3.8372-8.6735 9.1436-8.6735 5.2719 0 9.0832 3.8944 9.0832 8.6127v0.06072c0 4.7184-3.8372 8.6735-9.1437 8.6735-5.2718 0-9.0831-3.8944-9.0831-8.6128zm12.583 0v-0.06071c0-2.0209-1.4606-3.7383-3.5088-3.7383-2.1001 0-3.4483 1.6826-3.4483 3.6775v0.06072c0 2.0209 1.4605 3.7383 3.5088 3.7383 2.1087 0 3.4483-1.6827 3.4483-3.6776z"/>
|
|
6
|
+
<path d="m36.877 0.36428h5.7904v2.3332c1.063-1.3791 2.5927-2.6974 4.9348-2.6974 3.5089 0 5.609 2.3332 5.609 6.0974v10.85h-5.7905v-8.977c0-1.8041-0.942-2.7929-2.3161-2.7929-1.4001 0-2.4372 0.9801-2.4372 2.7929v8.977h-5.7904z"/>
|
|
7
|
+
<path d="m55.951 0.36426h5.7904v16.584h-5.7904z"/>
|
|
8
|
+
<path d="m64.29 8.7342v-0.06071c0-4.7184 3.8373-8.6735 9.1437-8.6735 5.2719 0 9.0832 3.8944 9.0832 8.6127v0.06072c0 4.7184-3.8372 8.6735-9.1437 8.6735-5.2719 0-9.0832-3.8944-9.0832-8.6128zm12.592 0v-0.06071c0-2.0209-1.4605-3.7383-3.5088-3.7383-2.1001 0-3.4483 1.6826-3.4483 3.6775v0.06072c0 2.0209 1.4606 3.7383 3.5088 3.7383 2.1088 0 3.4483-1.6827 3.4483-3.6776z"/>
|
|
9
|
+
<path d="m88.082 8.578-5.4533-8.2138h6.2484l2.4372 4.0765 2.4371-4.0765h6.1275l-5.4274 8.1791 5.5484 8.3959h-6.2225l-2.5582-4.2587-2.5927 4.2587h-6.0929z"/>
|
|
10
|
+
</g>
|
|
11
|
+
</svg>
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-soniox-api",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "n8n node for Soniox Speech-to-Text API",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc && gulp build:icons",
|
|
8
|
+
"dev": "tsc --watch",
|
|
9
|
+
"lint": "eslint nodes credentials --ext .ts",
|
|
10
|
+
"lintfix": "eslint nodes credentials --ext .ts --fix",
|
|
11
|
+
"prepublishOnly": "npm run build && npm run lint"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"n8n": {
|
|
17
|
+
"n8nNodesApiVersion": 1,
|
|
18
|
+
"credentials": [
|
|
19
|
+
"dist/credentials/SonioxApi.credentials.js"
|
|
20
|
+
],
|
|
21
|
+
"nodes": [
|
|
22
|
+
"dist/nodes/Soniox/Soniox.node.js"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"n8n-community-node-package",
|
|
27
|
+
"n8n",
|
|
28
|
+
"soniox",
|
|
29
|
+
"speech-to-text",
|
|
30
|
+
"transcription",
|
|
31
|
+
"audio",
|
|
32
|
+
"voice-recognition",
|
|
33
|
+
"stt",
|
|
34
|
+
"asr",
|
|
35
|
+
"workflow-automation"
|
|
36
|
+
],
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"homepage": "https://github.com/mazixs/n8n-nodes-soniox-api",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/mazixs/n8n-nodes-soniox-api.git"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/mazixs/n8n-nodes-soniox-api/issues"
|
|
45
|
+
},
|
|
46
|
+
"author": {
|
|
47
|
+
"name": "mazix",
|
|
48
|
+
"email": "mazix@bk.ru"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.0.0",
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
53
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
54
|
+
"eslint": "^9.0.0",
|
|
55
|
+
"typescript": "^5.9.0",
|
|
56
|
+
"n8n-workflow": "^1.112.0",
|
|
57
|
+
"n8n-core": "^1.113.0",
|
|
58
|
+
"gulp": "^5.0.0"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"n8n-workflow": "*"
|
|
62
|
+
},
|
|
63
|
+
"overrides": {
|
|
64
|
+
"form-data": "^4.0.4"
|
|
65
|
+
}
|
|
66
|
+
}
|