Note that Slack’s markup language is called mrkdown (missing “a”). – Guildenstern May 6 '20 at 10:19 Rather, it's called mrkdwn (missing 'a' and 'o'). Slack just updated its longtime editor for its primary interface - and the rich-text result hints at a longstanding tension over how much of a helping hand users need from their text editors and communication programs. From a report: Power users, like programmer Arthur O'Dwyer, make the case that t.
- Slack Markup Language Translator
- Slack Markup Language Definition
- Slack Markup Language
- Types Of Markup Language
Overview
The basic syntax outlined in John Gruber’s original design document added many of the elements needed on a day-to-day basis, but it wasn’t enough for some people. That’s where extended syntax comes in.
Several individuals and organizations took it upon themselves to extend the basic syntax by adding additional elements like tables, code blocks, syntax highlighting, URL auto-linking, and footnotes. These elements can be enabled by using a lightweight markup language that builds upon the basic Markdown syntax, or by adding an extension to a compatible Markdown processor.
Availability
Not all Markdown applications support extended syntax elements. You’ll need to check whether or not the lightweight markup language your application is using supports the extended syntax elements you want to use. If it doesn’t, it may still be possible to enable extensions in your Markdown processor.
Lightweight Markup Languages
There are several lightweight markup languages that are supersets of Markdown. They include Gruber’s basic syntax and build upon it by adding additional elements like tables, code blocks, syntax highlighting, URL auto-linking, and footnotes. Many of the most popular Markdown applications use one of the following lightweight markup languages:
Markdown Processors
There are dozens of Markdown processors available. Many of them allow you to add extensions that enable extended syntax elements. Check your processor’s documentation for more information.
Tables
To add a table, use three or more hyphens (---
) to create each column’s header, and use pipes (|
) to separate each column. You can optionally add pipes on either end of the table.
The rendered output looks like this:
Syntax | Description |
---|---|
Header | Title |
Paragraph | Text |
Cell widths can vary, as shown below. The rendered output will look the same.
Alignment
You can align text in the columns to the left, right, or center by adding a colon (:
) to the left, right, or on both side of the hyphens within the header row.
The rendered output looks like this:
Syntax | Description | Test Text |
---|---|---|
Header | Title | Here’s this |
Paragraph | Text | And more |
Formatting Text in Tables
You can format the text within tables. For example, you can add links, code (words or phrases in backticks (`
) only, not code blocks), and emphasis.
You can’t add headings, blockquotes, lists, horizontal rules, images, or HTML tags.
Escaping Pipe Characters in Tables
You can display a pipe (|
) character in a table by using its HTML character code (|
).
Fenced Code Blocks
The basic Markdown syntax allows you to create code blocks by indenting lines by four spaces or one tab. If you find that inconvenient, try using fenced code blocks. Depending on your Markdown processor or editor, you’ll use three backticks (```
) or three tildes (~~~
) on the lines before and after the code block. The best part? You don’t have to indent any lines!
The rendered output looks like this:
Syntax Highlighting
Many Markdown processors support syntax highlighting for fenced code blocks. This feature allows you to add color highlighting for whatever language your code was written in. To add syntax highlighting, specify a language next to the backticks before the fenced code block.
The rendered output looks like this:
Footnotes
Footnotes allow you to add notes and references without cluttering the body of the document. When you create a footnote, a superscript number with a link appears where you added the footnote reference. Readers can click the link to jump to the content of the footnote at the bottom of the page.
To create a footnote reference, add a caret and an identifier inside brackets ([^1]
). Identifiers can be numbers or words, but they can’t contain spaces or tabs. Instal chrome on mac. Identifiers only correlate the footnote reference with the footnote itself — in the output, footnotes are numbered sequentially.
Add the footnote using another caret and number inside brackets with a colon and text ([^1]: My footnote.
). You don’t have to put footnotes at the end of the document. You can put them anywhere except inside other elements like lists, block quotes, and tables.
The rendered output looks like this:
Here’s a simple footnote,1 and here’s a longer one.2
This is the first footnote. ↩
Here’s one with multiple paragraphs and code.
Indent paragraphs to include them in the footnote.
{ my code }
Add as many paragraphs as you like. ↩
Heading IDs
Many Markdown processors support custom IDs for headings — some Markdown processors automatically add them. Adding custom IDs allows you to link directly to headings and modify them with CSS. To add a custom heading ID, enclose the custom ID in curly braces on the same line as the heading.
Slack Markup Language Translator
The HTML looks like this:
Linking to Heading IDs
You can link to headings with custom IDs in the file by creating a standard link with a number sign (#
) followed by the custom heading ID.
Markdown | HTML | Rendered Output |
---|---|---|
[Heading IDs](#heading-ids) | <a href='#heading-ids'>Heading IDs</a> | Heading IDs |
Other websites can link to the heading by adding the custom heading ID to the full URL of the webpage (e.g, [Heading IDs](https://www.markdownguide.org/extended-syntax#heading-ids)
).
Definition Lists
Some Markdown processors allow you to create definition lists of terms and their corresponding definitions. To create a definition list, type the term on the first line. On the next line, type a colon followed by a space and the definition.
The HTML looks like this:
The rendered output looks like this:
- First Term
- This is the definition of the first term.
- Second Term
- This is one definition of the second term.
- This is another definition of the second term.
Strikethrough
You can strikethrough words by putting a horizontal line through the center of them. The result looks like this. This feature allows you to indicate that certain words are a mistake not meant for inclusion in the document. To strikethrough words, use two tilde symbols (~~
) before and after the words.
The rendered output looks like this:
The world is flat. We now know that the world is round.
Task Lists
Task lists allow you to create a list of items with checkboxes. In Markdown applications that support task lists, checkboxes will be displayed next to the content. To create a task list, add dashes (-
) and brackets with a space ([ ]
) in front of task list items. To select a checkbox, add an x
in between the brackets ([x]
).
The rendered output looks like this:
Emoji
There are two ways to add emoji to Markdown files: copy and paste the emoji into your Markdown-formatted text, or type emoji shortcodes.
Copying and Pasting Emoji
In most cases, you can simply copy an emoji from a source like Emojipedia and paste it into your document. Many Markdown applications will automatically display the emoji in the Markdown-formatted text. The HTML and PDF files you export from your Markdown application should display the emoji.
Using Emoji Shortcodes
Some Markdown applications allow you to insert emoji by typing emoji shortcodes. These begin and end with a colon and include the name of an emoji.
The rendered output looks like this:
Gone camping! ⛺ Be back soon.
That is so funny! 😂
Automatic URL Linking
Many Markdown processors automatically turn URLs into links. That means if you type http://www.example.com, your Markdown processor will automatically turn it into a link even though you haven’t used brackets.
The rendered output looks like this:
Disabling Automatic URL Linking
If you don’t want a URL to be automatically linked, you can remove the link by denoting the URL as code with backticks.
The rendered output looks like this:
http://www.example.com
Take your Markdown skills to the next level.
Learn Markdown in 60 pages. Designed for both novices and experts, The Markdown Guide book is a comprehensive reference that has everything you need to get started and master Markdown syntax.
Get the BookWant to learn more Markdown?
Don't stop now! 😎 Star the GitHub repository and then enter your email address below to receive new Markdown tutorials via email. No spam!
In this tutorial, we’ll be looking at how to build a SMS-to-Slack bridge using Python and Twilio. The bridge will work in such a way that every time your Twilio phone number receives an SMS message, we’ll forward the content of the SMS message to a channel in Slack. Furthermore, any threaded replies in Slack to the message that was posted will automatically be sent as an SMS message to the originating number.
Technical requirements
To follow along, you’ll need the following:
- A free Twilio Account. If you use this link to register, you will receive $10 credit when you upgrade to a paid account.
- A free Slack account, and a Slack workspace you have administrator access to.
- Python 3
- Ngrok. This will make the development version of our application accessible over the Internet.
Creating a Python environment
Let’s create a directory where our project will reside. From the terminal, run the following command:
Next, cd
into the project directory and run the following command to create a virtual environment.
To activate the virtual environment, run the following command:
If you are using a Windows computer, then the activation command is different:
Next, we’ll need to install all the dependencies our project will need:
- Flask: a Python web framework.
- Twilio-Python: A helper library that makes it easy to interact with the Twilio API.
- Python Slack Client: A helper library for interacting with the Slack API.
- Python-dotenv: A library for importing environment variables from a
.env
file.
To install all the dependencies at once, run the following command:
Creating a Slack webhook endpoint
As part of creating the Slack bot, we need to define an endpoint where Slack can forward messages that are posted in a channel. Before we can successfully configure that endpoint, Slack needs to verify and ensure that the endpoint is valid, so we’ll begin by implementing the verification portion of our Slack endpoint.
To pass Slack’s verification, the endpoint needs to return a response with the value of a challenge
key contained in the payload Slack sends to it in the verification request. You can read more about this process here.
Create a main.py file at the root of the project’s directory and add the following code to the file:
Here, we’ve created an endpoint with the /incoming/slack
URL and specified the HTTP method to be POST
. The challenge
key is obtained from the request
object from the Flask framework and returned back as a response
in plaintext, according to the verification requirements from Slack.
Run the following command in your terminal to start the Flask application:
Setting up Ngrok
Since our application is currently local, there’s no way Slack will be able to make a POST request to the endpoint we just created. We can use Ngrok to set up a temporary public URL so that our app is accessible over the web.
Run the following command on a second terminal window to start ngrok:
In this command, 5000
refers to the port your Flask application is currently listening on.
You should now be presented with a screen similar to the one below:
Take note of the https:// “Forwarding” URL as we’ll be making use of it shortly.
Creating the Slack bot
To be able to post and receive messages on behalf of our application to a channel on Slack, we need to create a Slack bot. Head over to Slack apps and select “Create New App”. Next, you'll be prompted with a screen similar to the one below.
Assign the name “twilio-slack” to the bot, select the Slack workspace you’ll use the app on, and then click the “Create App” button.
Once the app has been created, we need to assign the right Scopes to it. Scopes define the API methods an app is allowed to call. Select “Add features and functionality” and then select the “Permissions” box:
Next, scroll down to the Scopes section and assign the following scopes to the app:
- “channels:history”
- “channels:join”
- “channels:read”
- “chat:write”
- “chat:write.customize”
- “chat:write.public”
Our Slack bot needs a way to be notified whenever a message is posted to the channel where we’ll be sending the SMS notification to. To do so, the bot needs to subscribe to an event Slack provides. Head back to the “Basic information” page, open the “Add features and functionality” dropdown and select “Event Subscriptions”. Next, toggle “Event Subscriptions” on.
For the “Request URL” field, add the forwarding URL from ngrok with the /incoming/slack
path for the endpoint we created above added at the end. Your Request URL should look like https://aa3be367.ngrok.io/incoming/slack, but note that the first part of the ngrok domain will be different in your case.
After you’ve entered the URL, Slack will send a POST request to the endpoint to verify it, so make sure both the Flask application and ngrok are running. Once the verification is achieved, scroll down to the “Subscribe to events on behalf of users” section and add the following event :
- “message.channels”
This allows our application to be notified whenever a message is posted to a channel in Slack. Next click “Save Changes”.
After you’ve saved these settings, we need to install the bot to a Slack workspace so that an API token can be generated for us. Head back to the “Basic information” page and open the “Install your app to your workspace” dropdown. Click the “Install App to Workspace” and grant the necessary permissions. Once this is done, select “OAuth & Permissions” under the “Features” tab and take note of the “Bot User OAuth Access Token” that was generated for the bot. We’ll be needing it shortly.
Setting up Twilio
Slack Markup Language Definition
After you sign up for an account on Twilio, head over to your Twilio Console and click on Phone Numbers. If you already have one or more phone numbers assigned to your account, select the number you would like to use for this project. If this is a brand new account, buy a new phone number to use on this project.
Note that if you are using a trial Twilio account you will need to verify the phone number you’ll be sending SMS messages to. You can do that here.
In the phone number configuration scroll down to the “Messaging” section and under the “A message comes in” field, use the forwarding URL from ngrok with /incoming/twilio
appended. At this point, it’s important to note this endpoint doesn’t yet exist in our application. We shall be creating it shortly.
Ensure the request method is set to HTTP POST
and then click the “Save” button at the bottom of the page to save the settings.
On your Twilio Console, take note of your Account SID and Auth Token. We are going to need these values to authenticate with the Twilio service.
Coding our bot
In the Python project, create a .env file at the root of the project’s directory and edit the file with all the credentials and settings we’ve noted thus far:
For the phone number use the canonical E.164 format. Next, in the main.py, add the following import statements at the top of the file:
Here, we’ve imported all the major dependencies our project will be needing. Next, add the following code just below the app
variable:
The slack_client
instance will be used to interact with the Slack API, while the twilio_client
will be used to interact with the Twilio API.
Forwarding SMS messages to Slack
Next, we’ll add the endpoint we configured in the Twilio SMS configuration. This function will send incoming SMS messages to Slack.
The first thing we did was to obtain the message and phone number that sent the SMS. They both come in the payload of the POST
request with a key of Body
and From
respectively.
A Slack message is then constructed and posted to the “#general” channel of our workspace using the slack_client
instance. You can change the Slack channel according to your needs.
Twilio expects the response from this endpoint should be in TWIML or Twilio Markup Language. But in this project we really have nothing to do on the Twilio side. Thankfully, the Twilio Python helper library comes bundled with some classes that make generating an empty response easy.
Sending Slack threaded replies via SMS
We’ve handled one side of our bot’s logic. The next thing to do is to handle sending out SMS messages whenever a threaded reply is written on a Slack message that was posted by the Twilio endpoint.
Edit the send_incoming_slack()
function we created earlier with the following code:
Next, add the following auxiliary functions also in the main.py
file:
Once Slack makes a POST
request to the /incoming/slack
endpoint and we determine it is not a verification message, the parse_message()
function checks to see if there’s a thread_ts
key contained in the payload. This is important, because the presence of that key indicates that the message is a threaded reply. If the key exists, the function returns the value of the thread_ts
key, the text of the threaded reply message and the id
of the channel where the message was posted. If the message was not a threaded reply, we return None
for the three values and with that the request does not have anything else to do and ends with an empty response.
When the message is a threaded reply, the get_to_number()
function is invoked. This function sends a request to the Slack API to retrieve the text of the parent message the threaded reply belongs to. A check is carried out to ensure that a subtype
key exists in the payload that was returned and has a value of bot_message
. This allows us to know that the parent message was a message from our bot.
Slack Markup Language
Next, the content of the parent message is passed as an argument to the extract_phone_number()
function. Using Python’s regular expression module, this function takes the message, and extracts each word contained in the message to a list
while ignoring punctuation marks. Based on our bot’s messaging structure, the item at index 3 is returned which will be the phone number from where the original message came from. The get_to_number()
function returns this number back to the send_incoming_slack()
function.
To complete the action of the endpoint, an SMS message with the content of the threaded reply is sent to the phone number of the original message using the twilio_client
instance.
Types Of Markup Language
Testing
To test the application make sure that you are running the Flask application and ngrok. Keep in mind that ngrok creates a different URL every time it runs, so after a restart you will need to update the Twilio endpoint in the Twilio Console and the Slack endpoint in the Slack app configuration to match the new URL assigned by ngrok. This is obviously only a concern during development, as a production deployment will use a public URL without the need to use ngrok.
To test the service, send an SMS message to your Twilio phone number from your phone. Head over to the Slack workspace on which you configured the bot and you should see the message appear in the #general channel.
Next, add a threaded reply to the message in Slack, and the message should be forwarded back to your phone in an SMS!
Conclusion
In this tutorial we’ve seen how we can build a Slack bot that receives and sends SMS messages using Python and Twilio. The GitHub repository with the complete code for this project can be found here.
Dotun Jolaoso
Website: https://dotunj.dev/
Github: https://github.com/Dotunj
Twitter: https://twitter.com/Dotunj_