Sending request from hubot http listener callback, "TypeError: Cannot read property 'on' of undefined" - coffeescript

I've been having issues trying to get my hubot instance to perform an http request while in a callback from a http listener. My guess is that it is in the middle of a req/res cycle and unable to complete a different request. Usually the robot object has the http method that allows for sending one, but I keep getting "TypeError: Cannot read property 'on' of undefined" In other hubot examples I've seen online, they refer to the use of the response object, but that is only the case inside of a chat listener and indeed when I attempt to use the response object it throws an error, "TypeError: res.http is not a function". Any help is much appreciated. Thanks!
robot.router.post '/gitlab-incoming', (req, res) ->
data = {
"request_type": req.body.object_kind,
"status": req.body.object_attributes.state,
"project_name": req.body.object_attributes.source.name,
"branch_name": req.body.object_attributes.source_branch,
"job_name": 'review_stop',
"team_name": process.env.GITLAB_TEAM_NAME,
"gitlab_ci_token": process.env.GITLAB_CI_TOKEN,
"action": 'play',
"project_id": "#{process.env.GITLAB_TEAM_NAME}%2F#{req.body.object_attributes.source.name}"
}
if data['status'] == 'merged'
robot.http("https://gitlab.com/api/v4/projects/#{data['project_id']}/jobs")
.header('Accept', 'application/json')
.header('PRIVATE-TOKEN', data['gitlab_ci_token'])
.get() (err, http_res, body) ->
if err
res.send 'Sorry. Unable to fetch the list of jobs from Gitlab'
job_found = false
job_id = undefined

Related

Calling AxiosRef with method and data as empty object not working

I am working in a Nest TypeScript work where I would like to call a http request using AxiosRefby passing the method.
Means instead of calling as this.httpService.axiosRef.get(url, {headers}) I would like to invoke as this.httpService.axiosRef({method, url, headers}).
And there I am seeing some issue:
Here is my working code snippet:
async request<T = any>(creds: CredentialObj, method: Method, data: any, query?: Record<string, string>): Promise<T> {
const headers = this.getHeaders(creds);
const timeout = +(process.env.HTTP_CALL_TIMEOUT || 10000);
const url: string = `<the URL>`;
return this.httpService
.axiosRef.get(url, { headers })
.then((response: AxiosResponse<T>) => this.handleHttpResponse(response))
.catch((error: AxiosError) => this.handleHttpReject(error));
}
But If I change the axiosRef like this:
console.log(`Method: ${method}`);
console.log(`Data: ${JSON.stringify(data)}`);
return this.httpService
.axiosRef({ method, url, headers, data})
.then((response: AxiosResponse<T>) => this.handleHttpResponse(response))
.catch((error: AxiosError) => this.handleHttpReject(error));
It does not work and gives an error:
Method: get
Data: {}
Error: Request failed with status code 400
at createError (..\node_modules\axios\lib\core\createError.js:16:15)
at settle (...\nest-services\node_modules\axios\lib\core\settle.js:17:12)
at IncomingMessage.handleStreamEnd (C:\Users\pradipm\clients\CloudManager\cm_12\occm\service-infra\nest-services\node_modules\axios\lib\adapters\http.js:260:11)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1358:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
It's just an empty data object.
Actually I want to make it like this way of passing the method name such that I can use it for all REST API verbs as a common util routine. For cases other than get (e.g. post, patch) we need to pass the payload. Hence trying to make a single utility for the same.
My axios version is: "axios": "^0.21.1",

Stripe API request working with Postman but failing with Apex Rest Callout

I'm trying to make a callout to a Stripe Api with Apex. I made the exactly same request in Postman with the same Http configuration and have this working well. But when running it with Apex i get a Http 400 (Bad Request) with this error message:
{
"error": {
"message": "This property cannot be expanded (data).",
"type": "invalid_request_error"
}
}
What I want to do is to query a list of Payment Intents from stripe and expand the balance transaction stored in the payment charge data. And here is how I do it
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setHeader('Authorization', 'Bearer Token');
request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
String payload = 'expand[]=data.charges.data.balance_transaction';
request.setMethod('GET');
request.setEndpoint(API_ENDPOINT + '/v1/payment_intents');
request.setBody(payload);
HttpResponse response = http.send(request);
System.debug(response.getBody());
Can anyone help me please to understand what I am missing here?
Try expand[]=charges.data.balance_transaction Instead.

What is the proper way of detecting network errors in stream downloads using Axios in Nest.js?

