How to delete ephemeral Slack message - c#

When a user uses a slash command, I post an ephemeral message to just that user. When they click a button I want that ephemeral message to either delete or update. Right now I'm just trying to get the delete part working.
In the Slack API documentation it says to send a HTTP POST to the response_url. The only response_url I get when a user clicks a button is something like this: https://hooks.slack.com/actions/XXXXXXXXX/YYYYYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ
When I send a POST to that url, I get an error(I'm not sure what the error is, I just know that my code fails on a try/catch).
The JSON I'm sending to that URL looks like this:
{
"response_type" = "ephemeral",
"replace_original" = "true",
"delete_original" = "true",
"text" = ""
};
I see in the Slack API documentation it says I should be sending that JSON to a URL that begins with https://hooks.slack.com/services/ however I'm not receiving any response_url that has the /services/.
Here is the C# code I am using to send the response:
var replaceMsg = new NameValueCollection();
replaceMsg["delete_original"] = "true";
replaceMsg["replace_original"] = "true";
replaceMsg["response_type"] = "ephemeral";
replaceMsg["text"] = "";
var responseReplace = client.UploadValues(button.response_url, "POST", replaceMsg);
Edit: It looks like I'm getting a 404 error when I try to send that
Exception: System.Net.WebException: The remote server returned an error: (404) Not Found.
However, when I paste the exact URL into my browser I don't get a 404, I see a JSON.
Can anyone guide me in the right direction? Thanks.

I did something very similar not too long ago and was able to get it working, though it was tricky.
This post helped me big time: How to remove Ephemeral Messages
I would do two things:
1) make sure you know what that POST response failure is as it may contain useful information.
2) It looks like you're sending in the string "true" instead of the boolean values, I'm guessing you probably want to send the boolean values instead:
{
"response_type" = "ephemeral",
"replace_original" = true,
"delete_original" = true,
"text" = ""
};

#theMayer and #Aaron were correct about the headers being wrong.
Setting the headers solved the issue, like so:
var client = new WebClient();
client.Headers.Add("Content-Type", "text/html");
var response = client.UploadData(button.response_url, "POST", Encoding.Default.GetBytes("{\"response_type\": \"ephemeral\",\"replace_original\": \"true\",\"delete_original\": \"true\",\"text\": \"\"}"));

Related

React - Can't fetch image from URL but works in C#

