[Quickstart] Real-world Twitter -> Slack
@gettingstarted
code:
data:privatelast updated:6 months ago
today
Build integrations remarkably fast!
You're viewing a public workflow template.
Sign up to customize, add steps, modify code and more.
Join 200,000+ developers using the Pipedream platform
steps.
trigger
Search Mentions
last updated:2 months ago
steps.
generate_slack_blocks
auth
to use OAuth tokens and API keys in code via theauths object
code
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 names
const ISO6391 = require('iso-639-1')

// Require lodash to help extract values from intermittent fields in the Tweet object
const _ = require('lodash') 

// Function to return a friendly language name (or "Unknown") for ISO language codes
function getLanguageName(isocode) {
  try { return ISO6391.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-900
function kFormatter(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 message
const quotedMessage = steps.trigger.event.full_text
	.split('\n')
	.map(line => `> ${line}`)
	.join('\n')

// Construct URLs to reference in the formatted message
const 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-kit
const 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 message
if(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
steps.
send_block_kit_message

Send a message using Slack's Block Kit UI framework to a channel, group or user.

configure

Enter an array of structured blocks as a URL-encoded string. E.g., [{ "type": "section", "text": { "type": "mrkdwn", "text": "This is a mrkdwn section block :ghost: *this is bold*, and ~this is crossed out~, and <https://pipedream.com|this is a link>" }}]

Tip: Construct your blocks in a code step, return them as an array, and then pass the return value to this step.

Enter a value for blocks

Optionally provide a string for Slack to display as the new message notification (if you do not provide this, notification will be blank).

Enter a value for Notification Text

Optionally pass TRUE to post the message as the authed user, instead of as a bot. Defaults to FALSE.

Optionally customize your bot's user name (default is Pipedream). Must be used in conjunction with as_user set to false, otherwise ignored.

Enter a value for Bot Username

Optionally provide an emoji to use as the icon for this message. E.g., :fire: Overrides icon_url. Must be used in conjunction with as_user set to false, otherwise ignored.

Enter a value for Icon (emoji)

Optionally provide an image URL to use as the icon for this message. Must be used in conjunction with as_user set to false, otherwise ignored.

Enter a value for Icon (image URL)