I'm working with the HttpService module from Nest.js to make the HTTP calls. I'm able to download an image from https://unsplash.com; when there is no network interruptions the code is working as expected.
This is the code I have for making the download call and start writing into the desired file
const urlDownload = 'https://unsplash.com/photos/xiie4XeSzTU/download?force=true';
let response = await this.httpService.get(urlDownload, {
responseType: 'stream'
}).toPromise();
response.data.pipe(writer);
And this is the code where I'm trying to handle the possible events of the writer and returning a response
let downloadFile = path.resolve(__dirname,'../../files/landscape.jpg');
let writer = fs.createWriteStream(downloadFile);
return new Promise((resolve, reject) => {
writer.on('finish', ()=>{
resolve('Image downloaded');
});
writer.on('error', ()=>{
reject('Image downloaded failed');
});
});
I'm deliberately turning off the wifi during the download to try the server response with Image downloaded failed (what I have in the writer error handler), but instead I'm getting an 500 statusCode, internal server error. When I go to the Nest console to whatch the error it appears
[Nest] 11220 - 2020-05-22 18:16:45 [ExceptionsHandler] getaddrinfo ENOTFOUND unsplash.com +439536ms
Error: getaddrinfo ENOTFOUND unsplash.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:64:26)
How can I solve this and catch correcty the network error from Nest to return a friendly message?
I could solve it. I let it here with the hope of helping somebody in the future.
It is not firing the error handler function because that handler is attached to the writter, and there is not writting error, it just stops writing because the cut of the connection but that is not an error.
I re-writed the response variable to stop being a promise and better I started treating it like an observer.
let response = this.httpService.get(urlDownload, {
responseType: 'stream',
});
And then it is the response in previus Promise format
return new Promise((resolve, reject) => {
writer.on('error', () => {
resolve('error due to, possibly, an unexisting file path');
})
response.subscribe({
next(response) { response.data.pipe(writer) },
error(err) {
console.error('More details: ' + err);
resolve('Error in the download :/')
},
complete() { resolve('Completed'); }
})
});
I'm not using the reject function of the promise but it is perfectly doable

Implementing Handover protocol for facebook chatbot throws error

My primary receiver is my dialogflow chatbot and my second one is the page inbox. I want to switch from the chatbot to the inbox by implementing:
request({
uri: 'https://graph.facebook.com/v3.2/me/pass_thread_control',
qs: {'access_token': 'pageAccessToken'},
method: 'POST',
json: {
recipient: {
id: 'userIdFromRequest'
},
target_app_id: 'pageInboxAppId'
},
}, (error: any, response: any, body: any) => {
console.log('BODY PASS THREAD CONTROL: ', body);
});
But I'm getting this error:
(#10) Only available to Primary and Secondary Receivers
When I try to get the secondary receivers:
request({
uri: 'https://graph.facebook.com/v3.2/me/secondary_receivers?fields=id,name&access_token=<page-access-token>',
qs: {'access_token': <page-access-token>},
method: 'GET',
}, (error: any, response: any, body: any) => {
console.log('BODY SECONDARY RECEIVERS: ', body);
});
I will get this error:
(#10) Only Main Receiver can call this API
But my chatbot IS the main receiver. I set in in page settings --> messenger platform.
I found out that this used to be a facebook bug, but it should have been fixed now.
Does someone has an idea what I'm doing wrong?
UPDATE
The app_roles parameter is missing in the web hook request. May it could have something to do with it?
Another mistake could be the userId. I took the senderId. The receiverId encounters an authorization error with errorCode 1 and the message "An unknown error occurred". I'm not sure which one is correct.<
UPDATE 2
The receiverId seems to be correct. The second request works with it. But still not the first: 500 internal server error...
Suddenly, it works now. Maybe they changed anything in the backend.

Can't subscribe to publication in Meteor

I have an app with a collection, publication and subscription as follows:
collections/Cities.coffee:
#Cities = new Meteor.SmartCollection('cities')
server/publications.coffee:
Meteor.publish "userCities", -> Cities.find { userId: #userId }
client/subscriptions.coffee:
Meteor.subscribe "cities",
onReady: -> console.log 'subscription a success'
onError: (err) -> console.log 'subscription a failure', err
The subscription seems to fail, the error mentions Internal server error [500]
There is also an error when the Meteor server starts:
Exception from sub DrWAY95DFAEkjBHrY TypeError: Object function (name) { ...
} has no method '_compileSelector'
No idea where this is going wrong. I have reset the server.
As pointed out by Marco in the comments, Meteor.smartCollection is retired. Switching to regular collections solved the issue.