@pipedream/twilio 0.3.3 → 0.3.5

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/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # Overview
2
+
3
+ With the Twilio API, you can build telephone applications that make and receive
4
+ phone calls, as well astext messaging applications that send and receive text
5
+ messages.
6
+
7
+ Some examples of applications you could build include:
8
+
9
+ - A phone call application that allows you to make and receive phone calls over
10
+ the internet
11
+ - A text messaging application that allows you to send and receive text
12
+ messages over the internet
13
+ - A voicemail application that allows you to leave and receive voicemails over
14
+ the internet
@@ -0,0 +1,23 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+
3
+ export default {
4
+ key: "twilio-delete-call",
5
+ name: "Delete Call",
6
+ description: "Remove a call record from your account. [See the docs](https://www.twilio.com/docs/voice/api/call-resource#delete-a-call-resource) for more information",
7
+ version: "0.1.0",
8
+ type: "action",
9
+ props: {
10
+ twilio,
11
+ sid: {
12
+ propDefinition: [
13
+ twilio,
14
+ "sid",
15
+ ],
16
+ },
17
+ },
18
+ async run({ $ }) {
19
+ const resp = await this.twilio.deleteCall(this.sid);
20
+ $.export("$summary", `Successfully deleted the call, "${this.sid}"`);
21
+ return resp;
22
+ },
23
+ };
@@ -0,0 +1,23 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+
3
+ export default {
4
+ key: "twilio-delete-message",
5
+ name: "Delete Message",
6
+ description: "Delete a message record from your account. [See the docs](https://www.twilio.com/docs/sms/api/message-resource#delete-a-message-resource) for more information",
7
+ version: "0.1.0",
8
+ type: "action",
9
+ props: {
10
+ twilio,
11
+ messageId: {
12
+ propDefinition: [
13
+ twilio,
14
+ "messageId",
15
+ ],
16
+ },
17
+ },
18
+ async run({ $ }) {
19
+ const resp = await this.twilio.deleteMessage(this.messageId);
20
+ $.export("$summary", `Successfully deleted the message, "${this.messageId}"`);
21
+ return resp;
22
+ },
23
+ };
@@ -0,0 +1,50 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import got from "got";
3
+ import stream from "stream";
4
+ import { promisify } from "util";
5
+ import fs from "fs";
6
+
7
+ export default {
8
+ key: "twilio-download-recording-media",
9
+ name: "Download Recording Media",
10
+ description: "Download a recording media file. [See the docs](https://www.twilio.com/docs/voice/api/recording#fetch-a-recording-media-file) for more information",
11
+ version: "0.1.0",
12
+ type: "action",
13
+ props: {
14
+ twilio,
15
+ recordingID: {
16
+ propDefinition: [
17
+ twilio,
18
+ "recordingID",
19
+ ],
20
+ },
21
+ format: {
22
+ propDefinition: [
23
+ twilio,
24
+ "format",
25
+ ],
26
+ },
27
+ filePath: {
28
+ type: "string",
29
+ label: "File Path",
30
+ description: "The destination path in [`/tmp`](https://pipedream.com/docs/workflows/steps/code/nodejs/working-with-files/#the-tmp-directory) for the downloaded the file (e.g., `/tmp/myFile.mp3`)",
31
+ },
32
+ },
33
+ async run({ $ }) {
34
+ // Get Recording resource to get `uri`
35
+ const recording = await this.twilio.getRecording(this.recordingID);
36
+ const client = this.twilio.getClient();
37
+ // `uri` ends in ".json" - remove ".json" from uri
38
+ const uri = client.api.absoluteUrl(recording.uri).replace(".json", "");
39
+ // Add chosen download format extension (e.g. ".mp3"), as specified in the Twilio API docs:
40
+ // https://www.twilio.com/docs/voice/api/recording#fetch-a-recording-media-file
41
+ const downloadUrl = uri + this.format;
42
+ const pipeline = promisify(stream.pipeline);
43
+ const resp = await pipeline(
44
+ got.stream(downloadUrl),
45
+ fs.createWriteStream(this.filePath),
46
+ );
47
+ $.export("$summary", `Successfully downloaded the recording media file to "${this.filePath}"`);
48
+ return resp;
49
+ },
50
+ };
@@ -0,0 +1,24 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import { callToString } from "../../common/utils.mjs";
3
+
4
+ export default {
5
+ key: "twilio-get-call",
6
+ name: "Get Call",
7
+ description: "Return call resource of an individual call. [See the docs](https://www.twilio.com/docs/voice/api/call-resource#fetch-a-call-resource) for more information",
8
+ version: "0.1.0",
9
+ type: "action",
10
+ props: {
11
+ twilio,
12
+ sid: {
13
+ propDefinition: [
14
+ twilio,
15
+ "sid",
16
+ ],
17
+ },
18
+ },
19
+ async run({ $ }) {
20
+ const resp = await this.twilio.getCall(this.sid);
21
+ $.export("$summary", `Successfully fetched the call, "${callToString(resp)}"`);
22
+ return resp;
23
+ },
24
+ };
@@ -0,0 +1,24 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import { messageToString } from "../../common/utils.mjs";
3
+
4
+ export default {
5
+ key: "twilio-get-message",
6
+ name: "Get Message",
7
+ description: "Return details of a message. [See the docs](https://www.twilio.com/docs/sms/api/message-resource#fetch-a-message-resource) for more information",
8
+ version: "0.1.0",
9
+ type: "action",
10
+ props: {
11
+ twilio,
12
+ messageId: {
13
+ propDefinition: [
14
+ twilio,
15
+ "messageId",
16
+ ],
17
+ },
18
+ },
19
+ async run({ $ }) {
20
+ const resp = await this.twilio.getMessage(this.messageId);
21
+ $.export("$summary", `Successfully fetched the message, "${messageToString(resp)}"`);
22
+ return resp;
23
+ },
24
+ };
@@ -0,0 +1,60 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import { omitEmptyStringValues } from "../../common/utils.mjs";
3
+
4
+ export default {
5
+ key: "twilio-list-calls",
6
+ name: "List Calls",
7
+ description: "Return a list of calls associated with your account. [See the docs](https://www.twilio.com/docs/voice/api/call-resource#read-multiple-call-resources) for more information",
8
+ version: "0.1.0",
9
+ type: "action",
10
+ props: {
11
+ twilio,
12
+ from: {
13
+ propDefinition: [
14
+ twilio,
15
+ "from",
16
+ ],
17
+ description: "Only include calls from this phone number, SIP address, Client identifier or SIM SID. Format the phone number in E.164 format with a `+` and country code (e.g., `+16175551212`).",
18
+ optional: true,
19
+ },
20
+ to: {
21
+ propDefinition: [
22
+ twilio,
23
+ "to",
24
+ ],
25
+ description: "Only show calls made to this phone number, SIP address, Client identifier or SIM SID. Format the phone number in E.164 format with a `+` and country code (e.g., `+16175551212`).",
26
+ optional: true,
27
+ },
28
+ parentCallSid: {
29
+ propDefinition: [
30
+ twilio,
31
+ "parentCallSid",
32
+ ],
33
+ },
34
+ status: {
35
+ propDefinition: [
36
+ twilio,
37
+ "status",
38
+ ],
39
+ },
40
+ limit: {
41
+ propDefinition: [
42
+ twilio,
43
+ "limit",
44
+ ],
45
+ },
46
+ },
47
+ async run({ $ }) {
48
+ const resp = await this.twilio.listCalls(omitEmptyStringValues({
49
+ to: this.to,
50
+ from: this.from,
51
+ parentCallSid: this.parentCallSid,
52
+ status: this.status,
53
+ limit: this.limit,
54
+ }));
55
+ /* eslint-disable multiline-ternary */
56
+ $.export("$summary", `Successfully fetched ${resp.length} call${resp.length === 1 ? "" : "s"}${
57
+ this.from ? ` from ${this.from}` : ""}${this.to ? ` to ${this.to}` : ""}`);
58
+ return resp;
59
+ },
60
+ };
@@ -0,0 +1,34 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import { omitEmptyStringValues } from "../../common/utils.mjs";
3
+
4
+ export default {
5
+ key: "twilio-list-message-media",
6
+ name: "List Message Media",
7
+ description: "Return a list of media associated with your message. [See the docs](https://www.twilio.com/docs/sms/api/media-resource#read-multiple-media-resources) for more information",
8
+ version: "0.1.0",
9
+ type: "action",
10
+ props: {
11
+ twilio,
12
+ messageId: {
13
+ propDefinition: [
14
+ twilio,
15
+ "messageId",
16
+ ],
17
+ },
18
+ limit: {
19
+ propDefinition: [
20
+ twilio,
21
+ "limit",
22
+ ],
23
+ },
24
+ },
25
+ async run({ $ }) {
26
+ const resp = await this.twilio.listMessageMedia(this.messageId, omitEmptyStringValues({
27
+ limit: this.limit,
28
+ }));
29
+ $.export("$summary", `Successfully fetched ${resp.length} media object${resp.length === 1
30
+ ? ""
31
+ : "s"} associated with the message, "${this.messageId}"`);
32
+ return resp;
33
+ },
34
+ };
@@ -0,0 +1,60 @@
1
+ import { phone } from "phone";
2
+ import twilio from "../../twilio.app.mjs";
3
+ import { omitEmptyStringValues } from "../../common/utils.mjs";
4
+
5
+ export default {
6
+ key: "twilio-list-messages",
7
+ name: "List Messages",
8
+ description: "Return a list of messages associated with your account. [See the docs](https://www.twilio.com/docs/sms/api/message-resource#read-multiple-message-resources) for more information",
9
+ version: "0.1.0",
10
+ type: "action",
11
+ props: {
12
+ twilio,
13
+ from: {
14
+ propDefinition: [
15
+ twilio,
16
+ "from",
17
+ ],
18
+ description: "Read messages sent from only this phone number or alphanumeric sender ID. Format the phone number in E.164 format with a `+` and country code (e.g., `+16175551212`).",
19
+ optional: true,
20
+ },
21
+ to: {
22
+ propDefinition: [
23
+ twilio,
24
+ "to",
25
+ ],
26
+ description: "Read messages sent to only this phone number. Format the phone number in E.164 format with a `+` and country code (e.g., `+16175551212`).",
27
+ optional: true,
28
+ },
29
+ limit: {
30
+ propDefinition: [
31
+ twilio,
32
+ "limit",
33
+ ],
34
+ },
35
+ },
36
+ async run({ $ }) {
37
+ // Parse the given number into its E.164 equivalent
38
+ // The E.164 phone number will be included in the first element
39
+ // of the array, but the array will be empty if parsing fails.
40
+ // See https://www.npmjs.com/package/phone
41
+ let to = this.to;
42
+ if (this.to) {
43
+ const toParsed = phone(this.to);
44
+ if (!toParsed || !toParsed.phoneNumber) {
45
+ throw new Error(`Phone number ${this.to} couldn't be parsed as a valid number.`);
46
+ }
47
+ to = toParsed.phoneNumber;
48
+ }
49
+
50
+ const resp = await this.twilio.listMessages(omitEmptyStringValues({
51
+ to,
52
+ from: this.from,
53
+ limit: this.limit,
54
+ }));
55
+ /* eslint-disable multiline-ternary */
56
+ $.export("$summary", `Successfully fetched ${resp.length} message${resp.length === 1 ? "" : "s"}${
57
+ this.from ? ` from ${this.from}` : ""}${this.to ? ` to ${this.to}` : ""}`);
58
+ return resp;
59
+ },
60
+ };
@@ -0,0 +1,37 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import { omitEmptyStringValues } from "../../common/utils.mjs";
3
+
4
+ export default {
5
+ key: "twilio-list-recording-transcriptions",
6
+ name: "List Recording Transcriptions",
7
+ description: "Return a set of transcriptions available for a recording. [See the docs](https://www.twilio.com/docs/voice/api/recording#fetch-a-recordings-transcriptions) for more information",
8
+ version: "0.1.0",
9
+ type: "action",
10
+ props: {
11
+ twilio,
12
+ recordingID: {
13
+ propDefinition: [
14
+ twilio,
15
+ "recordingID",
16
+ ],
17
+ },
18
+ limit: {
19
+ propDefinition: [
20
+ twilio,
21
+ "limit",
22
+ ],
23
+ },
24
+ },
25
+ async run({ $ }) {
26
+ const resp = await this.twilio.listRecordingTranscriptions(
27
+ this.recordingID,
28
+ omitEmptyStringValues({
29
+ limit: this.limit,
30
+ }),
31
+ );
32
+ $.export("$summary", `Successfully fetched ${resp.length} recording transcription${resp.length === 1
33
+ ? ""
34
+ : "s"} for the recording, "${this.recordingID}"`);
35
+ return resp;
36
+ },
37
+ };
@@ -0,0 +1,52 @@
1
+ import { phone } from "phone";
2
+ import twilio from "../../twilio.app.mjs";
3
+ import { callToString } from "../../common/utils.mjs";
4
+
5
+ export default {
6
+ key: "twilio-make-phone-call",
7
+ name: "Make a Phone Call",
8
+ description: "Make a phone call, passing text that Twilio will speak to the recipient of the call. [See the docs](https://www.twilio.com/docs/voice/api/call-resource#create-a-call-resource) for more information",
9
+ version: "0.1.0",
10
+ type: "action",
11
+ props: {
12
+ twilio,
13
+ from: {
14
+ propDefinition: [
15
+ twilio,
16
+ "from",
17
+ ],
18
+ },
19
+ to: {
20
+ propDefinition: [
21
+ twilio,
22
+ "to",
23
+ ],
24
+ },
25
+ text: {
26
+ label: "Text",
27
+ type: "string",
28
+ description: "The text you'd like Twilio to speak to the user when they pick up the phone.",
29
+ },
30
+ },
31
+ async run({ $ }) {
32
+ // Parse the given number into its E.164 equivalent
33
+ // The E.164 phone number will be included in the first element
34
+ // of the array, but the array will be empty if parsing fails.
35
+ // See https://www.npmjs.com/package/phone
36
+ const toParsed = phone(this.to);
37
+ console.log(toParsed);
38
+ if (!toParsed || !toParsed.phoneNumber) {
39
+ throw new Error(`Phone number ${this.to} couldn't be parsed as a valid number.`);
40
+ }
41
+
42
+ const data = {
43
+ to: toParsed.phoneNumber,
44
+ from: this.from,
45
+ twiml: `<Response><Say>${this.text}</Say></Response>`,
46
+ };
47
+
48
+ const resp = await this.twilio.getClient().calls.create(data);
49
+ $.export("$summary", `Successfully made a new phone call, "${callToString(resp)}"`);
50
+ return resp;
51
+ },
52
+ };
@@ -0,0 +1,59 @@
1
+ import { phone } from "phone";
2
+ import twilio from "../../twilio.app.mjs";
3
+ import { messageToString } from "../../common/utils.mjs";
4
+
5
+ export default {
6
+ key: "twilio-send-mms",
7
+ name: "Send MMS",
8
+ description: "Send an SMS with text and media files. [See the docs](https://www.twilio.com/docs/sms/api/message-resource#create-a-message-resource) for more information",
9
+ type: "action",
10
+ version: "0.1.0",
11
+ props: {
12
+ twilio,
13
+ from: {
14
+ propDefinition: [
15
+ twilio,
16
+ "from",
17
+ ],
18
+ },
19
+ to: {
20
+ propDefinition: [
21
+ twilio,
22
+ "to",
23
+ ],
24
+ },
25
+ body: {
26
+ propDefinition: [
27
+ twilio,
28
+ "body",
29
+ ],
30
+ },
31
+ mediaUrl: {
32
+ propDefinition: [
33
+ twilio,
34
+ "mediaUrl",
35
+ ],
36
+ },
37
+ },
38
+ async run({ $ }) {
39
+ // Parse the given number into its E.164 equivalent
40
+ // The E.164 phone number will be included in the first element
41
+ // of the array, but the array will be empty if parsing fails.
42
+ // See https://www.npmjs.com/package/phone
43
+ const toParsed = phone(this.to);
44
+ if (!toParsed || !toParsed.phoneNumber) {
45
+ throw new Error(`Phone number ${this.to} couldn't be parsed as a valid number.`);
46
+ }
47
+
48
+ const data = {
49
+ to: toParsed.phoneNumber,
50
+ from: this.from,
51
+ body: this.body,
52
+ mediaUrl: this.mediaUrl,
53
+ };
54
+
55
+ const resp = await this.twilio.getClient().messages.create(data);
56
+ $.export("$summary", `Successfully sent a new MMS, "${messageToString(resp)}"`);
57
+ return resp;
58
+ },
59
+ };
@@ -0,0 +1,52 @@
1
+ import { phone } from "phone";
2
+ import twilio from "../../twilio.app.mjs";
3
+ import { messageToString } from "../../common/utils.mjs";
4
+
5
+ export default {
6
+ key: "twilio-send-sms",
7
+ name: "Send SMS",
8
+ description: "Send a simple text-only SMS. [See the docs](https://www.twilio.com/docs/sms/api/message-resource#create-a-message-resource) for more information",
9
+ type: "action",
10
+ version: "0.1.0",
11
+ props: {
12
+ twilio,
13
+ from: {
14
+ propDefinition: [
15
+ twilio,
16
+ "from",
17
+ ],
18
+ },
19
+ to: {
20
+ propDefinition: [
21
+ twilio,
22
+ "to",
23
+ ],
24
+ },
25
+ body: {
26
+ propDefinition: [
27
+ twilio,
28
+ "body",
29
+ ],
30
+ },
31
+ },
32
+ async run({ $ }) {
33
+ // Parse the given number into its E.164 equivalent
34
+ // The E.164 phone number will be included in the first element
35
+ // of the array, but the array will be empty if parsing fails.
36
+ // See https://www.npmjs.com/package/phone
37
+ const toParsed = phone(this.to);
38
+ if (!toParsed || !toParsed.phoneNumber) {
39
+ throw new Error(`Phone number ${this.to} couldn't be parsed as a valid number.`);
40
+ }
41
+
42
+ const data = {
43
+ to: toParsed.phoneNumber,
44
+ from: this.from,
45
+ body: this.body,
46
+ };
47
+
48
+ const resp = await this.twilio.getClient().messages.create(data);
49
+ $.export("$summary", `Successfully sent a new SMS, "${messageToString(resp)}"`);
50
+ return resp;
51
+ },
52
+ };
@@ -0,0 +1,13 @@
1
+ const HTTP_METHOD = {
2
+ POST: "POST",
3
+ };
4
+
5
+ const SERVICE_TYPE = {
6
+ SMS: "sms",
7
+ VOICE: "voice",
8
+ };
9
+
10
+ export default {
11
+ HTTP_METHOD,
12
+ SERVICE_TYPE,
13
+ };
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Format a number of seconds into a time elapsed string
3
+ *
4
+ * @example
5
+ * // returns "15s"
6
+ * formatTimeElapsed(15);
7
+ *
8
+ * @example
9
+ * // returns "35min"
10
+ * formatTimeElapsed(60 * 35.5);
11
+ *
12
+ * @param {Number} seconds - the number of seconds
13
+ * @returns the formatted time elapsed string
14
+ */
15
+ function formatTimeElapsed(seconds) {
16
+ var interval = seconds / 31536000;
17
+
18
+ if (interval > 1) {
19
+ return Math.floor(interval) + " years";
20
+ }
21
+ interval = seconds / 2592000;
22
+ if (interval > 1) {
23
+ return Math.floor(interval) + " months";
24
+ }
25
+ interval = seconds / 86400;
26
+ if (interval > 1) {
27
+ return Math.floor(interval) + "d";
28
+ }
29
+ interval = seconds / 3600;
30
+ if (interval > 1) {
31
+ return Math.floor(interval) + "h";
32
+ }
33
+ interval = seconds / 60;
34
+ if (interval > 1) {
35
+ return Math.floor(interval) + "min";
36
+ }
37
+ return Math.floor(seconds) + "s";
38
+ }
39
+
40
+ /**
41
+ * Get the time between two dates as a time-elapsed string
42
+ *
43
+ * @param {Date} date1 the earlier date
44
+ * @param {Date} date2 the later date
45
+ * @returns the time elapsed between two dates
46
+ */
47
+ function timeBetween(date1, date2) {
48
+ var seconds = Math.floor((date2 - date1) / 1000);
49
+
50
+ return formatTimeElapsed(seconds);
51
+ }
52
+
53
+ /**
54
+ * Return a copy of `obj` with properties omitted whose value is an empty string
55
+ *
56
+ * @param {Object} obj - the base object
57
+ * @returns the new object
58
+ */
59
+ function omitEmptyStringValues(obj) {
60
+ return Object.fromEntries(
61
+ Object.entries(obj).filter((kVpair) => kVpair[1] !== ""),
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Return `value` if `condition` or an empty string otherwise
67
+ *
68
+ * @param {*} condition - the condition
69
+ * @param {*} value - the value to conditionally return
70
+ * @returns the value, if the condition is true, and empty string otherwise
71
+ */
72
+ function valueOrEmptyString(condition, value) {
73
+ return condition
74
+ ? value
75
+ : "";
76
+ }
77
+
78
+ /**
79
+ * Format a date as a human-readable string
80
+ *
81
+ * @example
82
+ * // returns "2021-10-01"
83
+ * formatDateString("2021-10-01T01:06:45.000Z");
84
+ *
85
+ * @param {Date|String} date - the date to format
86
+ * @returns the formatted date string
87
+ */
88
+ function formatDateString(date) {
89
+ const dateObj = new Date(date);
90
+ return dateObj.toISOString().split("T")[0];
91
+ }
92
+
93
+ /**
94
+ * Format a [Twilio Call object]{@link https://www.twilio.com/docs/voice/api/call-resource} as a
95
+ * string
96
+ *
97
+ * @param {Object} call - The Twilio Call object
98
+ * @returns the string representing a call
99
+ */
100
+ function callToString(call) {
101
+ const fromPart = valueOrEmptyString(call.fromFormatted, call.fromFormatted);
102
+ const toPart = valueOrEmptyString(call.toFormatted, ` to ${call.toFormatted}`);
103
+ const datePart = valueOrEmptyString(call.startTime, ` on ${formatDateString(call.startTime)}`);
104
+ const durationPart = valueOrEmptyString(call.duration, ` for ${formatTimeElapsed(call.duration)}`);
105
+ return fromPart + toPart + datePart + durationPart;
106
+ }
107
+
108
+ /**
109
+ * Format a [Twilio Message object]{@link https://www.twilio.com/docs/sms/api/message-resource} as a
110
+ * string
111
+ *
112
+ * @param {Object} call - The Twilio Message object
113
+ * @returns the string representing a message
114
+ */
115
+ function messageToString(message) {
116
+ const MAX_LENGTH = 30;
117
+ const messageText = message.body.length > MAX_LENGTH
118
+ ? `${message.body.slice(0, MAX_LENGTH)}...`
119
+ : message.body; // truncate long text
120
+ const messageDate = message.dateSent || message.dateCreated;
121
+ const dateString = formatDateString(messageDate);
122
+ return `${message.from} to ${message.to} on ${dateString}: ${messageText}`;
123
+ }
124
+
125
+ /**
126
+ * Format a [Twilio Recording object]{@link https://www.twilio.com/docs/voice/api/recording} as a
127
+ * string
128
+ *
129
+ * @param {Object} call - The Twilio Recording object
130
+ * @returns the string representing a recording
131
+ */
132
+ function recordingToString(recording) {
133
+ const datePart = valueOrEmptyString(recording.startTime, ` ${formatDateString(recording.startTime)}`);
134
+ const durationPart = valueOrEmptyString(recording.duration, ` - ${formatTimeElapsed(recording.duration)}`);
135
+ return datePart + durationPart;
136
+ }
137
+
138
+ export {
139
+ timeBetween,
140
+ omitEmptyStringValues,
141
+ callToString,
142
+ messageToString,
143
+ recordingToString,
144
+ };