I've a problem which I find a bit weird but it is surely obvious for you guys. I'm trying to fetch an image as blob and then convert it to base64 to store it in Azure storage later on. I get the URL for the image from an object and want to download it as base64 to my react app. I'm able to get the image and put it into a html image tag as source , and it works just fine, the image shows up. On my server I can get the image via a HTTP client request and get it just fine too.
In C#:
using (var client = new HttpClient())
using (HttpResponseMessage response2 =
await client.GetAsync("URL HERE"))
{
byte[] fileContents = await response2.Content.ReadAsByteArrayAsync()>
}
When I'm trying to fetch the image in my react app like this:
const response = await fetch('URL HERE');
OR
const response = await fetch('URL HERE', {
method: 'GET',
mode: 'no-cors',
headers: {},
});
OR
let file = await fetch('URL HERE',
{
method: 'GET',
mode: 'no-cors',
})
.then((r) => r.blob())
.then((blobFile) => {
return new File([blobFile], 'FileName', { type: 'image/png' });
});
Why is this happening in React but in C# everyting works fine and how to solve it? It eaither shows as CORS-error OR the blob is empty, size 0. If I click the link I reach the image so the URL is fine too.
Any suggestions?
Many thanks!
no-cors option is rarely a good way to fix cors errors. When you use React you use browser's system and browser send you a cors errors when it not receive a correct response. For example, if your server sends you a 500 error, oftenly you will not receive the 500 error but a cors error.
Did you try to make the same request from React with Postman ? I think, if it works woth C#, it will probaly works with Postman but just to try.
Did you make some console logs like this :
let file = await fetch('url')
.then(r => {
console.log(r);
return r.blob();
)
.then((blobResponse) => {
console.log(blobResponse);
return blobResponse; // if you want to dl the file make a new File is probably not necessary : URL.createObjectURL(blob)
});
Maybe it is a real CORS error and so you should check your server and API configuration. There is a lot of issues about it on internet.
If it is, try something like this on your API response : (do not keep 'Access-Control-Allow-Origin', '*' on production)
$response->headers->set('Access-Control-Expose-Headers', 'Access-Control-*');
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Headers', '*');
$response->headers->set('Access-Control-Allow-Methods', 'HEAD, PUT, GET, POST, DELETE, OPTIONS');
$response->headers->set('Allow', 'HEAD, PUT, GET, POST, DELETE, OPTIONS');
Maybe you need too, to make a response for the OPTIONS http request. Browser send it before your request to ensure that your request will be received :
if ($request->getMethod() == 'OPTIONS') {
return $this->jsonResponse([]);
}

API GET Request Returns HTML/Text instead of JSON

This is my first time working with a RESTful API and Xamarin and etc. I have so far made a simple REST API. I have written a GET call to it that, if I write http://localhost:[num]/api/Name, it will return a JSON file of the matching Emu's information. I have tested this with Postman, so I know that it works.
I have now written an app that will call this API in order to catch this information and then display it. So far, I've got it connected to the server hosting my API, but I'm unable to get it to return JSON. Instead it seems to be returning text/HTTP.
From what I've searched up on previous Stack Overflow threads, it seems that I was missing Headers requesting that reply be in a JSON format. When I added in code that was on the official .NET documentation on Microsoft's website, it gave me issues with my Json Deserialiser. I have also added in the information in the header to make sure that it returns json.
Here is the code for the function:
async private void Submit_OnClicked(object sender, EventArgs e)
{
var nameValue = EmuName.Text;
var baseAddr = new Uri("http://my_url/HelloEmu/");
var client = new HttpClient { BaseAddress = baseAddr };
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
string url = (string)nameValue;
var returnedJson = await client.GetStringAsync(url);
Models.EmuItemModel MyEmu = JsonConvert.DeserializeObject<Models.EmuItemModel>(returnedJson);
ReturnedName.Text = MyEmu.Name;
ReturnedAge.Text = MyEmu.Age.ToString();
ReturnedWeight.Text = MyEmu.Weight.ToString();
My code actually faults on the line ReturnedWeight.Text = MyEmu.Weight.ToString()
But I'm guessing the more majour issue is occuring during deserialisng the object, because it seemingly "skips" over the preceeding two lines when I run it in the debugger.
When I run it in Visual Studio 2019, the value of "returnedJson" is this:
"<html><head><meta http-equiv=\"refresh\" content=\"0;url=http://lookup.t-mobile.com/search/?q=http://my_url/HelloEmu/Keith&t=0\"/></head><body><script>window.location=\"http://lookup.t-mobile.com/search/?q=\"+escape(window.location)+\"&r=\"+escape(document.referrer)+\"&t=0\";</script></body></html>"
I think this is an HTML output. I would love any hints about what on earth I'm doing wrong!
EDIT: Since it almost seems like the HTML is returning an error message, perhaps it could do with my url??? I've published the website using the File system method. So to access the API in Postman I'll use http://localhost:[port]/api/values, calling my website in a regular ol' browser makes it go http://my_url/HelloEmu. I get a 403 "no directory" method in return...
EDIT: Here is the Postman code:
enter image description here
Usually it happens because there are missing headers or some other malformed request, Download RestSharp DLL from NuGet, and then you can use the following, in postman, go to "Code":
And choose C# you will see a code snippet (Example):

Error deserializing JSON (invalid JSON Primitive) on windows 10 works, on server 2012 does not

I've searched all the existing question/answers concerning the error in the subject but the behaviour let me thing is not something wrong at the code rather on the machine instead.
I have the local dev machine on Windows 10 in wich the deserialization works perfectly. Once I publish on Server 2012 it blows up.
I used 3 version of the code to try to force a resolution, I can get different error messages but the result is the same, on production when try to deserialize blows up
I am using .NET framework 4 and c# with NewtonJson to handle json calls.
What I am unable to find if someone had odd behaviour on different deploy.
below the snippet
foreach(var s in ids) {
i++;
string _endpoint = sbc_url + s;
Uri _uri = new Uri(_endpoint);
WebClient wcClient = new WebClient();
wcClient.BaseAddress = _endpoint;
wcClient.Headers.Add("contentType: 'application/json; charset=utf-8'");
wcClient.Headers.Add("dataType: 'json'");
var response = wcClient.DownloadString(_endpoint);
try {
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize <Dictionary<string, dynamic>> (response); // BLOWS UP HERE
ws_ret r = new ws_ret();
foreach(var tt in dict["result"]) {
r.result.Add(tt);
}
if (r.result != null)
numeri.result.AddRange(r.result);
} catch (Exception ex) {
}
}
Setting contentType: "application/json", the request body will treated as JSON content. This is why "Invalid JSON primitive" error occurs, because of URL encoded format is not same as JSON format.
Remove:
wcClient.Headers.Add("contentType: 'application/json; charset=utf-8'");
I apologize but I've solved. The sysadmin didnt inform me that the connection was under firewall and simply the server machine was out of allowed addresses. BTW I am sure this post still make sense because as I was thinking two identical configurations there are no way to have different behaviour and if someone happen the same issue need to insist to investigate everything.
As I suspected the error message returned "Invalid JSON primitive" does not have anything to see with the permission denyed. Thanks a lot to everybody

Can I find whether maximum POST size was too large?

I send a file via POST to my ApiController.
If the file is below 2 MB, everything works like a charm.
If the file is bigger, I get a Error 404.
This is the (old) function declaration in my Controller:
[HttpPost]
public HttpResponseMessage FileUpload(HttpRequestMessage req, string entryId = "", string owner = "", int debug = 0)
{
which returns, if the entity is too large, this:
Remote Address:172.17.41.12:443
Request URL:https://webdevserver/myapp/api/Debug/FileUpload
Request Method:POST
Status Code:404 Not Found
or if it is inside the size limits, this:
Remote Address:172.17.41.12:443
Request URL:https://webdevserver/myapp/api/Debug/FileUpload
Request Method:POST
Status Code:200 OK
So I want to send a useful error message - which Error 404 definitely is NOT! - and stumbled upon HTTP Status Code 413, which IIS doesn't send automatically :( so I changed my code to:
[HttpPost]
public HttpResponseMessage FileUpload(HttpRequestMessage req=null, string entryId = "", string owner = "", int debug = 0)
{
if(req==null) {
// POST was not handed over to my function by IIS
// now is it possible to check whether file was empty or too large!? Because
return new HttpResponseMessage(HttpStatusCode.RequestEntityTooLarge);
// should only be sent if POST content was really too large!
So, how can I check whether the size of the POST data was too big or POST was empty?
According to this blog, the status code 404.13 was introduced in IIS 7 to replace the http status code 413.
Since this was done by design, I would suggest that you maintain the response as is, and in your code try to determine whether the 404 error was actually a 404.13 error.

Why does setting WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Redirect cause SecurityException?

I'm working on a Rest Service in .Net 4, and I need to perform a redirect.
A little description of what I'm doing: I have a silverlight application that contains a button. When I click the button, I send a POST request to my REST service with some information. From that information, I create a URL and (try to) redirect the browser. Here's the code for the method in the service:
[WebInvoke(Method = "POST", UriTemplate = "OpenBinder")]
public void OpenBinder(int someId)
{
string url = getUrl(someId);
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.Location = url;
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Redirect;
}
}
This seems to execute correctly, but when I call EndGetResponse on the client, I see that a "Security Error" occurred. It's System.Security.SecurityException, but I don't get any more details than that. Any ideas on what could be going on here?
Without more info, I am not sure what your specific security error is, but generally with this type of situation, your redirect should happen on the client side in the response handler. Can you restructure your code to have the client redirect?
OK, so my code was actually working correctly. When I looked through Fiddler, I noticed it was it was making the correct request to the Url. The problem was clientacesspolicy.xml was stopping it.

Categories

Resources