I have written a custom Slash command that takes in a query from the user and returns an image.
The Server side which receives the Slash command retrieves the query from the user, and forms the Image URL http://example.com/file1.png and it sends back the response as <http://example.com/file1.png>. This is shown as a link in the response and is not unfurled. What could be the problem?
I even tried the following:
1) I sent back a JSON payload as given below:
{
"text":"http://example.com/file1.gif","unfurl_media":true
}
But that displayed the link again and did not unfurl it.
2) I tried
{
"text":"<http://example.com/file1.gif>","unfurl_media":true
}
But same results.
What could be the problem? Do I absolutely need a incoming webhook integration and send the message there ?
Did it work the first time, or had the URL previously been unfurled?
Slack will only automatically unfurl a URL once per hour in a given channel. If a user manually posts the URL and it is not unfurled because of this limit they will get an ephemeral message from SlackBot about it, however the unfurl just silently fails for slash commands or webhooks. I've hit this before in testing and had to make sure to change either the URL or the channel to verify things are working.
You should not need a manual attachment or a webhook or even the unfurl_media flag in the response (it's on by default for messages posted via webhooks/slash command).
I was having a similar issue with slash commands returning the text of my image url.
What you need to change is to use an object with an image_url for your image, and put that inside an attachments array.
Below is an example that returns the link of the image as text and the image itself.
{
"parse": "full",
"response_type": "in_channel",
"text": "http://example.com/file1.png",
"attachments":[
{
"image_url": "http://example.com/file1.png"
}
],
"unfurl_media":true,
"unfurl_links":true
}
{
"parse": "full",
"text": "http://example.com/file1.png",
"attachments":[
{
"image_url": "http://example.com/file1.png"
}
],
"unfurl_media":true,
"unfurl_links":true
}
Related
Background:
I am using the python slack API (slackclient) to build an iterative sequence of data-gathering actions in ephemeral messages.
The core of this works fine. After processing the incoming request that contains the user's interaction with a set of message buttons (or menus), I respond immediately with a JSON body, as described in the "Responding right away" section of the official slack docs.
The problem:
Every response replaces the preceding message+attachments. In many cases, this is what I want, but there are situations where I want to add a response rather than replace the previous message.
Per the slack docs,setting replace_original to false should do just that. But the following code, snipped from my handling of a simple button click (for example), replaces the original button (and the text message to which it was attached):
r = {
'response_type': 'ephemeral',
'text': 'foo',
'replace_original': 'false'
}
log.debug("Returning: {}".format(json.dumps(r)))
resp = Response(response=json.dumps(r),
mimetype="application/json",
status=200)
return resp
I have tried this with and without the delete_original and response_type fields, with no change.
In short, it appears that in this case the replace_original field isn't doing anything at all; behavior is always as if it were set to 'true'.
I feel like I must be missing something here - any help is greatly appreciated.
Simple solution here: the slack API is expecting a boolean, not a string. So 'replace_original': 'false' in the above snippet ends up as {"response_type": "ephemeral", "text": "foo", "replace_original": "false"} after the json.dumps() call, which is invalid.
Instead, setting 'replace_original': False becomes {"response_type": "ephemeral", "text": "foo", "replace_original": false}, which then has the expected behavior
I created a custom slash command in Slack. The backend code, not that it's important, is a Lambda function in Python in AWS.
My problem is that when I enter the slash command, I am the only one who can see the message. Otherwise, it works perfectly. Is there a way to get others to see the output from my custom slash command?
See "'In Channel' vs. 'Ephemeral' responses" here: https://api.slack.com/slash-commands#responding_to_a_command.
By default, the response messages sent to commands will only be
visible to the user that issued the command (we call these "ephemeral"
messages). However, if you would like the response to be visible to
all members of the channel in which the user typed the command, you
can add a response_type of in_channel to the JSON response, like this:
{
"response_type": "in_channel",
"text": "It's 80 degrees right now.",
"attachments": [
{
"text":"Partly cloudy today and tomorrow"
}
]
}
When the response_type is in_channel, both the response message and the initial message typed by the user will be shared in
the channel.
If you have a block in your JSON payload to slack (you used slacks block-kit) e.g
`"blocks": []`
you'll have to put the "response_type": "in_channel" above blocks for it to work :) e.g
{
"response_type": "in_channel",
"blocks": [....]
}
How can I make slack parse #someone mentions as links to the user instead of plaintext. I've been reading slack documentation on message formatting but still haven't figured it out. Here's an example of what I'm getting now:
{
"text": "*username:* #alexis",
"response_type": "ephemeral"
}
To make a proper "clickable" mention, you need to pass the unique user ID and not the plaintext name.
The format of the user ID is: U024BE7LHand a mention would look like this: <#U024BE7LH>
Ther user ID of the user that executed the slash command will be in the payload that slack sends to your endpoint. You can also look up user IDs by calling the users.list method, which will give you access to the user IDs of all the users in the team.
More information here
Pass the username inside <> quotes like this <#someone>
Sample
{
"text": "*username:* <#alexis>",
"response_type": "ephemeral"
}
Also if instead of user you want to notify channel then use !channel, !group , !here , or !everyone instead of #username
For eg.
{
"text": "*username:* <!channel>",
"response_type": "ephemeral"
}
slack_web_client.chat_postMessage(
channel="channel_name",
text="Hi! <#User_id>"
)
Place User ID in <> quotes and make sure that your app/bot has Scopes for commands.
Further details - https://api.slack.com/interactivity/slash-commands
I'm using Mandrill in Nodejs to send emails to customers, and want to embed an image in my html content attached to the emails. I found some solutions from https://mandrill.zendesk.com/hc/en-us/articles/205582457-Tips-for-using-images-in-Mandrill-emails and decided to use the 4th one, which includes the image inline in the html. The code is as below:
var message = {
html: htmlContent,
subject: "Subject",
...
images = [{
"type": logo.logoType, // which is "image/jpeg"
"name": "logo",
"content": content // the content is valid when using in <img src="data:image/jpeg;base64,content"> directly
}]
};
mandrillClient.messages.send({
message: message
}, function() {
callback(null);
}, function(err) {
callback(err);
})
And the corresponding html code in htmlContent is
<img src="cid:logo">
However, when I checked with the sent email in Mandrill Outbound Activity, "View Content" doesn't show the image correctly. And I looked at the html source, found the image code was still as
<img src="cid:logo">
The plain text didn't get replaced by image data.
How can I get it work properly? Any ideas?
Thanks in advance.
Finally I found it just didn't work when checking the sent email in Mandrill Outbound Activity, but it works fine in your actual email inbox. So it means you will never see the embedded image when do testing, you must send it with production api key and see the results in a real email inbox.
Just FYI. Hope no one will waste any time on this like I did. :)
I am attempting to create a course with the API, and no matter how I tweak what I am sending I keep getting back the same 404 error. I am posting the following to /d2l/api/lp/1.4/courses/ in our test instance.
{
"Name":"STLR Course-112",
"Code":"STLR.112.201420",
"Path":"",
"CourseTemplateId":22462,
"SemesterId":22460,
"StartDate":"2014-05-07T12:00:00.000Z",
"EndDate":"2014-05-07T13:00:00.000Z",
"LocaleId":null,
"ForceLocale":false,
"ShowAddressBook":false
}
I can confirm with a test instance here that this API works with data almost identical to the block you provide here. POSTing a body like this (white space added for clarity):
{"CourseTemplateId": 8082,
"LocaleId": null,
"Code": "STLR.112.201420",
"Name": "STLR Course-112",
"Path": "",
"ShowAddressBook": false,
"EndDate": "2014-05-07T13:00:00.000Z",
"StartDate": "2014-05-07T12:00:00.000Z",
"ForceLocale": false,
"SemesterId": 6984}
Gets me a 200 with a response like this (white space added for clarity):
{"Identifier":"114119",
"Name":"STLR Course-112",
"Code":"STLR.112.201420",
"IsActive":true,
"Path":"/content/enforced/114119-STLR.112.201420/",
"StartDate":"2014-05-07T12:00:00.000Z",
"EndDate":"2014-05-07T13:00:00.000Z",
"CourseTemplate":{"Identifier":"8082",
"Name":"ExtensibilityTemplate",
"Code":"EXT-TMPL"},
"Semester":{"Identifier":"6984",
"Name":"Fall 2011",
"Code":"FA2011"},
"Department":{"Identifier":"8081",
"Name":"Extensibility",
"Code":"EXT"}
}
It appears to me that the only differences between my input block and yours are the IDs provided for course template and semester, so that I could hook the new course into my local test instance instead of the IDs for those orgunits in yours. Otherwise, it appears the input properties are identical.
Some things you could look at:
Ensure you're using the right Org Unit Id values for your course template and your semester
Ensure that your LMS is configured to enforce content paths for new org units: this should then provoke the LMS to auto-create the path for you when you create a course offering; if you don't have content path enforcement on, then you might have to instead specify a valid content path for your course offering on create, and passing in an empty string probably won't be a valid path, and thus you might get a 404 back because the API service handler "can't find the content path" you've specified.
Is there a particular message that comes back with the 404?