- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.5k
Infobip - Enhanced SMS Actions with OpenAPI Auto-Generation #18404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,11 +1,96 @@ | ||
| # Overview | ||
| # Enhanced Infobip App | ||
|  | ||
| The Infobip API is a communication platform that enables seamless integration of messaging, voice, and email functionalities into various applications. With Infobip, you can automate notifications, authenticate users via one-time passwords, engage customers across multiple channels, and track communication performance. Pipedream's serverless execution environment lets you create sophisticated workflows that harness the capabilities of Infobip by triggering actions based on events, manipulating data, and connecting with numerous other apps. | ||
| Auto-generated Infobip SMS components using the official OpenAPI specification. | ||
|  | ||
| # Example Use Cases | ||
| ## Features | ||
|  | ||
| - **Customer Support Automation**: When a new ticket is created in Zendesk, use Infobip to send an SMS confirmation to the customer. Automatically escalate unresolved issues by triggering a voice call after a set period, enhancing customer experience and response times. | ||
| - **Auto-Generated Methods**: All SMS API methods from OpenAPI spec | ||
| - **Always Up-to-Date**: Methods stay current with latest Infobip API | ||
| - **Backward Compatible**: Existing manual methods still work | ||
| - **Type-Safe**: JSDoc comments from OpenAPI descriptions | ||
|  | ||
| - **Multi-channel Marketing Campaigns**: Trigger an Infobip workflow from a Shopify order event. Send personalized SMS messages for order confirmations, then follow up with email campaigns for related products, feedback requests, or loyalty program invites, all orchestrated within Pipedream. | ||
| ## Quick Start | ||
|  | ||
| - **Two-factor Authentication (2FA)**: Implement 2FA by integrating Infobip with a custom authentication system. Generate and send one-time passwords via SMS when a user attempts to log in, and verify the tokens within Pipedream workflows to enhance security across your application. | ||
| ### Send SMS (v3 - Recommended) | ||
| ```javascript | ||
| const response = await this.infobip.sendSmsMessage({ | ||
| data: { | ||
| messages: [{ | ||
| sender: "TestSender", | ||
| destinations: [{ to: "+1234567890" }], | ||
| content: { text: "Hello World" } | ||
| }] | ||
| } | ||
| }); | ||
| ``` | ||
|  | ||
| ### Legacy Method (Still Works) | ||
| ```javascript | ||
| const response = await this.infobip.sendSms({ | ||
| data: { | ||
| messages: [{ | ||
| destinations: [{ to: "+1234567890" }], | ||
| from: "TestSender", | ||
| text: "Hello World" | ||
| }] | ||
| } | ||
| }); | ||
| ``` | ||
|  | ||
| ## Available Scripts | ||
|  | ||
| Run these npm scripts for development: | ||
|  | ||
| ```bash | ||
| # Generate enhanced app with OpenAPI methods | ||
| npm run generate-infobip-enhanced-app | ||
|  | ||
| # Generate action components from OpenAPI spec | ||
| npm run generate-infobip-actions | ||
| ``` | ||
|  | ||
| ## Auto-Generated Methods | ||
|  | ||
| Key methods available from OpenAPI: | ||
|  | ||
| - `sendSmsMessages` - Send SMS (v3 API) | ||
| - `getSmsDeliveryReports` - Get delivery reports | ||
| - `getSmsLogs` - Get SMS logs | ||
| - `getScheduledSmsMessages` - Get scheduled messages | ||
| - `previewSms` - Preview SMS before sending | ||
| - `getInboundSmsMessages` - Get inbound messages | ||
|  | ||
| ## Advanced Usage | ||
|  | ||
| ### List All Methods | ||
| ```javascript | ||
| const methods = await this.infobip.getOpenAPIMethods(); | ||
| console.log('Available methods:', methods); | ||
| ``` | ||
|  | ||
| ### Dynamic Method Calling | ||
| ```javascript | ||
| const reports = await this.infobip.callOpenAPIMethod('getSmsDeliveryReports', { | ||
| params: { messageId: 'your-message-id' } | ||
| }); | ||
| ``` | ||
|  | ||
| ### Debug OpenAPI Spec | ||
| ```javascript | ||
| const spec = await this.infobip.debugOpenAPISpec(); | ||
| console.log('OpenAPI version:', spec.info.version); | ||
| ``` | ||
|  | ||
| ## Troubleshooting | ||
|  | ||
| **OpenAPI Fetch Issues**: If spec fails to load, fallback manual methods still work. | ||
|  | ||
| **Method Not Found**: | ||
| ```javascript | ||
| const methods = await this.infobip.debugAvailableMethods(); | ||
| ``` | ||
|  | ||
| ## References | ||
|  | ||
| - [Infobip OpenAPI Spec](https://api.infobip.com/platform/1/openapi/sms) | ||
| - [Infobip SMS Docs](https://www.infobip.com/docs/sms) | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import infobip from "../../infobip.app.mjs"; | ||
|  | ||
| export default { | ||
| key: "get-inbound-sms-messages", | ||
| name: "Get Inbound SMS Messages", | ||
| description: | ||
| "Get inbound SMS messages If you are unable to receive incoming SMS to the endpoint of your choice in real-time, you can use this API call to fetch messages. Each request will return a batch of rece... [See the documentation](https://www.infobip.com/docs/api)", | ||
| version: "0.0.1", | ||
| type: "action", | ||
| props: { | ||
| infobip, | ||
| limit: { | ||
| type: "integer", | ||
| label: "Limit", | ||
| description: "Maximum number of messages to be returned in a response. If not set, the latest 50 records are returned. Maximum limit value is `1000` and you can only access messages for the last 48h.", | ||
| optional: true, | ||
| }, | ||
| applicationId: { | ||
| type: "string", | ||
| label: "Application Id", | ||
| description: "Application id that the message is linked to. For more details, see our [documentation](https://www.infobip.com/docs/cpaas-x/application-and-entity-management).", | ||
| optional: true, | ||
| }, | ||
| entityId: { | ||
| type: "string", | ||
| label: "Entity Id", | ||
| description: "Entity id that the message is linked to. For more details, see our [documentation](https://www.infobip.com/docs/cpaas-x/application-and-entity-management).", | ||
| optional: true, | ||
| }, | ||
| campaignReferenceId: { | ||
| type: "string", | ||
| label: "Campaign Reference Id", | ||
| description: "ID of a campaign that was sent in the message.", | ||
| optional: true, | ||
| } | ||
| }, | ||
| async run({ $ }) { | ||
| const { infobip, limit, applicationId, entityId, campaignReferenceId, ...params } = this; | ||
|  | ||
| const pathQuery = []; | ||
| if (limit !== undefined && limit !== null) pathQuery.push({ name: "limit", value: limit.toString() }); | ||
| if (applicationId !== undefined && applicationId !== null) pathQuery.push({ name: "applicationId", value: applicationId.toString() }); | ||
| if (entityId !== undefined && entityId !== null) pathQuery.push({ name: "entityId", value: entityId.toString() }); | ||
| if (campaignReferenceId !== undefined && campaignReferenceId !== null) pathQuery.push({ name: "campaignReferenceId", value: campaignReferenceId.toString() }); | ||
|  | ||
| Object.entries(params).forEach(([key, value]) => { | ||
| if (value !== undefined && value !== null) { | ||
| pathQuery.push({ name: key, value: value.toString() }); | ||
| } | ||
| }); | ||
|  | ||
| const response = await infobip.getInboundSmsMessages({ | ||
| $, | ||
| pathQuery: pathQuery.length > 0 ? pathQuery : undefined, | ||
| }); | ||
|  | ||
| $.export( | ||
| "$summary", | ||
| `Data retrieved successfully: ${response.status?.description || "Success"}` | ||
| ); | ||
| return response; | ||
| }, | ||
| }; | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import infobip from "../../infobip.app.mjs"; | ||
|  | ||
| export default { | ||
| key: "get-outbound-sms-message-delivery-reports-v3", | ||
| name: "Get Outbound SMS Message Delivery Reports V3", | ||
| description: | ||
| "Get outbound SMS message delivery reports If you are unable to receive real-time message delivery reports towards your endpoint for various reasons, we offer you an API method to fetch batches of m... [See the documentation](https://www.infobip.com/docs/sms)", | ||
| version: "0.0.1", | ||
| type: "action", | ||
| props: { | ||
| infobip, | ||
| bulkId: { | ||
| type: "string", | ||
| label: "Bulk Id", | ||
| description: "The ID that uniquely identifies the request. Bulk ID will be received only when you send a message to more than one destination address.", | ||
| optional: true, | ||
| }, | ||
| messageId: { | ||
| type: "string", | ||
| label: "Message Id", | ||
| description: "The ID that uniquely identifies the message sent.", | ||
| optional: true, | ||
| }, | ||
| limit: { | ||
| type: "integer", | ||
| label: "Limit", | ||
| description: "Maximum number of delivery reports to be returned. If not set, the latest 50 records are returned. Maximum limit value is 1000 and you can only access reports for the last 48h", | ||
| optional: true, | ||
| }, | ||
| entityId: { | ||
| type: "string", | ||
| label: "Entity Id", | ||
| description: "Entity id used to send the message. For more details, see our [documentation](https://www.infobip.com/docs/cpaas-x/application-and-entity-management).", | ||
| optional: true, | ||
| }, | ||
| applicationId: { | ||
| type: "string", | ||
| label: "Application Id", | ||
| description: "Application id used to send the message. For more details, see our [documentation](https://www.infobip.com/docs/cpaas-x/application-and-entity-management).", | ||
| optional: true, | ||
| }, | ||
| campaignReferenceId: { | ||
| type: "string", | ||
| label: "Campaign Reference Id", | ||
| description: "ID of a campaign that was sent in the message.", | ||
| optional: true, | ||
| } | ||
| }, | ||
| async run({ $ }) { | ||
| const { infobip, bulkId, messageId, limit, entityId, applicationId, campaignReferenceId, ...params } = this; | ||
|  | ||
| const pathQuery = []; | ||
| if (bulkId !== undefined && bulkId !== null) pathQuery.push({ name: "bulkId", value: bulkId.toString() }); | ||
| if (messageId !== undefined && messageId !== null) pathQuery.push({ name: "messageId", value: messageId.toString() }); | ||
| if (limit !== undefined && limit !== null) pathQuery.push({ name: "limit", value: limit.toString() }); | ||
| if (entityId !== undefined && entityId !== null) pathQuery.push({ name: "entityId", value: entityId.toString() }); | ||
| if (applicationId !== undefined && applicationId !== null) pathQuery.push({ name: "applicationId", value: applicationId.toString() }); | ||
| if (campaignReferenceId !== undefined && campaignReferenceId !== null) pathQuery.push({ name: "campaignReferenceId", value: campaignReferenceId.toString() }); | ||
|  | ||
| Object.entries(params).forEach(([key, value]) => { | ||
| if (value !== undefined && value !== null) { | ||
| pathQuery.push({ name: key, value: value.toString() }); | ||
| } | ||
| }); | ||
| 
      Comment on lines
    
      +52
     to 
      +64
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Simplify redundant pathQuery building logic. Lines 53-58 explicitly check each known prop, then lines 60-64 iterate over remaining params. This is redundant—the loop in lines 60-64 would handle all params, making the explicit checks unnecessary. Either: 
 Option 2 is preferred to eliminate duplication across all action files. | ||
|  | ||
| const response = await infobip.getOutboundSmsMessageDeliveryReportsV3({ | ||
| $, | ||
| pathQuery: pathQuery.length > 0 ? pathQuery : undefined, | ||
| }); | ||
|  | ||
| $.export( | ||
| "$summary", | ||
| `Data retrieved successfully: ${response.status?.description || "Success"}` | ||
| ); | ||
| return response; | ||
| }, | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import infobip from "../../infobip.app.mjs"; | ||
|  | ||
| export default { | ||
| key: "get-outbound-sms-message-delivery-reports", | ||
| name: "Get Outbound SMS Message Delivery Reports", | ||
| description: | ||
| "Get outbound SMS message delivery reports If you are for any reason unable to receive real-time delivery reports on your endpoint, you can use this API method to learn if and when the message has b... [See the documentation](https://www.infobip.com/docs/sms)", | ||
| version: "0.0.1", | ||
| type: "action", | ||
| props: { | ||
| infobip, | ||
| bulkId: { | ||
| type: "string", | ||
| label: "Bulk Id", | ||
| description: "Unique ID assigned to the request if messaging multiple recipients or sending multiple messages via a single API request.", | ||
| optional: true, | ||
| }, | ||
| messageId: { | ||
| type: "string", | ||
| label: "Message Id", | ||
| description: "Unique message ID for which a report is requested.", | ||
| optional: true, | ||
| }, | ||
| limit: { | ||
| type: "integer", | ||
| label: "Limit", | ||
| description: "Maximum number of delivery reports to be returned. If not set, the latest 50 records are returned. Maximum limit value is `1000` and you can only access reports for the last 48h.", | ||
| optional: true, | ||
| }, | ||
| applicationId: { | ||
| type: "string", | ||
| label: "Application Id", | ||
| description: "Application id used to send the message. For more details, see our [documentation](https://www.infobip.com/docs/cpaas-x/application-and-entity-management).", | ||
| optional: true, | ||
| }, | ||
| entityId: { | ||
| type: "string", | ||
| label: "Entity Id", | ||
| description: "Entity id used to send the message. For more details, see our [documentation](https://www.infobip.com/docs/cpaas-x/application-and-entity-management).", | ||
| optional: true, | ||
| }, | ||
| campaignReferenceId: { | ||
| type: "string", | ||
| label: "Campaign Reference Id", | ||
| description: "ID of a campaign that was sent in the message.", | ||
| optional: true, | ||
| } | ||
| }, | ||
| async run({ $ }) { | ||
| const { infobip, bulkId, messageId, limit, applicationId, entityId, campaignReferenceId, ...params } = this; | ||
|  | ||
| const pathQuery = []; | ||
| if (bulkId !== undefined && bulkId !== null) pathQuery.push({ name: "bulkId", value: bulkId.toString() }); | ||
| if (messageId !== undefined && messageId !== null) pathQuery.push({ name: "messageId", value: messageId.toString() }); | ||
| if (limit !== undefined && limit !== null) pathQuery.push({ name: "limit", value: limit.toString() }); | ||
| if (applicationId !== undefined && applicationId !== null) pathQuery.push({ name: "applicationId", value: applicationId.toString() }); | ||
| if (entityId !== undefined && entityId !== null) pathQuery.push({ name: "entityId", value: entityId.toString() }); | ||
| if (campaignReferenceId !== undefined && campaignReferenceId !== null) pathQuery.push({ name: "campaignReferenceId", value: campaignReferenceId.toString() }); | ||
|  | ||
| Object.entries(params).forEach(([key, value]) => { | ||
| if (value !== undefined && value !== null) { | ||
| pathQuery.push({ name: key, value: value.toString() }); | ||
| } | ||
| }); | ||
|  | ||
| const response = await infobip.getOutboundSmsMessageDeliveryReports({ | ||
| $, | ||
| pathQuery: pathQuery.length > 0 ? pathQuery : undefined, | ||
| }); | ||
|  | ||
| $.export( | ||
| "$summary", | ||
| `Data retrieved successfully: ${response.status?.description || "Success"}` | ||
| ); | ||
| return response; | ||
| }, | ||
| }; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix script names to match package.json.
The script names in the documentation don't match the actual npm scripts defined in
package.json.Apply this diff:
In components/infobip/README.md around lines 44 to 50, the documented npm script
names are incorrect; update the README to use the actual scripts from
package.json by replacing "npm run generate-infobip-enhanced-app" with "npm run
generate-app" and "npm run generate-infobip-actions" with "npm run
generate-actions" so the commands in the docs match the package.json.