@pipedream/twilio 0.3.11 → 0.4.0

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.
Files changed (27) hide show
  1. package/README.md +9 -12
  2. package/actions/check-verification-token/check-verification-token.mjs +19 -9
  3. package/actions/create-verification-service/create-verification-service.mjs +24 -0
  4. package/actions/delete-call/delete-call.mjs +3 -2
  5. package/actions/delete-message/delete-message.mjs +3 -2
  6. package/actions/download-recording-media/download-recording-media.mjs +26 -6
  7. package/actions/get-call/get-call.mjs +3 -2
  8. package/actions/get-message/get-message.mjs +3 -2
  9. package/actions/list-calls/list-calls.mjs +2 -2
  10. package/actions/list-message-media/list-message-media.mjs +3 -2
  11. package/actions/list-messages/list-messages.mjs +2 -2
  12. package/actions/list-transcripts/list-transcripts.mjs +51 -0
  13. package/actions/make-phone-call/make-phone-call.mjs +93 -3
  14. package/actions/{send-mms/send-mms.mjs → send-message/send-message.mjs} +5 -5
  15. package/actions/send-sms-verification/send-sms-verification.mjs +2 -2
  16. package/package.json +5 -3
  17. package/sources/{common-polling.mjs → common/common-polling.mjs} +17 -12
  18. package/sources/{common-webhook.mjs → common/common-webhook.mjs} +1 -8
  19. package/sources/new-call/new-call.mjs +2 -2
  20. package/sources/new-incoming-sms/new-incoming-sms.mjs +2 -2
  21. package/sources/new-phone-number/new-phone-number.mjs +2 -2
  22. package/sources/new-recording/new-recording.mjs +2 -2
  23. package/sources/new-transcript-created/new-transcript-created.mjs +52 -0
  24. package/twilio.app.mjs +46 -9
  25. package/actions/list-recording-transcriptions/list-recording-transcriptions.mjs +0 -37
  26. package/actions/send-sms/send-sms.mjs +0 -57
  27. package/sources/new-transcription/new-transcription.mjs +0 -28
package/README.md CHANGED
@@ -1,14 +1,11 @@
1
1
  # Overview
2
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
3
+ Twilio's API on Pipedream opens up a multitude of communication capabilities, allowing you to build robust, scalable, and automated workflows. With Twilio, you can send and receive SMS and MMS messages, make voice calls, and perform other communication functions programmatically. Leveraging Pipedream's seamless integration, you can connect these communications features with hundreds of other services to automate notifications, streamline customer interactions, and enhance operational efficiency.
4
+
5
+ # Example Use Cases
6
+
7
+ - **SMS Alert System for eCommerce Order Updates**: Connect Twilio with Shopify to send SMS updates to customers when their order status changes. Apply conditions to trigger messages for order confirmation, shipment tracking, and delivery notifications, adding a personal touch to the online shopping experience.
8
+
9
+ - **Automated Customer Support Ticketing**: Use Twilio with Zendesk to create a support ticket when a customer sends a text message to your Twilio number. This workflow automates the ticket generation process, ensuring that customer issues are promptly recorded and queued for support staff attention without manual entry.
10
+
11
+ - **Two-Factor Authentication (2FA) for App Security**: Integrate Twilio with your custom app's authentication system to send a one-time passcode via SMS for 2FA. Enhance security by incorporating an extra verification step, making it tougher for unauthorized users to gain access to sensitive information or accounts.
@@ -1,11 +1,12 @@
1
1
  import app from "../../twilio.app.mjs";
2
+ import { ConfigurationError } from "@pipedream/platform";
2
3
 
3
4
  export default {
4
5
  key: "twilio-check-verification-token",
5
6
  name: "Check Verification Token",
6
- description: "Check if user-provided token is correct. [See the documentation](https://www.twilio.com/docs/verify/api) for more information",
7
+ description: "Check if user-provided token is correct. [See the documentation](https://www.twilio.com/docs/verify/api)",
7
8
  type: "action",
8
- version: "0.0.1",
9
+ version: "0.0.2",
9
10
  props: {
10
11
  app,
11
12
  serviceSid: {
@@ -27,12 +28,21 @@ export default {
27
28
  },
28
29
  },
29
30
  async run({ $ }) {
30
- const res = await this.app.checkVerificationToken(
31
- this.serviceSid,
32
- this.to,
33
- this.code,
34
- );
35
- $.export("$summary", `Successfully fetched SMS verification of "${this.to}"`);
36
- return res;
31
+ try {
32
+ const res = await this.app.checkVerificationToken(
33
+ this.serviceSid,
34
+ this.to,
35
+ this.code,
36
+ );
37
+ $.export("$summary", `Verification code is ${res.valid
38
+ ? ""
39
+ : "not"} valid`);
40
+ return res;
41
+ } catch (e) {
42
+ if (e.status === 404) {
43
+ throw new ConfigurationError("Verification ID not found. Twilio deletes the verification SID once it's expired (10 minutes), approved, or the max attempts to check a code have been reached.");
44
+ }
45
+ throw new ConfigurationError(JSON.stringify(e));
46
+ }
37
47
  },
38
48
  };
@@ -0,0 +1,24 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+
3
+ export default {
4
+ key: "twilio-create-verification-service",
5
+ name: "Create Verification Service",
6
+ description: "Create a verification service for sending SMS verifications. [See the documentation](https://www.twilio.com/docs/verify/api/service#create-a-verification-service)",
7
+ type: "action",
8
+ version: "0.0.1",
9
+ props: {
10
+ twilio,
11
+ friendlyName: {
12
+ type: "string",
13
+ label: "Friendly Name",
14
+ description: "The name of the new verification service",
15
+ },
16
+ },
17
+ async run({ $ }) {
18
+ const response = await this.twilio.createVerificationService({
19
+ friendlyName: this.friendlyName,
20
+ });
21
+ $.export("$summary", `Successfully created verification service with SID: ${response.sid}"`);
22
+ return response;
23
+ },
24
+ };
@@ -3,8 +3,8 @@ import twilio from "../../twilio.app.mjs";
3
3
  export default {
4
4
  key: "twilio-delete-call",
5
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.2",
6
+ description: "Remove a call record from your account. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#delete-a-call-resource)",
7
+ version: "0.1.3",
8
8
  type: "action",
9
9
  props: {
10
10
  twilio,
@@ -13,6 +13,7 @@ export default {
13
13
  twilio,
14
14
  "sid",
15
15
  ],
16
+ optional: false,
16
17
  },
17
18
  },
18
19
  async run({ $ }) {
@@ -3,8 +3,8 @@ import twilio from "../../twilio.app.mjs";
3
3
  export default {
4
4
  key: "twilio-delete-message",
5
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.2",
6
+ description: "Delete a message record from your account. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#delete-a-message-resource)",
7
+ version: "0.1.3",
8
8
  type: "action",
9
9
  props: {
10
10
  twilio,
@@ -13,6 +13,7 @@ export default {
13
13
  twilio,
14
14
  "messageId",
15
15
  ],
16
+ optional: false,
16
17
  },
17
18
  },
18
19
  async run({ $ }) {
@@ -1,14 +1,14 @@
1
1
  import twilio from "../../twilio.app.mjs";
2
- import got from "got@12.4.1";
3
2
  import stream from "stream";
4
3
  import { promisify } from "util";
5
4
  import fs from "fs";
5
+ import { axios } from "@pipedream/platform";
6
6
 
7
7
  export default {
8
8
  key: "twilio-download-recording-media",
9
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.3",
10
+ description: "Download a recording media file. [See the documentation](https://www.twilio.com/docs/voice/api/recording#fetch-a-recording-media-file)",
11
+ version: "0.1.5",
12
12
  type: "action",
13
13
  props: {
14
14
  twilio,
@@ -27,7 +27,21 @@ export default {
27
27
  filePath: {
28
28
  type: "string",
29
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`)",
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`). Make sure to include the file extension.",
31
+ },
32
+ },
33
+ methods: {
34
+ getFileStream({
35
+ $, downloadUrl,
36
+ }) {
37
+ return axios($, {
38
+ url: downloadUrl,
39
+ auth: {
40
+ username: `${this.twilio.$auth.AccountSid}`,
41
+ password: `${this.twilio.$auth.AuthToken}`,
42
+ },
43
+ responseType: "stream",
44
+ });
31
45
  },
32
46
  },
33
47
  async run({ $ }) {
@@ -39,10 +53,16 @@ export default {
39
53
  // Add chosen download format extension (e.g. ".mp3"), as specified in the Twilio API docs:
40
54
  // https://www.twilio.com/docs/voice/api/recording#fetch-a-recording-media-file
41
55
  const downloadUrl = uri + this.format;
56
+ const fileStream = await this.getFileStream({
57
+ $,
58
+ downloadUrl,
59
+ });
42
60
  const pipeline = promisify(stream.pipeline);
43
61
  const resp = await pipeline(
44
- got.stream(downloadUrl),
45
- fs.createWriteStream(this.filePath),
62
+ fileStream,
63
+ fs.createWriteStream(this.filePath.includes("/tmp")
64
+ ? this.filePath
65
+ : `/tmp/${this.filePath}`),
46
66
  );
47
67
  $.export("$summary", `Successfully downloaded the recording media file to "${this.filePath}"`);
48
68
  return resp;
@@ -4,8 +4,8 @@ import { callToString } from "../../common/utils.mjs";
4
4
  export default {
5
5
  key: "twilio-get-call",
6
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.2",
7
+ description: "Return call resource of an individual call. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#fetch-a-call-resource)",
8
+ version: "0.1.3",
9
9
  type: "action",
10
10
  props: {
11
11
  twilio,
@@ -14,6 +14,7 @@ export default {
14
14
  twilio,
15
15
  "sid",
16
16
  ],
17
+ optional: false,
17
18
  },
18
19
  },
19
20
  async run({ $ }) {
@@ -4,8 +4,8 @@ import { messageToString } from "../../common/utils.mjs";
4
4
  export default {
5
5
  key: "twilio-get-message",
6
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.2",
7
+ description: "Return details of a message. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#fetch-a-message-resource)",
8
+ version: "0.1.3",
9
9
  type: "action",
10
10
  props: {
11
11
  twilio,
@@ -14,6 +14,7 @@ export default {
14
14
  twilio,
15
15
  "messageId",
16
16
  ],
17
+ optional: false,
17
18
  },
18
19
  },
19
20
  async run({ $ }) {
@@ -4,8 +4,8 @@ import { omitEmptyStringValues } from "../../common/utils.mjs";
4
4
  export default {
5
5
  key: "twilio-list-calls",
6
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.2",
7
+ description: "Return a list of calls associated with your account. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#read-multiple-call-resources)",
8
+ version: "0.1.3",
9
9
  type: "action",
10
10
  props: {
11
11
  twilio,
@@ -4,8 +4,8 @@ import { omitEmptyStringValues } from "../../common/utils.mjs";
4
4
  export default {
5
5
  key: "twilio-list-message-media",
6
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.2",
7
+ description: "Return a list of media associated with your message. [See the documentation](https://www.twilio.com/docs/sms/api/media-resource#read-multiple-media-resources)",
8
+ version: "0.1.3",
9
9
  type: "action",
10
10
  props: {
11
11
  twilio,
@@ -14,6 +14,7 @@ export default {
14
14
  twilio,
15
15
  "messageId",
16
16
  ],
17
+ optional: false,
17
18
  },
18
19
  limit: {
19
20
  propDefinition: [
@@ -5,8 +5,8 @@ import { omitEmptyStringValues } from "../../common/utils.mjs";
5
5
  export default {
6
6
  key: "twilio-list-messages",
7
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.3",
8
+ description: "Return a list of messages associated with your account. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#read-multiple-message-resources)",
9
+ version: "0.1.4",
10
10
  type: "action",
11
11
  props: {
12
12
  twilio,
@@ -0,0 +1,51 @@
1
+ import twilio from "../../twilio.app.mjs";
2
+ import { omitEmptyStringValues } from "../../common/utils.mjs";
3
+
4
+ export default {
5
+ key: "twilio-list-transcripts",
6
+ name: "List Transcripts",
7
+ description: "Return a list of transcripts. [See the documentation](https://www.twilio.com/docs/voice/intelligence/api/transcript-resource#fetch-multiple-transcripts)",
8
+ version: "0.0.1",
9
+ type: "action",
10
+ props: {
11
+ twilio,
12
+ includeTranscriptText: {
13
+ propDefinition: [
14
+ twilio,
15
+ "includeTranscriptText",
16
+ ],
17
+ },
18
+ limit: {
19
+ propDefinition: [
20
+ twilio,
21
+ "limit",
22
+ ],
23
+ },
24
+ },
25
+ async run({ $ }) {
26
+ let results = await this.twilio.listTranscripts(
27
+ omitEmptyStringValues({
28
+ limit: this.limit,
29
+ }),
30
+ );
31
+ if (this.includeTranscriptText) {
32
+ const transcripts = [];
33
+ for (const result of results) {
34
+ const {
35
+ sentences, transcript,
36
+ } = await this.twilio.getSentences(result.sid);
37
+ transcripts.push({
38
+ ...result,
39
+ _version: undefined,
40
+ sentences,
41
+ transcript,
42
+ });
43
+ }
44
+ results = transcripts;
45
+ }
46
+ $.export("$summary", `Successfully fetched ${results.length} transcript${results.length === 1
47
+ ? ""
48
+ : "s"}`);
49
+ return results;
50
+ },
51
+ };
@@ -5,8 +5,8 @@ import { callToString } from "../../common/utils.mjs";
5
5
  export default {
6
6
  key: "twilio-make-phone-call",
7
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.3",
8
+ description: "Make a phone call passing text, a URL, or an application that Twilio will use to handle the call. [See the documentation](https://www.twilio.com/docs/voice/api/call-resource#create-a-call-resource)",
9
+ version: "0.1.4",
10
10
  type: "action",
11
11
  props: {
12
12
  twilio,
@@ -22,11 +22,94 @@ export default {
22
22
  "to",
23
23
  ],
24
24
  },
25
+ callType: {
26
+ type: "string",
27
+ label: "Call Type",
28
+ description: "Whether to use `text`, a `URL`, or an `application` to handle the call",
29
+ options: [
30
+ {
31
+ label: "Enter text for Twilio to speak when the user picks up the phone",
32
+ value: "text",
33
+ },
34
+ {
35
+ label: "Enter a URL that returns the TwiML instructions for the call",
36
+ value: "url",
37
+ },
38
+ {
39
+ label: "Enter the SID of an Application resource that will handle the call",
40
+ value: "application",
41
+ },
42
+ ],
43
+ reloadProps: true,
44
+ },
25
45
  text: {
26
46
  label: "Text",
27
47
  type: "string",
28
48
  description: "The text you'd like Twilio to speak to the user when they pick up the phone.",
49
+ hidden: true,
29
50
  },
51
+ url: {
52
+ type: "string",
53
+ label: "URL",
54
+ description: "The absolute URL that returns the TwiML instructions for the call",
55
+ hidden: true,
56
+ },
57
+ applicationSid: {
58
+ propDefinition: [
59
+ twilio,
60
+ "applicationSid",
61
+ ],
62
+ hidden: true,
63
+ },
64
+ timeout: {
65
+ type: "integer",
66
+ label: "Timeout",
67
+ description: "The integer number of seconds that we should allow the phone to ring before assuming there is no answer. The default is `60` seconds and the maximum is `600` seconds.",
68
+ optional: true,
69
+ },
70
+ record: {
71
+ type: "boolean",
72
+ label: "Record",
73
+ description: "Whether to record the call",
74
+ optional: true,
75
+ reloadProps: true,
76
+ },
77
+ },
78
+ async additionalProps(existingProps) {
79
+ const props = {};
80
+ existingProps.text.hidden = !(this.callType === "text");
81
+ existingProps.url.hidden = !(this.callType === "url");
82
+ existingProps.applicationSid.hidden = !(this.callType === "application");
83
+ if (this.record) {
84
+ props.trim = {
85
+ type: "string",
86
+ label: "Trim",
87
+ description: "Whether to trim any leading and trailing silence from the recording",
88
+ options: [
89
+ "trim-silence",
90
+ "do-not-trim",
91
+ ],
92
+ optional: true,
93
+ };
94
+ props.recordingTrack = {
95
+ type: "string",
96
+ label: "Recording Track",
97
+ description: "The audio track to record for the call. Default is `both`.",
98
+ options: [
99
+ "inbound",
100
+ "outbound",
101
+ "both",
102
+ ],
103
+ optional: true,
104
+ };
105
+ props.recordingCallbackUrl = {
106
+ type: "string",
107
+ label: "Recording Callback URL",
108
+ description: "The URL that we call when the recording is available to be accessed",
109
+ optional: true,
110
+ };
111
+ }
112
+ return props;
30
113
  },
31
114
  async run({ $ }) {
32
115
  // Parse the given number into its E.164 equivalent
@@ -47,7 +130,14 @@ export default {
47
130
  const data = {
48
131
  to: toParsed.phoneNumber,
49
132
  from: fromParsed.phoneNumber,
50
- twiml: `<Response><Say>${this.text}</Say></Response>`,
133
+ twiml: this.text && `<Response><Say>${this.text}</Say></Response>`,
134
+ url: this.url,
135
+ applicationSid: this.applicationSid,
136
+ timeout: this.timeout,
137
+ record: this.record,
138
+ trim: this.trim,
139
+ recordingTrack: this.recordingTrack,
140
+ recordingStatusCallback: this.recordingCallbackUrl,
51
141
  };
52
142
 
53
143
  const resp = await this.twilio.getClient().calls.create(data);
@@ -3,11 +3,11 @@ import twilio from "../../twilio.app.mjs";
3
3
  import { messageToString } from "../../common/utils.mjs";
4
4
 
5
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",
6
+ key: "twilio-send-message",
7
+ name: "Send Message",
8
+ description: "Send an SMS text with optional media files. [See the documentation](https://www.twilio.com/docs/sms/api/message-resource#create-a-message-resource)",
9
9
  type: "action",
10
- version: "0.1.3",
10
+ version: "0.0.1",
11
11
  props: {
12
12
  twilio,
13
13
  from: {
@@ -58,7 +58,7 @@ export default {
58
58
  };
59
59
 
60
60
  const resp = await this.twilio.getClient().messages.create(data);
61
- $.export("$summary", `Successfully sent a new MMS, "${messageToString(resp)}"`);
61
+ $.export("$summary", `Successfully sent a new message, "${messageToString(resp)}"`);
62
62
  return resp;
63
63
  },
64
64
  };
@@ -3,9 +3,9 @@ import app from "../../twilio.app.mjs";
3
3
  export default {
4
4
  key: "twilio-send-sms-verification",
5
5
  name: "Send SMS Verification",
6
- description: "Send an SMS verification to a phone number. [See the documentation](https://www.twilio.com/docs/verify/api) for more information",
6
+ description: "Send an SMS verification to a phone number. [See the documentation](https://www.twilio.com/docs/verify/api)",
7
7
  type: "action",
8
- version: "0.0.1",
8
+ version: "0.0.2",
9
9
  props: {
10
10
  app,
11
11
  serviceSid: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/twilio",
3
- "version": "0.3.11",
3
+ "version": "0.4.0",
4
4
  "description": "Pipedream Twilio Components",
5
5
  "main": "twilio.app.mjs",
6
6
  "keywords": [
@@ -10,8 +10,10 @@
10
10
  "homepage": "https://pipedream.com/apps/twilio",
11
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
12
12
  "dependencies": {
13
- "@pipedream/platform": "^1.2.0",
14
- "phone": "^3.1.29",
13
+ "@pipedream/platform": "^3.0.0",
14
+ "got": "^13.0.0",
15
+ "phone": "^3.1.49",
16
+ "stream": "^0.0.3",
15
17
  "twilio": "^3.54.2"
16
18
  },
17
19
  "gitHead": "e12480b94cc03bed4808ebc6b13e7fdb3a1ba535",
@@ -1,4 +1,4 @@
1
- import twilio from "../twilio.app.mjs";
1
+ import twilio from "../../twilio.app.mjs";
2
2
  import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3
3
 
4
4
  export default {
@@ -23,23 +23,28 @@ export default {
23
23
  },
24
24
  emitEvent(result) {
25
25
  const meta = this.generateMeta(result);
26
+ delete result._version;
26
27
  this.$emit(result, meta);
27
28
  },
28
29
  },
29
30
  async run() {
30
- let dateCreatedAfter = this._getCreatedAfter();
31
- const params = {
31
+ const dateCreatedAfter = this._getCreatedAfter();
32
+ let newDateCreatedAfter = dateCreatedAfter;
33
+
34
+ const results = await this.listResults({
32
35
  dateCreatedAfter,
33
- };
34
- const results = await this.listResults(params);
36
+ });
37
+
35
38
  for (const result of results) {
36
- this.emitEvent(result);
37
- if (
38
- !dateCreatedAfter ||
39
- Date.parse(result.dateCreated) > Date.parse(dateCreatedAfter)
40
- )
41
- dateCreatedAfter = result.dateCreated;
39
+ const dateCreated = result.dateCreated;
40
+ const ts = Date.parse(dateCreated);
41
+ if ( !dateCreatedAfter || ts > Date.parse(dateCreatedAfter) ) {
42
+ this.emitEvent(result);
43
+ if (!dateCreatedAfter || ts > Date.parse(newDateCreatedAfter)) {
44
+ newDateCreatedAfter = dateCreated;
45
+ }
46
+ }
42
47
  }
43
- this._setCreatedAfter(dateCreatedAfter);
48
+ this._setCreatedAfter(newDateCreatedAfter);
44
49
  },
45
50
  };
@@ -1,4 +1,4 @@
1
- import twilio from "../twilio.app.mjs";
1
+ import twilio from "../../twilio.app.mjs";
2
2
 
3
3
  export default {
4
4
  props: {
@@ -9,12 +9,6 @@ export default {
9
9
  "incomingPhoneNumber",
10
10
  ],
11
11
  },
12
- authToken: {
13
- propDefinition: [
14
- twilio,
15
- "authToken",
16
- ],
17
- },
18
12
  http: {
19
13
  label: "HTTP Responder",
20
14
  description: "Exposes a `respond()` method that lets the source issue HTTP responses",
@@ -93,7 +87,6 @@ export default {
93
87
  signature,
94
88
  url: `${this.http.endpoint}/`,
95
89
  params: body,
96
- authToken: this.authToken,
97
90
  });
98
91
 
99
92
  if (!isRequestValid) {
@@ -1,4 +1,4 @@
1
- import common from "../common-webhook.mjs";
1
+ import common from "../common/common-webhook.mjs";
2
2
  import constants from "../../common/constants.mjs";
3
3
 
4
4
  export default {
@@ -6,7 +6,7 @@ export default {
6
6
  key: "twilio-new-call",
7
7
  name: "New Call (Instant)",
8
8
  description: "Emit new event each time a call to the phone number is completed. Configures a webhook in Twilio, tied to a phone number.",
9
- version: "0.1.3",
9
+ version: "0.1.4",
10
10
  type: "source",
11
11
  dedupe: "unique",
12
12
  methods: {
@@ -1,5 +1,5 @@
1
1
  import twilio from "twilio";
2
- import common from "../common-webhook.mjs";
2
+ import common from "../common/common-webhook.mjs";
3
3
  import constants from "../../common/constants.mjs";
4
4
 
5
5
  const MessagingResponse = twilio.twiml.MessagingResponse;
@@ -9,7 +9,7 @@ export default {
9
9
  key: "twilio-new-incoming-sms",
10
10
  name: "New Incoming SMS (Instant)",
11
11
  description: "Emit new event every time an SMS is sent to the phone number set. Configures a webhook in Twilio, tied to an incoming phone number.",
12
- version: "0.1.3",
12
+ version: "0.1.4",
13
13
  type: "source",
14
14
  dedupe: "unique",
15
15
  props: {
@@ -1,11 +1,11 @@
1
- import common from "../common-polling.mjs";
1
+ import common from "../common/common-polling.mjs";
2
2
 
3
3
  export default {
4
4
  ...common,
5
5
  key: "twilio-new-phone-number",
6
6
  name: "New Phone Number",
7
7
  description: "Emit new event when you add a new phone number to your account",
8
- version: "0.1.4",
8
+ version: "0.1.5",
9
9
  type: "source",
10
10
  dedupe: "unique",
11
11
  methods: {
@@ -1,11 +1,11 @@
1
- import common from "../common-polling.mjs";
1
+ import common from "../common/common-polling.mjs";
2
2
 
3
3
  export default {
4
4
  ...common,
5
5
  key: "twilio-new-recording",
6
6
  name: "New Recording",
7
7
  description: "Emit new event when a new call recording is created",
8
- version: "0.1.4",
8
+ version: "0.1.5",
9
9
  type: "source",
10
10
  dedupe: "unique",
11
11
  methods: {
@@ -0,0 +1,52 @@
1
+ import common from "../common/common-polling.mjs";
2
+
3
+ export default {
4
+ ...common,
5
+ key: "twilio-new-transcript-created",
6
+ name: "New Transcript Created",
7
+ description: "Emit new event when a new call transcript is created",
8
+ version: "0.0.1",
9
+ type: "source",
10
+ dedupe: "unique",
11
+ props: {
12
+ ...common.props,
13
+ includeTranscriptText: {
14
+ propDefinition: [
15
+ common.props.twilio,
16
+ "includeTranscriptText",
17
+ ],
18
+ },
19
+ },
20
+ methods: {
21
+ ...common.methods,
22
+ async listResults(...args) {
23
+ const results = await this.twilio.listTranscripts(...args);
24
+ if (!this.includeTranscriptText) {
25
+ return results;
26
+ }
27
+ const transcripts = [];
28
+ for (const result of results) {
29
+ const {
30
+ sentences, transcript,
31
+ } = await this.twilio.getSentences(result.sid);
32
+ transcripts.push({
33
+ ...result,
34
+ sentences,
35
+ transcript,
36
+ });
37
+ }
38
+ return transcripts;
39
+ },
40
+ generateMeta(transcript) {
41
+ const {
42
+ sid: id,
43
+ dateCreated,
44
+ } = transcript;
45
+ return {
46
+ id,
47
+ summary: `New transcript ${id}`,
48
+ ts: Date.parse(dateCreated),
49
+ };
50
+ },
51
+ },
52
+ };
package/twilio.app.mjs CHANGED
@@ -10,13 +10,6 @@ export default {
10
10
  type: "app",
11
11
  app: "twilio",
12
12
  propDefinitions: {
13
- authToken: {
14
- type: "string",
15
- secret: true,
16
- label: "Twilio Auth Token",
17
- description:
18
- "Your Twilio auth token, found [in your Twilio console](https://www.twilio.com/console). Required for validating Twilio events.",
19
- },
20
13
  body: {
21
14
  type: "string",
22
15
  label: "Message Body",
@@ -72,7 +65,7 @@ export default {
72
65
  limit: {
73
66
  type: "integer",
74
67
  label: "Limit",
75
- description: "The maximum number of results to be worked with during one execution cycle.",
68
+ description: "The maximum number of results to retrieve",
76
69
  optional: true,
77
70
  default: 50,
78
71
  },
@@ -166,10 +159,28 @@ export default {
166
159
  }));
167
160
  },
168
161
  },
162
+ includeTranscriptText: {
163
+ type: "boolean",
164
+ label: "Include Transcript Text?",
165
+ description: "Set to `true` to include the transcript sentences in the response",
166
+ optional: true,
167
+ },
168
+ applicationSid: {
169
+ type: "string",
170
+ label: "Application SID",
171
+ description: "The SID of the Application resource",
172
+ async options() {
173
+ const applications = await this.listApplications();
174
+ return applications?.map((application) => ({
175
+ label: application.friendly_name,
176
+ value: application.sid,
177
+ })) || [];
178
+ },
179
+ },
169
180
  },
170
181
  methods: {
171
182
  validateRequest({
172
- signature, url, params, authToken = this.$auth.authToken,
183
+ signature, url, params, authToken = this.$auth.AuthToken,
173
184
  } = {}) {
174
185
  // See https://www.twilio.com/docs/usage/webhooks/webhooks-security
175
186
  return twilio.validateRequest(
@@ -240,6 +251,32 @@ export default {
240
251
  const client = this.getClient();
241
252
  return client.transcriptions.list(params);
242
253
  },
254
+ listTranscripts(params) {
255
+ const client = this.getClient();
256
+ return client.intelligence.v2.transcripts.list(params);
257
+ },
258
+ listTranscriptSentences(transcriptId, params = {}) {
259
+ const client = this.getClient();
260
+ return client.intelligence.v2.transcripts(transcriptId).sentences.list(params);
261
+ },
262
+ async getSentences(transcriptId) {
263
+ const sentences = await this.listTranscriptSentences(transcriptId, {
264
+ limit: 1000,
265
+ });
266
+ const transcriptParts = sentences.map((sentence) => `Speaker ${sentence.mediaChannel} (Sentence ${sentence.sentenceIndex}):\n${sentence.transcript}\nConfidence: ${sentence.confidence}\n`);
267
+ return {
268
+ sentences,
269
+ transcript: transcriptParts.join("\n"),
270
+ };
271
+ },
272
+ listApplications(params) {
273
+ const client = this.getClient();
274
+ return client.applications.list(params);
275
+ },
276
+ createVerificationService(params) {
277
+ const client = this.getClient();
278
+ return client.verify.v2.services.create(params);
279
+ },
243
280
  /**
244
281
  * Returns a list of messages associated with your account. When getting the
245
282
  * list of all messages, results will be sorted on the DateSent field with
@@ -1,37 +0,0 @@
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.2",
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
- };
@@ -1,57 +0,0 @@
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.3",
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} could not be parsed as a valid number.`);
40
- }
41
-
42
- const fromParsed = phone(this.from);
43
- if (!fromParsed || !fromParsed.phoneNumber) {
44
- throw new Error(`Phone number ${this.from} could not be parsed as a valid number.`);
45
- }
46
-
47
- const data = {
48
- to: toParsed.phoneNumber,
49
- from: fromParsed.phoneNumber,
50
- body: this.body,
51
- };
52
-
53
- const resp = await this.twilio.getClient().messages.create(data);
54
- $.export("$summary", `Successfully sent a new SMS, "${messageToString(resp)}"`);
55
- return resp;
56
- },
57
- };
@@ -1,28 +0,0 @@
1
- import common from "../common-polling.mjs";
2
-
3
- export default {
4
- ...common,
5
- key: "twilio-new-transcription",
6
- name: "New Transcription",
7
- description: "Emit new event when a new call transcription is created",
8
- version: "0.1.4",
9
- type: "source",
10
- dedupe: "unique",
11
- methods: {
12
- ...common.methods,
13
- async listResults(...args) {
14
- return await this.twilio.listTranscriptions(...args);
15
- },
16
- generateMeta(transcription) {
17
- const {
18
- sid: id,
19
- dateCreated,
20
- } = transcription;
21
- return {
22
- id,
23
- summary: `New transcription ${id}`,
24
- ts: Date.parse(dateCreated),
25
- };
26
- },
27
- },
28
- };