@adobe-commerce/aio-toolkit 1.2.4 → 1.2.6
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/CHANGELOG.md +145 -0
- package/README.md +169 -0
- package/dist/aio-toolkit-cli-workflow/bin/cli.js +2048 -0
- package/dist/aio-toolkit-cli-workflow/bin/cli.js.map +1 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js +16 -0
- package/dist/aio-toolkit-cursor-context/bin/cli.js.map +1 -1
- package/dist/index.d.mts +51 -6
- package/dist/index.d.ts +51 -6
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +213 -0
- package/dist/index.mjs.map +1 -1
- package/files/cursor-context/commands/aio-toolkit-analyze-adobe-commerce-module.md +612 -0
- package/files/cursor-context/commands/aio-toolkit-create-amazon-sqs-consumer.md +445 -0
- package/files/cursor-context/commands/aio-toolkit-create-event-consumer-action.md +6 -0
- package/files/cursor-context/commands/aio-toolkit-create-graphql-action.md +21 -7
- package/files/cursor-context/commands/aio-toolkit-create-openwhisk-action.md +326 -0
- package/files/cursor-context/commands/aio-toolkit-create-runtime-action.md +15 -5
- package/files/cursor-context/commands/aio-toolkit-create-shipping-carrier.md +681 -0
- package/files/cursor-context/commands/aio-toolkit-create-webhook-action.md +22 -9
- package/files/cursor-context/rules/aio-toolkit-create-adobe-commerce-client.mdc +252 -116
- package/files/cursor-context/rules/aio-toolkit-oop-best-practices.mdc +10 -4
- package/files/cursor-context/rules/aio-toolkit-setup-new-relic-telemetry.mdc +167 -2
- package/files/cursor-context/rules/aio-toolkit-use-abdb-collection.mdc +610 -0
- package/files/cursor-context/rules/aio-toolkit-use-abdb-repository.mdc +705 -0
- package/files/cursor-context/rules/aio-toolkit-use-adobe-auth.mdc +442 -0
- package/files/cursor-context/rules/aio-toolkit-use-amazon-sqs-publish.mdc +397 -0
- package/files/cursor-context/rules/aio-toolkit-use-file-repository.mdc +502 -0
- package/files/cursor-context/rules/aio-toolkit-use-publish-event.mdc +510 -0
- package/files/cursor-context/rules/aio-toolkit-use-runtime-api-gateway-service.mdc +542 -0
- package/package.json +4 -2
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Adding Amazon SQS message publishing to Adobe I/O Runtime actions using @adobe-commerce/aio-toolkit
|
|
3
|
+
globs: '**/{actions,lib}/**/*.{ts,js}'
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Using Amazon SQS — Publish
|
|
8
|
+
|
|
9
|
+
## Trigger Conditions
|
|
10
|
+
|
|
11
|
+
This rule applies when the user wants to publish (send) messages to an Amazon SQS queue from within an existing action using any of these phrases:
|
|
12
|
+
|
|
13
|
+
- "Publish messages to SQS"
|
|
14
|
+
- "Send messages to Amazon SQS"
|
|
15
|
+
- "Queue work to SQS"
|
|
16
|
+
- "Add SQS publishing to [action-name]"
|
|
17
|
+
- "Write to SQS queue"
|
|
18
|
+
- "Push payloads to SQS"
|
|
19
|
+
- "Use AmazonSQSClient to publish"
|
|
20
|
+
- "Fan-out via SQS"
|
|
21
|
+
- "Queue [entity] for processing in SQS"
|
|
22
|
+
|
|
23
|
+
**Important**: This rule does NOT create new actions. It integrates `AmazonSQSClient.publish()` into an **existing** action only.
|
|
24
|
+
|
|
25
|
+
**Integration with Other Action Creation Rules:**
|
|
26
|
+
|
|
27
|
+
When using action creation rules (RuntimeAction, WebhookAction, EventConsumerAction, GraphQlAction, OpenwhiskAction) and the developer mentions publishing to SQS in the business logic:
|
|
28
|
+
|
|
29
|
+
- **Automatically trigger this rule** after the action is created
|
|
30
|
+
- This rule handles client construction, payload serialisation, stats checking, config wiring, and env setup
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 1: Confirm Prerequisites
|
|
35
|
+
|
|
36
|
+
Before generating code, confirm:
|
|
37
|
+
|
|
38
|
+
1. **`@adobe-commerce/aio-toolkit` installed**: `AmazonSQSClient` is exported from it — check `package.json`
|
|
39
|
+
- If NOT installed: `npm install @adobe-commerce/aio-toolkit`
|
|
40
|
+
|
|
41
|
+
2. **`@aws-sdk/client-sqs` installed** (peer dependency — required):
|
|
42
|
+
- Check `package.json` dependencies
|
|
43
|
+
- If NOT installed: `npm install @aws-sdk/client-sqs`
|
|
44
|
+
|
|
45
|
+
3. **SQS queue already exists**: `AmazonSQSClient` does not create queues. The target queue must exist in AWS before the action runs.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Step 2: Ask Clarifying Questions
|
|
50
|
+
|
|
51
|
+
Ask the following before generating any code:
|
|
52
|
+
|
|
53
|
+
1. **Which action file** should `publish()` be added to?
|
|
54
|
+
|
|
55
|
+
2. **Payload structure** — what does each message body contain?
|
|
56
|
+
- Is it a JSON object? If so, what fields?
|
|
57
|
+
- Is there a type/event discriminator field?
|
|
58
|
+
- Example: `{ type: 'order.created', data: { orderId, ... } }`
|
|
59
|
+
|
|
60
|
+
3. **FIFO queue?** — does the queue URL end in `.fifo`?
|
|
61
|
+
- If yes: ask for a `messageGroupId` (default `'default'`)
|
|
62
|
+
|
|
63
|
+
4. **Single payload or array?** — does the action publish one message at a time or build an array first then publish in bulk?
|
|
64
|
+
|
|
65
|
+
5. **Error handling preference** — what should happen when `stats.failed > 0`?
|
|
66
|
+
- Log and continue (soft failure)
|
|
67
|
+
- Return an error response (hard failure)
|
|
68
|
+
- Retry failed payloads (ask how many retries)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Step 3: Confirm Plan
|
|
73
|
+
|
|
74
|
+
Before writing code, confirm the implementation plan:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
I'll make the following changes:
|
|
78
|
+
|
|
79
|
+
1. Action file ([path/to/action/index.ts|js]):
|
|
80
|
+
- Import AmazonSQSClient from @adobe-commerce/aio-toolkit
|
|
81
|
+
- Construct sqs client from params (AWS_REGION, AWS_ACCESS_KEY_ID,
|
|
82
|
+
AWS_SECRET_ACCESS_KEY, AWS_SQS_URL)
|
|
83
|
+
- Build payloads array [JSON.stringify(...) per message]
|
|
84
|
+
- Call sqs.publish(payloads) and check stats
|
|
85
|
+
- Log stats.published / stats.failed
|
|
86
|
+
[If stats.failed > 0: log errors / return error response]
|
|
87
|
+
|
|
88
|
+
2. app.config.yaml (or ext.config.yaml / actions.config.yaml):
|
|
89
|
+
- Add AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SQS_URL inputs
|
|
90
|
+
|
|
91
|
+
3. .env:
|
|
92
|
+
- Add AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SQS_URL
|
|
93
|
+
|
|
94
|
+
Shall I proceed?
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Step 4: Generate Code
|
|
100
|
+
|
|
101
|
+
Detect language (TypeScript or JavaScript) by checking the action file extension or `tsconfig.json`. Generate in the detected language.
|
|
102
|
+
|
|
103
|
+
### A. Adding publish() to a RuntimeAction
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
const {
|
|
107
|
+
AmazonSQSClient,
|
|
108
|
+
RuntimeAction,
|
|
109
|
+
RuntimeActionResponse,
|
|
110
|
+
HttpMethod,
|
|
111
|
+
HttpStatus,
|
|
112
|
+
} = require('@adobe-commerce/aio-toolkit');
|
|
113
|
+
|
|
114
|
+
const name = '[action-name]';
|
|
115
|
+
|
|
116
|
+
exports.main = RuntimeAction.execute(
|
|
117
|
+
name,
|
|
118
|
+
[HttpMethod.POST],
|
|
119
|
+
['AWS_REGION', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_SQS_URL'],
|
|
120
|
+
['Authorization'],
|
|
121
|
+
async (params, ctx) => {
|
|
122
|
+
const { logger } = ctx;
|
|
123
|
+
|
|
124
|
+
logger.info({ message: `${name}-start` });
|
|
125
|
+
|
|
126
|
+
const sqs = new AmazonSQSClient({
|
|
127
|
+
region: params.AWS_REGION,
|
|
128
|
+
accessKeyId: params.AWS_ACCESS_KEY_ID,
|
|
129
|
+
secretAccessKey: params.AWS_SECRET_ACCESS_KEY,
|
|
130
|
+
queueUrl: params.AWS_SQS_URL,
|
|
131
|
+
// visibilityTimeout: 30, // optional — only relevant for consumers
|
|
132
|
+
// messageGroupId: 'default', // optional — FIFO queues only
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Build payloads — each string becomes one SQS message
|
|
136
|
+
const payloads = [
|
|
137
|
+
JSON.stringify({ type: '[event-type]', data: { /* your fields */ } }),
|
|
138
|
+
// ... or build an array from your business data
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
logger.info({ message: `${name}-publishing`, count: payloads.length });
|
|
142
|
+
|
|
143
|
+
const stats = await sqs.publish(payloads);
|
|
144
|
+
|
|
145
|
+
logger.info({
|
|
146
|
+
message: `${name}-published`,
|
|
147
|
+
published: stats.published,
|
|
148
|
+
failed: stats.failed,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (stats.failed > 0) {
|
|
152
|
+
logger.error({
|
|
153
|
+
message: `${name}-publish-errors`,
|
|
154
|
+
failed: stats.failed,
|
|
155
|
+
first_error: stats.errors[0]?.error?.message,
|
|
156
|
+
});
|
|
157
|
+
// Decide: return error response, or continue with partial success
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return RuntimeActionResponse.success({
|
|
161
|
+
success: true,
|
|
162
|
+
stats: { published: stats.published, failed: stats.failed },
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**TypeScript imports:**
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { AmazonSQSClient } from '@adobe-commerce/aio-toolkit';
|
|
172
|
+
import type { AmazonSQSPublishStats } from '@adobe-commerce/aio-toolkit';
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### B. Adding publish() to an EventConsumerAction (fan-out pattern)
|
|
176
|
+
|
|
177
|
+
A common pattern: receive an I/O Event, validate/transform the payload, then fan-out to SQS for downstream processing.
|
|
178
|
+
|
|
179
|
+
```javascript
|
|
180
|
+
const {
|
|
181
|
+
AmazonSQSClient,
|
|
182
|
+
EventConsumerAction,
|
|
183
|
+
} = require('@adobe-commerce/aio-toolkit');
|
|
184
|
+
|
|
185
|
+
exports.main = EventConsumerAction.execute(
|
|
186
|
+
'[action-name]',
|
|
187
|
+
['AWS_REGION', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_SQS_URL'],
|
|
188
|
+
async (params, ctx) => {
|
|
189
|
+
const { logger } = ctx;
|
|
190
|
+
|
|
191
|
+
const sqs = new AmazonSQSClient({
|
|
192
|
+
region: params.AWS_REGION,
|
|
193
|
+
accessKeyId: params.AWS_ACCESS_KEY_ID,
|
|
194
|
+
secretAccessKey: params.AWS_SECRET_ACCESS_KEY,
|
|
195
|
+
queueUrl: params.AWS_SQS_URL,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Transform I/O Event payload into SQS message(s)
|
|
199
|
+
const payload = JSON.stringify({
|
|
200
|
+
type: params.type, // I/O Event type
|
|
201
|
+
data: params.data, // I/O Event data
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const stats = await sqs.publish([payload]);
|
|
205
|
+
|
|
206
|
+
logger.info({
|
|
207
|
+
message: '[action-name]-queued',
|
|
208
|
+
published: stats.published,
|
|
209
|
+
failed: stats.failed,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if (stats.failed > 0) {
|
|
213
|
+
logger.error({
|
|
214
|
+
message: '[action-name]-queue-failed',
|
|
215
|
+
error: stats.errors[0]?.error?.message,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### C. Bulk publish (build array then publish once)
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
// Build all payloads first, then publish in one call.
|
|
226
|
+
// publish() handles the SQS 10-message batch limit automatically.
|
|
227
|
+
|
|
228
|
+
const payloads = items.map(item =>
|
|
229
|
+
JSON.stringify({ type: '[event-type]', data: item })
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
logger.info({ message: `${name}-publishing`, count: payloads.length });
|
|
233
|
+
|
|
234
|
+
const stats = await sqs.publish(payloads);
|
|
235
|
+
|
|
236
|
+
logger.info({
|
|
237
|
+
message: `${name}-complete`,
|
|
238
|
+
published: stats.published,
|
|
239
|
+
failed: stats.failed,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
if (stats.failed > 0) {
|
|
243
|
+
// Log each failed payload for investigation
|
|
244
|
+
for (const { payload, error } of stats.errors) {
|
|
245
|
+
logger.error({
|
|
246
|
+
message: `${name}-payload-failed`,
|
|
247
|
+
payload,
|
|
248
|
+
error: error instanceof Error ? error.message : String(error),
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### Step 4.1: Update Action Configuration
|
|
257
|
+
|
|
258
|
+
Add AWS credentials to the action's YAML configuration:
|
|
259
|
+
|
|
260
|
+
**In `app.config.yaml`, `ext.config.yaml`, or `actions.config.yaml`:**
|
|
261
|
+
|
|
262
|
+
```yaml
|
|
263
|
+
[action-name]:
|
|
264
|
+
function: actions/[action-name]/index.[js/ts]
|
|
265
|
+
web: 'yes'
|
|
266
|
+
runtime: nodejs:22
|
|
267
|
+
inputs:
|
|
268
|
+
LOG_LEVEL: debug
|
|
269
|
+
AWS_REGION: $AWS_REGION
|
|
270
|
+
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
|
|
271
|
+
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
|
|
272
|
+
AWS_SQS_URL: $AWS_SQS_URL
|
|
273
|
+
annotations:
|
|
274
|
+
require-adobe-auth: true
|
|
275
|
+
final: true
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Step 4.2: Add Environment Variables
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Amazon SQS
|
|
282
|
+
AWS_REGION=us-east-1
|
|
283
|
+
AWS_ACCESS_KEY_ID=your-access-key-id
|
|
284
|
+
AWS_SECRET_ACCESS_KEY=your-secret-access-key
|
|
285
|
+
AWS_SQS_URL=https://sqs.us-east-1.amazonaws.com/123456789012/your-queue-name
|
|
286
|
+
# For FIFO queues: https://sqs.us-east-1.amazonaws.com/123456789012/your-queue.fifo
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Where to find AWS credentials:**
|
|
290
|
+
1. Open [AWS IAM Console](https://console.aws.amazon.com/iam/)
|
|
291
|
+
2. Create or select an IAM user with `sqs:SendMessage` permission on the target queue
|
|
292
|
+
3. Under **Security credentials** → **Access keys** → create an access key
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Key Components
|
|
297
|
+
|
|
298
|
+
### `AmazonSQSClient` constructor
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
new AmazonSQSClient({
|
|
302
|
+
region: string, // AWS region — e.g. 'us-east-1'
|
|
303
|
+
accessKeyId: string, // IAM access key ID
|
|
304
|
+
secretAccessKey: string, // IAM secret access key
|
|
305
|
+
queueUrl: string, // full SQS queue URL
|
|
306
|
+
visibilityTimeout?: number, // default: 30s — only relevant for consumers
|
|
307
|
+
waitTimeSeconds?: number, // default: 0 — only relevant for consumers
|
|
308
|
+
messageGroupId?: string, // default: 'default' — FIFO queues only
|
|
309
|
+
})
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### `publish(payloads)` — send messages
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
async publish(payloads: string[]): Promise<PublishStats>
|
|
316
|
+
// payloads: array of raw string message bodies (JSON.stringify your objects)
|
|
317
|
+
// Returns PublishStats — NEVER throws; all failures returned in stats.errors
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**`PublishStats` shape:**
|
|
321
|
+
```javascript
|
|
322
|
+
{
|
|
323
|
+
published: number, // messages successfully accepted by SQS
|
|
324
|
+
failed: number, // messages rejected or that errored
|
|
325
|
+
errors: [
|
|
326
|
+
{ payload: string, error: Error }, // one per failure
|
|
327
|
+
...
|
|
328
|
+
]
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Key behaviours:**
|
|
333
|
+
- Automatically chunks payloads into batches of ≤10 (SQS hard limit per `SendMessageBatch`)
|
|
334
|
+
- FIFO: auto-stamps `MessageGroupId` + unique `MessageDeduplicationId` per entry when `queueUrl` ends in `.fifo`
|
|
335
|
+
- Never throws — check `stats.failed > 0` after every call
|
|
336
|
+
|
|
337
|
+
### Exports
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
const { AmazonSQSClient } = require('@adobe-commerce/aio-toolkit');
|
|
341
|
+
|
|
342
|
+
// TypeScript only
|
|
343
|
+
import type {
|
|
344
|
+
AmazonSQSConfig,
|
|
345
|
+
AmazonSQSPublishStats,
|
|
346
|
+
} from '@adobe-commerce/aio-toolkit';
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Important Notes
|
|
352
|
+
|
|
353
|
+
1. **`publish()` never throws**: All failures — including network/transport errors — are returned in `stats.errors`. Always check `stats.failed > 0` after calling publish.
|
|
354
|
+
2. **Payloads must be strings**: Serialize objects with `JSON.stringify()` before passing to `publish()`. The consumer is responsible for `JSON.parse()`.
|
|
355
|
+
3. **Batching is automatic**: Pass the full array at once — `publish()` handles the SQS 10-per-batch constraint internally. Do not pre-chunk manually.
|
|
356
|
+
4. **FIFO deduplication is automatic**: Each entry gets a unique `MessageDeduplicationId` (randomUUID). No extra config needed — just use a `.fifo` queue URL.
|
|
357
|
+
5. **`@aws-sdk/client-sqs` is a required peer dep**: Must be installed separately — it is not bundled with `@adobe-commerce/aio-toolkit`.
|
|
358
|
+
6. **Queue must exist**: `AmazonSQSClient` never creates queues. Ensure the queue exists in AWS before deploying.
|
|
359
|
+
7. **IAM permissions required**: The IAM user must have `sqs:SendMessage` (and `sqs:SendMessageBatch`) on the target queue.
|
|
360
|
+
8. **Works with any action type**: RuntimeAction, WebhookAction, EventConsumerAction, GraphQlAction, OpenwhiskAction.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Related Rules
|
|
365
|
+
|
|
366
|
+
- **"Create Amazon SQS Consumer"** (`aio-toolkit-create-amazon-sqs-consumer.md`) — use when you also need to consume (pull + process) messages from the queue; creates the scheduler + worker pair
|
|
367
|
+
|
|
368
|
+
## Integration with Action Creation Rules
|
|
369
|
+
|
|
370
|
+
**This rule should be triggered when developers mention SQS message publishing during action creation:**
|
|
371
|
+
|
|
372
|
+
### Trigger Patterns in Other Rules
|
|
373
|
+
|
|
374
|
+
When developers mention these phrases during action creation:
|
|
375
|
+
|
|
376
|
+
- "Publish to SQS after processing"
|
|
377
|
+
- "Queue work to Amazon SQS"
|
|
378
|
+
- "Fan-out to SQS queue"
|
|
379
|
+
- "Send messages to SQS"
|
|
380
|
+
- Any phrase containing "SQS" + "publish"/"send"/"queue"/"write"
|
|
381
|
+
|
|
382
|
+
**Action to take:**
|
|
383
|
+
|
|
384
|
+
1. Complete the action creation first
|
|
385
|
+
2. Inform the user: "I see you need to publish messages to Amazon SQS. Let me integrate AmazonSQSClient.publish()."
|
|
386
|
+
3. Trigger/reference the "Using Amazon SQS — Publish" rule
|
|
387
|
+
4. This rule handles client construction, payload serialisation, stats checking, config wiring, and env setup
|
|
388
|
+
|
|
389
|
+
**Example Flow:**
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
User: "Create an event consumer action that receives an order.created event and queues it to SQS"
|
|
393
|
+
AI: ✓ Detected TypeScript project
|
|
394
|
+
AI: Creating EventConsumerAction... [generates .ts file]
|
|
395
|
+
AI: I see you need to publish messages to Amazon SQS. Let me integrate AmazonSQSClient.publish().
|
|
396
|
+
AI: [Adds SQS client, payload building, publish call, stats check, config inputs, and .env entries]
|
|
397
|
+
```
|