Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import app from "../../inmobile.app.mjs";
import utils from "../../common/utils.mjs";

export default {
key: "inmobile-send-sms-messages",
name: "Send SMS Messages",
description: "Send one or more SMS messages using the InMobile API. [See the documentation](https://www.inmobile.com/docs/rest-api)",
version: "0.0.1",
type: "action",
annotations: {
readOnlyHint: false,
destructiveHint: true,
openWorldHint: true,
},
props: {
app,
messages: {
type: "string[]",
label: "Messages",
description: `An array of message objects (1-250 messages). Each message object supports the following properties:

**Required Fields:**
- \`to\` (string): The msisdn (country code and number) to send to. Remember to include country code, e.g. \`4512345678\`
- \`text\` (string): The text message (1-10000 characters)
- \`from\` (string): The sender. Can be a 3-11 character text sender or up to 14 digit sender number

**Optional Fields:**
- \`countryHint\` (string): Country code for optimal phone number validation, e.g. \`44\` or \`GB\`
- \`messageId\` (string): Optional message ID to identify the message (1-50 characters, must be unique)
- \`respectBlacklist\` (boolean): Block message if target number is blacklisted. Default: \`true\`
- \`validityPeriodInSeconds\` (integer): Validity period (60-172800 seconds). Default: \`172800\` (48 hours)
- \`statusCallbackUrl\` (string): URL for delivery status callbacks
- \`sendTime\` (string): Schedule message for future sending, e.g. \`2024-12-31T14:50:23Z\` (UTC time)
- \`msisdnCooldownInMinutes\` (integer): Prevent sending to same number within period (60-43200 minutes)
- \`flash\` (boolean): Send as flash message (class0). Default: \`false\`
- \`encoding\` (string): Message encoding - \`gsm7\` (default, 160 chars), \`ucs2\` (70 chars), or \`auto\`

**Example:**
\`\`\`json
[
{
"to": "4512345678",
"text": "Hello World",
"from": "YourSender",
"encoding": "gsm7"
},
{
"to": "4587654321",
"text": "Another message",
"from": "YourSender",
"flash": true
}
]
\`\`\``,
},
},
async run({ $ }) {
const {
app,
messages,
} = this;

const response = await app.sendSms({
$,
data: {
messages: utils.parseArray(messages),
},
});

$.export("$summary", "Successfully sent SMS messages");
return response;
},
};
68 changes: 68 additions & 0 deletions components/inmobile/common/utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const parseJson = (input, maxDepth = 100) => {
const seen = new WeakSet();
const parse = (value) => {
if (maxDepth <= 0) {
return value;
}
if (typeof(value) === "string") {
// Only parse if the string looks like a JSON object or array
const trimmed = value.trim();
if (
(trimmed.startsWith("{") && trimmed.endsWith("}")) ||
(trimmed.startsWith("[") && trimmed.endsWith("]"))
) {
try {
return parseJson(JSON.parse(value), maxDepth - 1);
} catch (e) {
return value;
}
}
return value;
} else if (typeof(value) === "object" && value !== null && !Array.isArray(value)) {
if (seen.has(value)) {
return value;
}
seen.add(value);
return Object.entries(value)
.reduce((acc, [
key,
val,
]) => Object.assign(acc, {
[key]: parse(val),
}), {});
} else if (Array.isArray(value)) {
return value.map((item) => parse(item));
}
return value;
};

return parse(input);
};

function parseArray(input, maxDepth = 100) {
if (typeof input === "string") {
const trimmed = input.trim();
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
try {
const parsed = JSON.parse(trimmed);
if (Array.isArray(parsed)) {
return parsed.map((item) => parseArray(item, maxDepth - 1));
}
} catch (e) {
throw new Error(`Invalid JSON array format: ${e.message}`);
}
}
return parseJson(input, maxDepth);
}

if (Array.isArray(input)) {
return input.map((item) => parseArray(item, maxDepth));
}

return input;
}

export default {
parseJson,
parseArray,
};
35 changes: 31 additions & 4 deletions components/inmobile/inmobile.app.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
import { axios } from "@pipedream/platform";

export default {
type: "app",
app: "inmobile",
propDefinitions: {},
methods: {
// this.$auth contains connected account data
authKeys() {
console.log(Object.keys(this.$auth));
getUrl(path) {
return `https://api.inmobile.com/v4${path}`;
},
getAuth() {
return {
username: "x",
password: this.$auth.api_key,
};
},
makeRequest({
$ = this, path, ...args
}) {
return axios($, {
url: this.getUrl(path),
auth: this.getAuth(),
...args,
});
},
post(args = {}) {
return this.makeRequest({
method: "POST",
...args,
});
},
sendSms(args = {}) {
return this.post({
path: "/sms/outgoing",
...args,
});
},
Comment on lines +25 to 36
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify the SMS endpoint path.

The implementation looks clean. Please confirm that /sms/outgoing is the correct InMobile API v4 endpoint for sending SMS messages.


🌐 Web query:

What is the correct InMobile REST API v4 endpoint path for sending SMS messages?

💡 Result:

Use POST to /v4/sms/outgoing — e.g. https://api.inmobile.com/v4/sms/outgoing?apikey=[your_api_key]. [1][2]

Sources:
[1] inMobile Klaviyo webhook guide (shows https://api.inmobile.com/v4/sms/outgoing?apikey=...).
[2] inMobile SDK / Packagist documentation (v4 API messaging endpoints).


Fix the SMS endpoint path to include the API version prefix.

The endpoint path is missing the /v4/ prefix. The correct InMobile REST API v4 endpoint path for sending SMS messages is /v4/sms/outgoing, not /sms/outgoing.

Update line 33:

path: "/v4/sms/outgoing",
🤖 Prompt for AI Agents
In components/inmobile/inmobile.app.mjs around lines 25 to 36, the sendSms call
uses the wrong endpoint path; change the path from "/sms/outgoing" to include
the API version prefix "/v4/sms/outgoing" so the request targets the InMobile
REST API v4 endpoint.

},
};
5 changes: 4 additions & 1 deletion components/inmobile/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/inmobile",
"version": "0.0.1",
"version": "0.1.0",
"description": "Pipedream InMobile Components",
"main": "inmobile.app.mjs",
"keywords": [
Expand All @@ -11,5 +11,8 @@
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@pipedream/platform": "^3.1.0"
}
}
6 changes: 5 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading