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
3 changes: 0 additions & 3 deletions components/loopmessage/.gitignore

This file was deleted.

61 changes: 61 additions & 0 deletions components/loopmessage/actions/common/send-message.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import app from "../../loopmessage.app.mjs";
import utils from "../../common/utils.mjs";
import { ConfigurationError } from "@pipedream/platform";

export default {
props: {
app,
recipient: {
propDefinition: [
app,
"recipient",
],
},
text: {
propDefinition: [
app,
"text",
],
},
senderName: {
optional: true,
propDefinition: [
app,
"senderName",
],
},
statusCallback: {
propDefinition: [
app,
"statusCallback",
],
},
statusCallbackHeader: {
propDefinition: [
app,
"statusCallbackHeader",
],
},
},
methods: {
getSummary() {
throw new ConfigurationError("The `getSummary` method is not implemented.");
},
},
async run({ $: step }) {
const {
app,
getSummary,
...data
} = this;

const response = await app.sendMessage({
step,
data: utils.keysToSnakeCase(data),
});

step.export("$summary", getSummary(response));

return response;
},
};
31 changes: 31 additions & 0 deletions components/loopmessage/actions/send-reaction/send-reaction.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import common from "../common/send-message.mjs";
import constants from "../../common/constants.mjs";

export default {
...common,
key: "loopmessage-send-reaction",
name: "Send Reaction",
description: "Action to submit your request to the sending queue. When a request in the queue will be ready to send a reaction in iMessage, an attempt will be made to deliver it to the recipient. [See the documentation](https://docs.loopmessage.com/imessage-conversation-api/messaging/send-message#send-reaction)",
type: "action",
version: "0.0.1",
props: {
...common.props,
messageId: {
type: "string",
label: "Message ID",
description: "The ID of the message to react to. You can get it from the webhook trigger.",
},
reaction: {
type: "string",
label: "Reaction",
description: "Reactions that starts with `-` mean *remove* it from the message. You can check the [Apple guide](https://support.apple.com/HT206894) about reactions and tapbacks.",
options: constants.REACTIONS,
},
},
methods: {
...common.methods,
getSummary(response) {
return `Successfully sent a reaction to with ID \`${response.message_id}\``;
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import common from "../common/send-message.mjs";

export default {
...common,
key: "loopmessage-send-text-message",
name: "Send Text Message",
description: "Action to send a text in iMessage to an individual recipient. [See the documentation](https://docs.loopmessage.com/imessage-conversation-api/messaging/send-message#send-single-message)",
type: "action",
version: "0.0.1",
props: {
...common.props,
service: {
propDefinition: [
common.props.app,
"service",
],
},
subject: {
propDefinition: [
common.props.app,
"subject",
],
},
effect: {
propDefinition: [
common.props.app,
"effect",
],
},
},
methods: {
...common.methods,
getSummary(response) {
return `Successfully sent a text message with ID \`${response.message_id}\``;
},
},
};
13 changes: 0 additions & 13 deletions components/loopmessage/app/loopmessage.app.ts

This file was deleted.

60 changes: 60 additions & 0 deletions components/loopmessage/common/constants.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const API_PLACEHOLDER = "{api}";
const BASE_URL = `https://${API_PLACEHOLDER}.loopmessage.com`;
const VERSION_PATH = "/api/v1";
const LAST_CREATED_AT = "lastCreatedAt";
const DEFAULT_MAX = 600;
const AUTH_HEADER = "authHeader";

const API = {
SERVER: "server",
LOOKUP: "lookup",
};

const SERVICES = [
"imessage",
"sms",
];

const EFFECTS = [
"slam",
"loud",
"gentle",
"invisibleInk",
"echo",
"spotlight",
"balloons",
"confetti",
"love",
"lasers",
"fireworks",
"shootingStar",
"celebration",
];

const REACTIONS = [
"love",
"like",
"dislike",
"laugh",
"exlaim",
"question",
"-love",
"-like",
"-dislike",
"-laugh",
"-exlaim",
"-question",
];

export default {
BASE_URL,
VERSION_PATH,
DEFAULT_MAX,
LAST_CREATED_AT,
AUTH_HEADER,
SERVICES,
EFFECTS,
REACTIONS,
API,
API_PLACEHOLDER,
};
27 changes: 27 additions & 0 deletions components/loopmessage/common/utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
async function streamIterator(stream) {
const resources = [];
for await (const resource of stream) {
resources.push(resource);
}
return resources;
}

function toSnakeCase(str) {
return str?.replace(/([A-Z])/g, "_$1").toLowerCase();
}

function keysToSnakeCase(data = {}) {
return Object.entries(data)
.reduce((acc, [
key,
value,
]) => ({
...acc,
[toSnakeCase(key)]: value,
}), {});
}

export default {
streamIterator,
keysToSnakeCase,
};
115 changes: 115 additions & 0 deletions components/loopmessage/loopmessage.app.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { axios } from "@pipedream/platform";
import constants from "./common/constants.mjs";

export default {
type: "app",
app: "loopmessage",
propDefinitions: {
recipient: {
type: "string",
label: "Recipient",
description: "The recipient of the message. This can be a phone number or email address.",
},
text: {
type: "string",
label: "Text",
description: "The text of the message.",
},
senderName: {
type: "string",
label: "Sender Name",
description: "Your dedicated sender name. This parameter will be ignored if you send a request to a recipient who is added as a Sandbox contact. If you've connected a phone number, you'll need to keep passing your original sender name. DON'T use a phone number as a value for this parameter.",
},
statusCallback: {
type: "string",
label: "Status Callback",
description: "The URL that will receive status updates for this message. Check the [Webhooks](https://docs.loopmessage.com/imessage-conversation-api/messaging/webhooks) section for details. Max length is 256 characters.",
optional: true,
},
statusCallbackHeader: {
type: "string",
label: "Status Callback Header",
description: "The custom Authorization header will be contained in the callback request. Max length is 256 characters.",
optional: true,
},
service: {
type: "string",
label: "Service",
description: "You can choose wich service to use to deliver the message. Your sender name must have an active SMS feature. SMS does not support `subject`, `effect`, or `reply_to_id` parameters. `attachments` in SMS - only support pictures (MMS).",
options: constants.SERVICES,
optional: true,
},
subject: {
type: "string",
label: "Subject",
description: "The subject of the message. A recipient will see this subject as a bold title before the message text.",
optional: true,
},
effect: {
type: "string",
label: "Effect",
description: "Add effect to your message. You can check the [Apple guide]() about `expressive messages`.",
options: constants.EFFECTS,
optional: true,
},
contacts: {
type: "string[]",
label: "Contacts",
description: "An array of contacts to send the message to. Should contains phone numbers in international formats or email addresses. Example: `[\"+13231112233\", \"steve@mac.com\", \"1(787)111-22-33\"]`. Invalid recipients will be skipped.",
},
region: {
type: "string",
label: "Region",
description: "Value in [ISO-2 country code](https://en.wikipedia.org/wiki/ISO_3166-2). For example: `US`, `GB`, `CA`, `AU` etc. This parameter should be passed only if you passed phone numbers without a country code.",
optional: true,
},
},
methods: {
getBaseUrl(api = constants.API.SERVER) {
const baseUrl = `${constants.BASE_URL}${constants.VERSION_PATH}`;
return baseUrl.replace(constants.API_PLACEHOLDER, api);
},
getUrl(path, api) {
return `${this.getBaseUrl(api)}${path}`;
},
getHeaders(headers) {
return {
"Content-Type": "application/json",
"Authorization": `Bearer ${this.$auth.authorization_key}`,
"Loop-Secret-Key": `${this.$auth.secret_api_key}`,
...headers,
};
},
makeRequest({
step = this, path, headers, api, ...args
} = {}) {

const config = {
headers: this.getHeaders(headers),
url: this.getUrl(path, api),
...args,
};

return axios(step, config);
},
post(args = {}) {
return this.makeRequest({
method: "post",
...args,
});
},
sendMessage(args = {}) {
return this.post({
path: "/message/send/",
...args,
});
},
singleLookup(args = {}) {
return this.app.post({
api: constants.API.LOOKUP,
path: "/contact/lookup/",
...args,
});
},
},
};
10 changes: 6 additions & 4 deletions components/loopmessage/package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
"name": "@pipedream/loopmessage",
"version": "0.0.1",
"version": "0.1.0",
"description": "Pipedream LoopMessage Components",
"main": "dist/app/loopmessage.app.mjs",
"main": "loopmessage.app.mjs",
"keywords": [
"pipedream",
"loopmessage"
],
"files": ["dist"],
"homepage": "https://pipedream.com/apps/loopmessage",
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
"dependencies": {
"@pipedream/platform": "^1.5.1"
},
"publishConfig": {
"access": "public"
}
}
}
14 changes: 14 additions & 0 deletions components/loopmessage/sources/common/base.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ConfigurationError } from "@pipedream/platform";
import app from "../../loopmessage.app.mjs";

export default {
props: {
app,
db: "$.service.db",
},
methods: {
generateMeta() {
throw new ConfigurationError("generateMeta is not implemented");
},
},
};
Loading