Skip to content

Shopify inventory alert via twilio sms - #60

Open
vishwajayawickrama wants to merge 2 commits into
wso2:mainfrom
vishwajayawickrama:shopify-inventory-alert-via-twilio-sms
Open

Shopify inventory alert via twilio sms#60
vishwajayawickrama wants to merge 2 commits into
wso2:mainfrom
vishwajayawickrama:shopify-inventory-alert-via-twilio-sms

Conversation

@vishwajayawickrama

@vishwajayawickrama vishwajayawickrama commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Purpose

This PR introduces a new pre-built integration — Shopify Inventory Alert via Twilio SMS — that automates low-stock notifications for Shopify store operators. When a new order is placed, the integration checks the inventory level of each ordered product variant and sends an SMS alert via Twilio if stock falls below a defined threshold, eliminating the need for manual inventory monitoring and reducing the risk of stockouts.

Reference: https://github.com/wso2-enterprise/integration-engineering/issues/73


Features

  • Real-time webhook processing — Listens for Shopify Order creation webhook events and immediately checks inventory for each ordered product variant.
  • Configurable inventory threshold — Sends SMS alerts when a variant's inventory drops below a set threshold (default: 10).
  • Per-variant cooldowns — Prevents duplicate alerts for the same product variant within a configurable time window (default: 24 hours).
  • Multi-recipient SMS delivery — Sends alerts to one or more recipient phone numbers via Twilio, with per-recipient cooldown tracking.
  • Customizable SMS template — Supports a configurable message template with placeholders: {{product.name}}, {{product.id}}, {{product.inventory}}, {{product.sku}}, {{threshold}}.
  • Zero-code deployment — All parameters (thresholds, cooldown period, recipients, credentials) are configurable without code changes, ready for Devant/Choreo deployment.

Summary by CodeRabbit

  • New Features

    • Shopify inventory monitoring with configurable polling interval, threshold, per-SKU cooldown, and optional product filtering
    • SMS alerts via Twilio to configurable recipient numbers with customizable message templates and per-recipient delivery handling
  • Documentation

    • Setup and configuration guides, schema, workflow diagram, and a comprehensive README with examples and defaults
  • Chores

    • Project manifest and ignore rules added for the new integration

@coderabbitai

coderabbitai Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new Shopify-to-Twilio inventory-alert integration: schema, config and manifest, documentation and diagram, type definitions, client initializations, core monitoring/notification functions with per-recipient cooldowns, and a main continuous polling loop that sends SMS via Twilio when inventory is low.

Changes

Cohort / File(s) Summary
Configuration & Schema
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json, ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal, ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml
Adds a JSON config schema plus Ballerina configurable declarations for Shopify and Twilio credentials, polling/threshold/filtering/message/cooldown settings, and package manifest.
Documentation & Project Files
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md, .../instructions.md, .../README.md, .../.gitignore
Adds workflow diagram, setup/instructions, README with examples/defaults, and .gitignore for build artifacts and config files.
Types
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/types.bal
Introduces data models for Shopify responses (products, variants, inventory levels) and internal models (AlertCooldown, ProductInventoryInfo, RecipientDeliveryResult).
Connections / Clients
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/connections.bal
Initializes Twilio and Shopify Admin clients from configured credentials.
Core Logic
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal
Implements product pagination, filtering, inventory checks, cooldown logic, SMS formatting, per-recipient Twilio sends, and cooldown updates; exposes helper functions used by main loop.
Runtime / Entry Point
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal
Adds public function main() implementing a continuous polling loop that calls check-and-notify(), handles errors (including HTTP 401), logs state, and sleeps between polls.
Repository Index
.github/workflows/projects.json
Registers the new project entry in the repository projects list.

Sequence Diagram

