Write any Node.jscodeand use anynpm package. You can alsoexport datafor use in later steps via return or this.key = 'value', pass input data to your code viaparams, and maintain state across invocations with$checkpoint.
async (event, steps) => {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
}
120
// Require iso-639-1 to convert language codes into human readable namesconstISO6391=require('iso-639-1')// Require lodash to help extract values from intermittent fields in the Tweet objectconst _ =require('lodash')// Function to return a friendly language name (or "Unknown") for ISO language codesfunctiongetLanguageName(isocode){try{returnISO6391.getName(isocode)}catch(err){return'Unknown'}}// Function to format numbers over 1000 from Stack Overflow https://stackoverflow.com/questions/9461621/format-a-number-as-2-5k-if-a-thousand-or-more-otherwise-900functionkFormatter(num){return Math.abs(num)>999? Math.sign(num)*((Math.abs(num)/1000).toFixed(1))+'k': Math.sign(num)*Math.abs(num)}// Format the Tweet (including line breaks) as a quoted Slack messageconst quotedMessage = steps.trigger.event.full_text
.split('\n').map(line=>`> ${line}`).join('\n')// Construct URLs to reference in the formatted messageconst tweetUrl =`https://twitter.com/${steps.trigger.event.user.screen_name}/statuses/${steps.trigger.event.id_str}`const userUrl =`https://twitter.com/${steps.trigger.event.user.screen_name}/`/*
Use lodash to get the URL for an image representing the media since
this object is not always present; `trigger.event.entities` will be present
when media — photos, animated GIFs or videos — are attached to the Tweet.
This object should always containt a photo, "even in cases of a video
and GIF being attached to Tweet."
https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/object-model/entities
*/const mediaUrl = _.get(steps,'trigger.event.entities.media[0].media_url_https')const mediaType = _.get(steps,'trigger.event.entities.media[0].type')// Format the message as Slack blocks - https://api.slack.com/block-kitconst blocks =[]
blocks.push({"type":"section","text":{"type":"mrkdwn","text":`*<${tweetUrl}|New Mention> by <${userUrl}|${steps.trigger.event.user.screen_name}> (${steps.trigger.event.created_at}):*\n${quotedMessage}`},"accessory":{"type":"image","image_url": steps.trigger.event.user.profile_image_url_https,"alt_text":"Profile picture"}})
console.log(mediaType)// If the Tweet contains a photo add it to the messageif(mediaUrl && mediaType ==='photo'){
blocks.push({"type":"image","image_url": mediaUrl,"alt_text":"Tweet Image"})}// Populate the context elements, button and footer
blocks.push({"type":"context","elements":[{"type":"mrkdwn","text":`*User:* ${steps.trigger.event.user.screen_name}`},{"type":"mrkdwn","text":`*Followers:* ${kFormatter(steps.trigger.event.user.followers_count)}`},{"type":"mrkdwn","text":`*Location:* ${steps.trigger.event.user.location}`},{"type":"mrkdwn","text":`*Language:* ${getLanguageName(steps.trigger.event.lang)} (${steps.trigger.event.lang})`},{"type":"mrkdwn","text":`*Description:* ${steps.trigger.event.user.description}`}]},{"type":"actions","elements":[{"type":"button","text":{"type":"plain_text","text":"View on Twitter","emoji":true},"url": tweetUrl
}]},{"type":"context","elements":[{"type":"mrkdwn","text":`Sent via <https://pipedream.com/@/${steps.trigger.context.workflow_id}|Pipedream>`}]},{"type":"divider"})return blocks
// Require iso-639-1 to convert language codes into human readable namesconstISO6391=require('iso-639-1')// Require lodash to help extract values from intermittent fields in the Tweet objectconst _ =require('lodash')// Function to return a friendly language name (or "Unknown") for ISO language codesfunctiongetLanguageName(isocode){try{returnISO6391.getName(isocode)}catch(err){return'Unknown'}}// Function to format numbers over 1000 from Stack Overflow https://stackoverflow.com/questions/9461621/format-a-number-as-2-5k-if-a-thousand-or-more-otherwise-900functionkFormatter(num){return Math.abs(num)>999? Math.sign(num)*((Math.abs(num)/1000).toFixed(1))+'k': Math.sign(num)*Math.abs(num)}// Format the Tweet (including line breaks) as a quoted Slack messageconst quotedMessage = steps.trigger.event.full_text
.split('\n').map(line=>`> ${line}`).join('\n')// Construct URLs to reference in the formatted messageconst tweetUrl =`https://twitter.com/${steps.trigger.event.user.screen_name}/statuses/${steps.trigger.event.id_str}`const userUrl =`https://twitter.com/${steps.trigger.event.user.screen_name}/`/*
Use lodash to get the URL for an image representing the media since
this object is not always present; `trigger.event.entities` will be present
when media — photos, animated GIFs or videos — are attached to the Tweet.
This object should always containt a photo, "even in cases of a video
and GIF being attached to Tweet."
https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/object-model/entities
*/const mediaUrl = _.get(steps,'trigger.event.entities.media[0].media_url_https')const mediaType = _.get(steps,'trigger.event.entities.media[0].type')// Format the message as Slack blocks - https://api.slack.com/block-kitconst blocks =[]
blocks.push({"type":"section","text":{"type":"mrkdwn","text":`*<${tweetUrl}|New Mention> by <${userUrl}|${steps.trigger.event.user.screen_name}> (${steps.trigger.event.created_at}):*\n${quotedMessage}`},"accessory":{"type":"image","image_url": steps.trigger.event.user.profile_image_url_https,"alt_text":"Profile picture"}})
console.log(mediaType)// If the Tweet contains a photo add it to the messageif(mediaUrl && mediaType ==='photo'){
blocks.push({"type":"image","image_url": mediaUrl,"alt_text":"Tweet Image"})}// Populate the context elements, button and footer
blocks.push({"type":"context","elements":[{"type":"mrkdwn","text":`*User:* ${steps.trigger.event.user.screen_name}`},{"type":"mrkdwn","text":`*Followers:* ${kFormatter(steps.trigger.event.user.followers_count)}`},{"type":"mrkdwn","text":`*Location:* ${steps.trigger.event.user.location}`},{"type":"mrkdwn","text":`*Language:* ${getLanguageName(steps.trigger.event.lang)} (${steps.trigger.event.lang})`},{"type":"mrkdwn","text":`*Description:* ${steps.trigger.event.user.description}`}]},{"type":"actions","elements":[{"type":"button","text":{"type":"plain_text","text":"View on Twitter","emoji":true},"url": tweetUrl
}]},{"type":"context","elements":[{"type":"mrkdwn","text":`Sent via <https://pipedream.com/@/${steps.trigger.context.workflow_id}|Pipedream>`}]},{"type":"divider"})return blocks