slack send message [ERROR] missing required field: channel - slack-api

I am trying to test sending message to channel via bot (App, to be exact.)
My query in Postman:
https://slack.com/api/chat.postMessage/ (there is token in headers)
and body
{"channel":"XXX","text":"I hope the tour went well, Mr. Wonka."}
But as result
{
"ok": false,
"error": "invalid_arguments",
"response_metadata": {
"messages": [
"[ERROR] missing required field: channel"
]
}
}

I had the same issue and my problem was that I was doing GET instead of POST. Now it works for me.

Please check your content-type header. It should be "application/json" instead of "plain/text"

I had to set
content-type: "application/json; charset=utf-8"
The charset mattered.

For myself, I was getting this because I was calling
POST https://slack.com/api/chat.postMessage/
The issue is in the last /. So the correct call is:
POST https://slack.com/api/chat.postMessage
EXTRA:
Here are my headers:
{
'Content-Type': 'application/json',
'charset': 'utf-8',
'Authorization': 'Bearer {YOUR_BOT_TOKEN_INSIDE_WITHOUT_CURLY_BRACKETS}'
}
and my body (make sure to put the # before the name of the channel).
{
'test': 'YOUR_TEXT_MESSAGE_IN_HERE',
'channel': '#{YOUR_CHANNEL_NAME_WITHOUT_CURLY_BRACKETS}'
}

Related

Use axios post to access mediawiki API

I have been using MediaWiki API for some time using properly formatted URLs, but i need to access a wiki with a required login.
I tried using fetch to make the request, and also axios, and the result is the same: the HTML page of the API, the same I would get if i just put the URL of the api in a browser.
My axios call is this:
axios.post('/wiki/api.php', {
logintoken: "this. Token",
action: "clientlogin",
username: "xxxxx",
password: "yyyyyy",
loginreturnurl: "http://localhost/",
format: "json"
}).then(function (response) {
console.log(response. Data);
})
It is as if the post request is simply not made. I tested using the Wikipedia api, and the result is the same.
Any help?
I believe you should add a ?format=json parameter?
Even though it is a post request
In the end it all came down to the fact that the MediaWiki API was expecting the parameters in the application/x-www-form-urlencoded format, and not application/json or text/plain ones.
When I changed that, I was able to login as expected, regardless of using axios or simply fetch.
The final code looks like this (token obtained via another API call):
const opts = {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({
"logintoken": this.token,
"action": "clientlogin",
"username": "username",
"password": "password",
"loginreturnurl": "http://localhost/",
"format": "json"
})
};
const res = await fetch('/wiki/api.php', opts).

I need help understanding determining Youtube username/channel name when you only have the channel ID

So according to https://developers.google.com/youtube/v3/guides/working_with_channel_ids, every account contains a unique channel ID which is independent to what used to be a username. That's all fine and dandy, as channel ID is the way to identify unique accounts. Sure, I'm all for that. Where I am confused, is when I am given a unique channel ID, how can I use this to obtain the channels preferred "username", whether it be some online alias or "real-life" name?
Specifically, I am using this API (https://developers.google.com/youtube/v3/live/docs/liveChatMessages/list?hl=en) to periodically watch as new messages are placed into my broadcast. It works, and provides data which looks like the following:
{
kind: 'youtube#liveChatMessage',
etag: 'zPV9PwBFYCiNZH_4PpspXF0ZrSs',
id: 'LCC.CikqJwoYVUNMcnBlSWl1aVF1WHphcldCZVFuc3dBEgtOaHI4d2NSUHIyQRI5ChpDTC0ybDQzcC12TUNGVVFCZlFvZDVBQUhiQRIbQ09YRjdfM2stdk1DRmZRYmZRb2QzT0FCUUEw',
snippet: {
type: 'textMessageEvent',
liveChatId: 'KicKGFVDTHJwZUlpdWlRdVh6YXJXQmVRbnN3QRILTmhyOHdjUlByMkE',
authorChannelId: 'UCLrpeIiuiQuXzarWBeQnswA',
publishedAt: '2021-11-02T23:22:37.070185+00:00',
hasDisplayContent: true,
displayMessage: 'testing once again 😀',
textMessageDetails: [Object]
}
}
As you can see, there is an authorChannelId here, which is great... Except for the fact that I can't reasonably read this as a human.
My use case is that I specifically want to have a periodically updating local app which can update me with a console message similarly formatted like so:
Bob Frank: foo bar :D
Even though I technically can have something like the following, it doesn't help me know which of my 5 friends I'm expecting in my live broadcast:
UCLrpeIiuiQuXzarWBeQnswA: foo bar :D
Ah yes... Who are you again? Can you remind me again UCLrpeIiuiQuXzarWBeQnswA?
I have also tried the following API (https://developers.google.com/youtube/v3/docs/channels/list), but it doesn't appear to give the right information either. With part: "snippet" and id: "UCLrpeIiuiQuXzarWBeQnswA" I get the following output:
{
config: {
url: 'https://youtube.googleapis.com/youtube/v3/channels?part=snippet&id=UCLrpeIiuiQuXzarWBeQnswA',
method: 'GET',
userAgentDirectives: [ [Object] ],
paramsSerializer: [Function (anonymous)],
headers: {
'x-goog-api-client': 'gdcl/5.0.5 gl-node/17.0.1 auth/7.10.1',
'Accept-Encoding': 'gzip',
'User-Agent': 'google-api-nodejs-client/5.0.5 (gzip)',
Authorization: 'Bearer',
Accept: 'application/json'
},
params: { part: 'snippet', id: 'UCLrpeIiuiQuXzarWBeQnswA' },
validateStatus: [Function (anonymous)],
retry: true,
responseType: 'json'
},
data: {
kind: 'youtube#channelListResponse',
etag: 'wjX6CX2hdUPFAc4y6OCUDDjXT6o',
pageInfo: { totalResults: 1, resultsPerPage: 5 },
items: [ [Object] ]
},
headers: {
'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
'cache-control': 'private',
connection: 'close',
'content-encoding': 'gzip',
'content-type': 'application/json; charset=UTF-8',
date: 'Wed, 03 Nov 2021 01:30:32 GMT',
server: 'scaffolding on HTTPServer2',
'transfer-encoding': 'chunked',
vary: 'Origin, X-Origin, Referer',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0'
},
status: 200,
statusText: 'OK',
request: {
responseURL: 'https://youtube.googleapis.com/youtube/v3/channels?part=snippet&id=UCLrpeIiuiQuXzarWBeQnswA'
}
}
So, any help would be greatly appreciated! Thanks!
Edit: removed access token. Whoops.
Edit2: Answer was in the question, but helped by the accepted answer below. Thank you Benjamin! The real answer is to go further into the final response above.... response.data.items[0].snippet.title. nodejs console.log() in this case did not expand each item and I totally missed this detail. My bad, I'm a novice in node and javascript. You can also use the API key as Benjamin points out, but at this point I've already got access to Oauth2 so I'll keep using the same auth.
Indeed Channels: list is the way to go.
Just by accessing and parsing the JSON at this URL https://youtube.googleapis.com/youtube/v3/channels?part=snippet&id=A_CHANNEL_ID&key=YOUR_API_KEY. It has a field "title" in its "snippet" which seems to be exactly what you want.
Of course you have to change A_CHANNEL_ID with, an authorChannelId, UCLrpeIiuiQuXzarWBeQnswA for instance.

Is there a way to change the Content Type for a Postman OAuth 2 Client Credentials request?

I'm trying to use the built in tool to get an OAuth 2.0 token for my requests. This seems pretty straightforward when reading the documentation and I set it up like this:
The issue is that the request for the token is sent with a content type of application/x-www-form-urlencoded. So the response I'm getting from the server is a 415 Unsupported Media Type I do not see a way to change the request content-type to application/json.
Am I missing something or is the only way to create a custom pre-request script?
https://github.com/oauthjs/node-oauth2-server/issues/92
application/x-www-form-urlencoded , is the supported content-type for Oauth
https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3
If you want to create , you can use pre-requisite script something like:
https://gist.github.com/madebysid/b57985b0649d3407a7aa9de1bd327990
// Refresh the access token and set it into environment variable
pm.sendRequest({
url: pm.collectionVariables.get("zoho_accounts_endpoint") + "/oauth/v2/token",
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
mode: 'urlencoded',
urlencoded: [
{key: "client_id", value: pm.collectionVariables.get("zoho_client_id"), disabled: false},
{key: "client_secret", value: pm.collectionVariables.get("zoho_client_secret"), disabled: false},
{key: "refresh_token", value: pm.collectionVariables.get("zoho_refresh_token"), disabled: false},
{key: "grant_type", value: 'refresh_token', disabled: false}
]
}
}, function (err, res) {
pm.collectionVariables.set("zoho_access_token", 'Zoho-oauthtoken ' + res.json().access_token);
});
Change it to JSON or what ever you want and store the value to a variable and use that as bearer {{token}}

Why is there "no response from server" in Swagger UI?

My API calls work correctly in Postman. But when I send requests from Swagger UI, it shows "no response from server" for all requests:
Response Body
no content
Response Code
0
Response Headers
{
"error": "no response from server"
}
What can the problem be and how to fix it?
The browser console shows these errors:
Failed to load resource: net::ERR_CONNECTION_REFUSED
Uncaught TypeError: Cannot read property 'length' of undefined
at showStatus (index.js:24)
at showErrorStatus (index.js:24)
at error (index.js:607) at spec-converter.js:533
at Request.callback (index.js:24)
at Request.crossDomainError (index.js:24)
at XMLHttpRequest.xhr.onreadystatechange (index.js:24)
net::ERR_CONNECTION_REFUSED sounds like you need to enable CORS on your localhost, so that it sends the Access-Control-Allow-Origin: * header in responses. How you do this depends on the server you use. More info here:
https://enable-cors.org/server.html
https://github.com/swagger-api/swagger-ui/#cors-support
You may also need to allow OPTIONS pre-flight requests.
Swagger returns 0 response code due to the Reference Looping in your serializer response.
Ignore the reference looping while getting the serializer response back.
If you are using Web API, use the following code
services.AddMvc()
.AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
remove schemes from swagger config json file(in my case tsoa.json) and restart the server. It worked for me.
{
"readme": "https://github.com/lukeautry/tsoa/blob/HEAD/tsoa.json",
"swagger": {
"outputDirectory": "./dist/src",
"entryFile": "./src/server.ts",
"basePath": "/",
"schemes": [
"http",
"https"
],
"securityDefinitions": {
"basic": {
"type": "basic"
}
}
},
"routes": {
"basePath": "/",
"entryFile": "./src/server.ts",
"routesDir": "./src",
"authenticationModule": "./src/security/Authentication"
}
}
In my case there was a problem with https. In swagger config the http scheme was "disabled" (not available). I had it like this:
GlobalConfiguration.Configuration.EnableSwagger(c => { c.Schemes(new[] { "https" }); });
And I had to change it to make it work in debug on localhost:
GlobalConfiguration.Configuration.EnableSwagger(c => { c.Schemes(new[] { "https", "http" }); });
The first snippet worked on production with enabled https but id didn't work while debugging in Visual Studio in default config.
In my case I was sending very simple text response e.g. "Resource not found" in the body and set Content-Type to "application/json". Depends on version Swagger has a hard time deserializing simple text to json, so im my case changing Content-Type to "text/plain" did the trick.

422 error when creating a ticket in Zendesk

I am developping an app in ASP.NET MVC5 using Zendesk_v2 (uploaded using a nuget package). I have admin rights for subdomain easynext.zendesk.com.
Here is my code for creating a ticket:
private static string requestUri = "https://easynext.zendesk.com/api/v2/tickets.json";
private static string _username = "gbalasel#easynext.be";
private static string _password = "MYPASSWORD";
private static ZendeskApi apiZendesk = new ZendeskApi(requestUri, _username, _password, "");
private void CréerTicketZendesk() {
var myTicket = apiZendesk.Tickets.CreateTicket(new Ticket()
{
Subject = "test ticket",
Priority = TicketPriorities.Low
});
}
This code sends me a 422 Unprocessable Entity error.
I have also made a test account for a client in Zendesk and the method works fine, the ticket is created in Zendesk and I also receive it in my email account.
Status 422 is most likely caused by a semantic error on your part. In my experience, ZD can return 422 most often in two situations:
When trying to PUT an update to a ticket whose status is closed. In that case, you need to create a new ticket or a follow-up ticket, if possible.
Setting an invalid value on some attribute of the ticket object or sub-object of the ticket. This can be particularly tedious to debug, as the ZD response doesn't usually tell you which attribute has an invalid value. You should check all the integer values that you are setting on the ticket. E.g., I've been burned by using the Group IDs from my production Zendesk while developing on the Sandbox System (they most likely have entirely different IDs for everything, including custom fields, groups, users, etc.).
If you are creating new tickets via POST, be sure to check all the values you are setting, as per my second bullet point above.
This telling you that you have not formed a request that it can handle; the destination script exists (otherwise you'd see a 404), the request is being handled (otherwise you'd get a 400 error) and it's been encoded correctly (or you'd get a 415 error) but the actual instruction can't be carried out.
take a look on this for more info.
Error List
just to add to the solution if anyone encounters the same problem.
requester_id is mandatory while posting the ticket json.
A sample ticket json -
{
"ticket": {
"subject": "My printer is on fire!",
"requester_id": 123,
"assignee_id": 456,
"type": "incident",
"subject": "Help, my printer is on fire!",
"description": "The fire is very colorful.",
"priority": "High",
"status": "open",
"custom_fields": [
{
"id": 111, // custom field ID
"value": "500.23"
}
]
}
}
Thanks
Yeah I run today to the same problem and solved it. The problem is that you need a comment and body part inside the ticket structure.
So this is how it could look like (in PHP):
$ticket = [
'group_id' => '35135',
'title' => 'Title',
'subject' => 'Subject',
'type' => 'ticket',
'comment' => ['body' => 'Comment text.'],
'priority' => 'normal',
'ticket_form_id' => '454524',
'custom_fields' => [
'51325351' => 'test',
],
];
Take a look on here:
https://developer.zendesk.com/rest_api/docs/core/tickets
I had an issue with the Zendesk API throwing a 422 when I was attempting to create a ticket. All parameters were correct, the problem was that the assignee for which the ticket was created for did not belong to the group.
I found this error by looking at the request response by using FIDDLER.
Adding this here in case someone else runs into this issue. For me the ticket formatting was correct, but the requester was suspended:
Error Result:
{
"error": "RecordInvalid",
"description": "Record validation errors",
"details": {
"requester": [{
"description": "Requester: jkraft is suspended."
}]
}
}
Follow these instructions to unsuspend a user: https://support.zendesk.com/hc/en-us/articles/4408835668634-How-do-I-unsuspend-access-for-a-user-
I hope this is helpful to tell whether or not you are receiving the HTTP 422 because the ticket was already closed or if its because you were trying to do something like edit a field with invald params:
If you log the response object from zendesk for the failed http 422, you can look at the response object and check its configs. In my example it was:
response: {
status: 422,
statusText: 'Unprocessable Entity',
headers: {
date: 'Wed, 01 Feb 2023 17:48:00 GMT',
'content-type': 'application/json; charset=utf-8',
'content-length': '145',
connection: 'close',
'x-zendesk-api-version': 'v2',
'x-zendesk-application-version': 'v15375',
'x-frame-options': 'SAMEORIGIN',
'zendesk-rate-limit-tickets-update': 'total=100; remaining=99; resets=60',
'x-rate-limit': '700',
'rate-limit': '700',
'x-rate-limit-remaining': '699',
'rate-limit-remaining': '699',
'rate-limit-reset': '60',
'strict-transport-security': 'max-age=31536000;',
'cache-control': 'no-cache',
'x-zendesk-origin-server': 'classic-app-server-5b7bb5f96b-2bngr',
'set-cookie': [Array],
'x-request-id': '792c83f6384a5f9a-SMF, 792c83f6384a5f9a-SMF',
'x-runtime': '0.086818',
'x-zendesk-zorg': 'yes',
'cf-cache-status': 'DYNAMIC',
'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=mwQlS2H5vr2L4HJeTbyCvhjJbRJIwwhO%2FjJFw1z5cpIkak9Oke5GtqcaWsrzIF9gnYxTnkiPAFpkBgprHoXcr2yi%2FvA7grLEoQvXeHhsSmzOnu2LslqRDbzYeeMhRRtQwIrE0uLhrZJxTzlo%2FIfcKZ4%3D"}],"group":"cf-nel","max_age":604800}',
nel: '{"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}',
server: 'cloudflare',
'cf-ray': '792c83f6384a5f9a-SMF'
},
config: {
transitional: [Object],
adapter: [Function: httpAdapter],
transformRequest: [Array],
transformResponse: [Array],
timeout: 10000,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
headers: [Object],
baseURL: 'https://***.zendesk.com/',
method: 'put',
url: '/api/v2/tickets/69519.json',
data: '{"ticket":{"status":"open","comment":{"html_body":"Follow-up Notes: \\n<p><br></p>","public":false}}}'
},
If you will notice, the 'url' and 'data' properties of the config object in my case proved I was hitting the correct api endpoint and I was also providing the correctly formatted payload. This led me to pull the tickets status and confirm it was closed, which was the source reason for the 422 response.

Resources