sequenceDiagram
    participant Main as Main Loop
    participant Shopify as Shopify API
    participant Cooldown as Cooldown Tracker
    participant Twilio as Twilio API

    Main->>Shopify: getShopifyProducts()
    Shopify-->>Main: products[]

    Main->>Main: filterProducts(products)
    Main->>Main: checkInventoryLevels(products)

    loop For each low-inventory item
        Main->>Cooldown: isCooldownExpired(sku)
        Cooldown-->>Main: boolean

        alt Cooldown expired
            Main->>Main: formatSmsMessage(productInfo)
            Main->>Twilio: sendInventoryAlert(message, recipients)
            Twilio-->>Main: delivery results
            Main->>Cooldown: update lastAlertTime & inventory (on success)
        else Cooldown active
            Main->>Main: skip notification
        end
    end

    Main->>Main: sleep(pollingIntervalSeconds)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 I nibble logs and watch the store,
When counts dip low I hop to the door,
A Twilio chirp, a squeaky SMS sing,
Cooldowns hush repeats — I lightly spring,
Hooray, alerts keep shelves asking for more.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete and does not follow the required template structure with all mandatory sections. Add missing sections: Goals, Approach, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests (unit and integration), Security checks, Samples, Related PRs, Migrations, Test environment, and Learning. Ensure all required sections are populated with appropriate information or marked as N/A with justification.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Shopify inventory alert via twilio sms' clearly summarizes the main feature being introduced—a new integration that sends inventory alerts via Twilio SMS.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@CLAassistant

CLAassistant commented Mar 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json`:
- Around line 5-84: Make the schema reject empty configs and unsafe values by:
1) adding "wso2" to the top-level required array and adding
"shopify_inventory_alert_via_twilio_sms" to the required array inside the "wso2"
object so the nested config must be present; 2) add "minItems": 1 to
"twilioRecipientNumbers" (symbol: twilioRecipientNumbers) so it cannot be an
empty array; 3) enforce numeric bounds by setting "minimum": 1 on
"pollingIntervalSeconds" (symbol: pollingIntervalSeconds) and "minimum": 0 on
"cooldownPeriodHours" (symbol: cooldownPeriodHours) and "inventoryThreshold"
(symbol: inventoryThreshold) as appropriate; and 4) optionally add "minItems": 1
on "productIdsToMonitor" or "collectionsToMonitor" if you require at least one
monitored item (symbols: productIdsToMonitor, collectionsToMonitor). Apply these
changes inside the existing "wso2" -> "shopify_inventory_alert_via_twilio_sms"
schema block.

In
`@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/instructions.md`:
- Around line 51-71: The public configuration lists knobs like
pollingIntervalSeconds and smsTemplate but omits the exposed
collectionsToMonitor setting; either add a documented entry for
collectionsToMonitor in the "Additional Configurations" section (describe type:
array of Shopify collection IDs, default behavior when empty, example format,
and how it interacts with productIdsToMonitor/cooldownPeriodHours) or remove
collectionsToMonitor from the public config schema so it is not exposed; update
the instructions.md entry accordingly and ensure examples/reference to
collectionsToMonitor are consistent with the existing placeholders and behavior.

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal`:
- Around line 20-21: The configurable collectionsToMonitor is declared but
unused; either remove it or implement its filtering in the product-selection
flow in functions.bal: update the product-fetching/filtering logic (the routine
that currently filters by productIdsToMonitor) to also check each product's
collection membership against collectionsToMonitor (match by collection ID or
handle/name as returned by the Shopify API) and only include products that
satisfy productIdsToMonitor OR belong to one of the configured collections; if
you choose to remove it, delete the configurable and any docs referencing it to
avoid misleading users.

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal`:
- Around line 65-81: The map key productKey used for lowInventoryProducts must
be a stable unique identifier instead of skuValue/productTitle to avoid
overwrites; change productKey to use variant.id (or variant.inventory_item_id if
available) as the key and keep skuValue, productTitle, and variantTitle only
inside the value object; update the code paths that set productKey and the
lowInventoryProducts assignment (referencing productKey, lowInventoryProducts,
variant.id, variant.inventory_item_id, skuValue) so each variant gets its own
unique entry and cooldown slot.
- Around line 123-134: The sendInventoryAlert function currently uses check
inside the foreach and will abort on the first failed
twilioClient->createMessage, causing partial deliveries and duplicate retries in
checkAndNotifyInventory; modify sendInventoryAlert to not fail-fast: iterate
twilioRecipientNumbers, call twilioClient->createMessage without using check,
collect per-recipient results (success/failure and error details) into a return
structure (e.g., a map or array of records keyed by recipient), and return that
to the caller so checkAndNotifyInventory can record cooldown/delivery state per
recipient or retry only failed recipients; reference sendInventoryAlert,
twilioClient->createMessage, twilioRecipientNumbers and checkAndNotifyInventory
when implementing this change.
- Around line 7-14: The getShopifyProducts() implementation only calls
adminClient->getProducts() once and misses subsequent pages; update
getShopifyProducts to paginate using the 'limit and 'sinceId query params on
adminClient->getProducts(), looping (e.g., request pages with limit up to 250)
until a page returns no products, accumulating each admin:Product[] into a
single result array, and use the last product's id as sinceId for the next
request; ensure the function returns the combined Product[] or error and
preserves the existing error handling around adminClient->getProducts().

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal`:
- Around line 4-5: The cooldownTracker map<AlertCooldown> is process-local so
restarts or multiple replicas break dedupe; replace or back it with a
persistent/shared store (e.g., Redis, DB, or other external KV) and update the
code paths that read/write cooldownTracker to use that store (or alternatively
enforce single-replica deployment); specifically refactor accesses to
cooldownTracker and any functions that read/modify AlertCooldown so they perform
atomic get/set (or TTL-based set) against the external store to preserve the
cooldown window across restarts and replicas.
- Around line 23-29: The current auth-failure branch logs the 401 and then
returns nil, which makes the process exit cleanly; change the branch to return
an error instead of a bare return so the failure bubbles up and marks the
deployment unhealthy. In the if result is error block (using result and
errorDetail), after detecting errorDetail["statusCode"] == 401 replace the plain
return with returning a Ballerina error (e.g., return error("Shopify
authentication failed: invalid API key or access token")) so callers of this
function receive the error; keep the io:println log if desired but ensure you
propagate the error rather than silently returning.

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md`:
- Around line 22-25: The README currently asks for extra Shopify scopes
(`read_inventory`, `read_locations`) that the sample does not use; update the
setup instructions in README.md to request only the exact scopes used by the
code (remove `read_inventory` and `read_locations`, leaving `read_products`), or
alternatively implement the missing inventory/location API calls (e.g., add
functions that call the Shopify Admin Inventory and Locations endpoints and
reference them from the sample) so the extra scopes are justified; ensure the
README scope list matches the actual usage in the codebase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 23dcb446-7a5c-4ec9-a7e7-c006f09610bb

📥 Commits

Reviewing files that changed from the base of the PR and between c7cb295 and 865c701.

📒 Files selected for processing (14)
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/instructions.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.gitignore
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/agents.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/automation.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/connections.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/data_mappings.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/types.bal

Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md Outdated
@hasathcharu

hasathcharu commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

Prebuilt Integration Checklist

  • .github/workflows/projects.json is updated with the new prebuilt integration path
  • Path in the .github/workflows/projects.json matches the project path exactly
  • Directory path is identical to the integration name in Ballerina.toml
  • README.MD is correctly structured
  • Configurations are organized by records based on vendor
  • choreo/config-schema.json exists and is up to date
  • choreo/instructions.md is correctly structured
  • choreo/diagram.md is correctly written and parsable by Mermaid
  • choreo/component.yaml exists for service type integrations

Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml (1)

8-9: Consider enabling sticky resolution for reproducible builds.

At Line 9, sticky = false allows dependency versions to float between builds. For prebuilt integrations, that can introduce non-deterministic CI/runtime behavior. Sibling integrations in this directory explicitly use sticky = true; this appears to be an unintentional exception.

Proposed change
 [build-options]
-sticky = false
+sticky = true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml`
around lines 8 - 9, The build option "sticky" in the Ballerina.toml is currently
set to false which allows floating dependency versions; change the build-options
setting by updating the "sticky" flag to true so the project uses sticky
resolution for reproducible builds (edit the "sticky" property under the
[build-options] section to true).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml`:
- Around line 8-9: The build option "sticky" in the Ballerina.toml is currently
set to false which allows floating dependency versions; change the build-options
setting by updating the "sticky" flag to true so the project uses sticky
resolution for reproducible builds (edit the "sticky" property under the
[build-options] section to true).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 29a91527-eeab-4c87-bc0e-5ea628f9d7c8

📥 Commits

Reviewing files that changed from the base of the PR and between bf249d4 and c7b3cba.

📒 Files selected for processing (1)
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml

@coderabbitai

coderabbitai Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Comments resolved. Auto-approval is disabled; enable reviews.request_changes_workflow to approve automatically.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json (1)

5-91: ⚠️ Potential issue | 🟠 Major

Harden schema: require config structure and block unsafe values.

The schema still accepts empty or unsafe payloads (missing wso2/integration object, empty recipients, non-positive polling, negative thresholds/cooldown). Tighten constraints so bad configs fail at deploy time.

🔒 Suggested schema hardening
             "recipientNumbers": {
               "type": "array",
+              "minItems": 1,
               "items": {
                 "type": "string"
               }
             }
@@
             "inventoryThreshold": {
               "type": "integer",
+              "minimum": 0,
               "description": ""
             },
             "pollingIntervalSeconds": {
               "type": "number",
+              "minimum": 1,
               "description": ""
             },
@@
             "cooldownPeriodHours": {
               "type": "number",
+              "minimum": 0,
               "description": ""
             }
@@
         }
       },
+      "required": [
+        "shopify_inventory_alert_via_twilio_sms"
+      ],
       "additionalProperties": false
     }
   },
+  "required": [
+    "wso2"
+  ],
   "additionalProperties": false,
   "requiredLevel": 3
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json`
around lines 5 - 91, The schema currently allows missing or unsafe values;
tighten it by making the integration object and its critical fields required and
adding validation constraints: require "wso2" ->
"shopify_inventory_alert_via_twilio_sms" to exist, add required entries inside
that object for "shopifyConfig", "twilioConfig", "inventoryThreshold",
"pollingIntervalSeconds", "productIdsToMonitor", "smsTemplate", and
"cooldownPeriodHours"; for "twilioConfig.recipientNumbers" add "minItems":1 and
enforce non-empty strings (or a phone-number pattern) for items; set numeric
minima: "pollingIntervalSeconds": {"type":"number","exclusiveMinimum":0},
"inventoryThreshold": {"type":"integer","minimum":0}, "cooldownPeriodHours":
{"type":"number","minimum":0}; for "productIdsToMonitor" add "minItems":1 and
ensure items are non-negative integers; and require "smsTemplate" to be a
non-empty string (minLength:1) so invalid/empty configurations fail at deploy
time.
🧹 Nitpick comments (1)
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal (1)

184-197: Rename key variable/log field for clarity (sku is actually variant-id key).

sku here is the map key from lowInventoryProducts (currently variant.id), but logs print it as sku=.... This is misleading during incident triage.

🧭 Small clarity refactor
-    string[] skuKeys = lowInventoryProducts.keys();
-    foreach string sku in skuKeys {
-        ProductInventoryInfo productInfo = lowInventoryProducts.get(sku);
+    string[] variantKeys = lowInventoryProducts.keys();
+    foreach string variantKey in variantKeys {
+        ProductInventoryInfo productInfo = lowInventoryProducts.get(variantKey);
@@
-        if !isCooldownExpired(sku, cooldownTracker) {
+        if !isCooldownExpired(variantKey, cooldownTracker) {
             continue;
         }
@@
-        io:println("Sending inventory alert | product=\"" + productName +
-            "\" sku=" + sku + " inventory=" + currentInventory.toString());
+        io:println("Sending inventory alert | product=\"" + productName +
+            "\" sku=" + productInfo.sku + " variantKey=" + variantKey +
+            " inventory=" + currentInventory.toString());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal`
around lines 184 - 197, The loop variable and log field named sku are misleading
because the map lowInventoryProducts uses variant.id as the key; rename the loop
variable sku to variantId (and update all its usages: the foreach header, the
call to isCooldownExpired(variantId, cooldownTracker), any indexing
lowInventoryProducts.get(variantId), and the io:println log) and change the log
label from sku=... to variantId=... so the output and code consistently reflect
that this is a variant identifier rather than a SKU; keep ProductInventoryInfo
productInfo and currentInventory usage unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal`:
- Around line 211-221: The current logic sets cooldownTracker[sku] when
successCount > 0 which suppresses retries for recipients that failed in the same
batch; change this so cooldown is tracked per recipient (preferred) or only set
when all recipients succeeded: instead of storing cooldownTracker[sku] on any
success, iterate deliveryResults and for each successful recipient set
cooldownTracker[recipientId or phone] = { lastAlertTime: time:monotonicNow(),
inventory: currentInventory }, and only set cooldownTracker[sku] if successCount
== deliveryResults.length(); update any cooldown checks to look up by recipient
key (phone/recipientId) or SKU accordingly.

In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md`:
- Around line 70-77: The two fenced code blocks containing the inventory alert
template and example in README.md are missing language identifiers and trigger
markdown-lint MD040; update both triple-backtick fences that wrap the lines
starting with "INVENTORY ALERT: {{product.name}} (ID: {{product.id}})..." and
the example "INVENTORY ALERT: Blue Denim Jacket..." to include a language (e.g.,
text) after the opening ````` to silence the lint warning and keep the docs
consistent.

---

Duplicate comments:
In
`@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json`:
- Around line 5-91: The schema currently allows missing or unsafe values;
tighten it by making the integration object and its critical fields required and
adding validation constraints: require "wso2" ->
"shopify_inventory_alert_via_twilio_sms" to exist, add required entries inside
that object for "shopifyConfig", "twilioConfig", "inventoryThreshold",
"pollingIntervalSeconds", "productIdsToMonitor", "smsTemplate", and
"cooldownPeriodHours"; for "twilioConfig.recipientNumbers" add "minItems":1 and
enforce non-empty strings (or a phone-number pattern) for items; set numeric
minima: "pollingIntervalSeconds": {"type":"number","exclusiveMinimum":0},
"inventoryThreshold": {"type":"integer","minimum":0}, "cooldownPeriodHours":
{"type":"number","minimum":0}; for "productIdsToMonitor" add "minItems":1 and
ensure items are non-negative integers; and require "smsTemplate" to be a
non-empty string (minLength:1) so invalid/empty configurations fail at deploy
time.

---

Nitpick comments:
In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal`:
- Around line 184-197: The loop variable and log field named sku are misleading
because the map lowInventoryProducts uses variant.id as the key; rename the loop
variable sku to variantId (and update all its usages: the foreach header, the
call to isCooldownExpired(variantId, cooldownTracker), any indexing
lowInventoryProducts.get(variantId), and the io:println log) and change the log
label from sku=... to variantId=... so the output and code consistently reflect
that this is a variant identifier rather than a SKU; keep ProductInventoryInfo
productInfo and currentInventory usage unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 773ab9e3-3e05-443d-9db0-fe06ba5f117e

📥 Commits

Reviewing files that changed from the base of the PR and between c7b3cba and aa89873.

📒 Files selected for processing (10)
  • .github/workflows/projects.json
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/instructions.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/connections.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/types.bal
🚧 Files skipped from review as they are similar to previous changes (5)
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/types.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/instructions.md
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/connections.bal
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md

Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal`:
- Around line 150-151: The cooldown map is being keyed inconsistently (sometimes
by recipientNumber alone and sometimes by sku), causing cross-SKU suppression;
update the keying strategy used by isCooldownExpired, the places that set
cooldowns, and any lookup/update of cooldownTracker to use a namespaced
composite key (e.g., "recipient:<recipientNumber>|sku:<sku>") so cooldowns are
applied per-recipient-per-SKU and avoid collisions between recipient-only and
sku-only entries; locate usages of isCooldownExpired(recipientNumber,
cooldownTracker), the code paths that record cooldowns (where cooldownTracker is
written/updated), and any checks at lines around 150/194/211/230 and change both
reads and writes to construct and use the same composite key format.
- Around line 217-218: The log prints the full phone number via
result.recipient; change it to log a non-PII representation by computing a
masked or hashed value (e.g., create a helper like maskPhone(recipient) or
hashRecipient(recipient) and produce either a masked string like "+*******1234"
or a hash/hex of the number) and then replace result.recipient in the io:println
call with the masked/hashed variable; keep productName and detail as-is but
ensure no raw recipient value is logged anywhere (update the io:println usage
and any other references to result.recipient in the same scope).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5e6361ce-07bc-4709-b4c1-551c036b9fbe

📥 Commits

Reviewing files that changed from the base of the PR and between aa89873 and 73efd14.

📒 Files selected for processing (1)
  • ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal

Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Ballerina-based, webhook-driven integration package that receives Shopify order-create events and sends low-inventory SMS alerts via Twilio, including Choreo/Devant deployment metadata and configuration schema.

Changes:

  • Introduces Shopify OrdersService trigger flow that inspects ordered variants, checks current inventory via Shopify Admin API, and sends SMS alerts via Twilio with per-SKU/per-recipient cooldown handling.
  • Adds configuration (Ballerina configurable + Choreo JSON schema) and Choreo component metadata (instructions/diagram/component.yaml).
  • Registers the new project path in the GitHub workflow projects list and adds package scaffolding (Ballerina.toml, .gitignore, README).

Reviewed changes

Copilot reviewed 13 out of 16 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/types.bal Defines cooldown, inventory, and delivery-result record types used across the integration.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal Shopify Orders webhook service entrypoint and startup logging.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/functions.bal Core logic: inventory fetch, cooldown evaluation, message templating, Twilio send, and tracking.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/connections.bal Initializes Shopify listener, Shopify Admin client, and Twilio client.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal Declares configurable credentials and alert parameters (threshold/template/cooldown).
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/README.md Integration overview and setup/configuration guidance for Shopify + Twilio + Devant deployment.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/Ballerina.toml New package metadata (org/name/version/distribution).
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.gitignore Ignores build artifacts and local config/dependency files.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/instructions.md Choreo UI instructions for setup and configuration.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md Workflow diagram for webhook → threshold → cooldown → Twilio SMS.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/config-schema.json Choreo config schema for Shopify/Twilio credentials and alert settings.
ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/component.yaml Declares public REST endpoint on port 8090 for the Shopify webhook.
.github/workflows/projects.json Adds the new integration path to the workflow project list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/config.bal Outdated
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/main.bal Outdated
@vishwajayawickrama
vishwajayawickrama force-pushed the shopify-inventory-alert-via-twilio-sms branch 2 times, most recently from 9872c60 to 170cb55 Compare March 24, 2026 10:23
Comment thread ballerina-integrator/shopify-inventory-alert-via-twilio-sms/.choreo/diagram.md Outdated
@vishwajayawickrama
vishwajayawickrama force-pushed the shopify-inventory-alert-via-twilio-sms branch from bede54f to 25b1cdb Compare April 28, 2026 08:39
- Implement configuration files for component and schema
- Create flow diagram for the integration process
- Add detailed instructions for setup and usage
- Implement main logic for processing Shopify orders and sending SMS alerts
- Define necessary types and data mappings for inventory tracking
- Include cooldown logic to prevent duplicate alerts
Co-authored-by: Copilot <copilot@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants