Creating ConverationPost in discussion using rally-node - node.js

How do I go about creating a ConverationPost in an existing user story?
I can't seem to get the syntax right:
const create = {
type: 'ConversationPost',
data: {
Text: 'api test comment',
Artifact: '/hierarchicalrequirement/287838839156'
}
};
restApi.create(create)
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
})
The error is always:
{ Error: /ConversationPost/create: 401! body=undefined
at generateError (/Users/ts/Sites/node/tests/node_modules/rally/dist/request.js:38:11)
at Request._callback (/Users/ts/Sites/node/tests/node_modules/rally/dist/request.js:114:20)
at Request.self.callback (/Users/ts/Sites/node/tests/node_modules/request/request.js:185:22)
at emitTwo (events.js:126:13)
at Request.emit (events.js:214:7)
at Request.<anonymous> (/Users/ts/Sites/node/tests/node_modules/request/request.js:1161:10)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Gunzip.<anonymous> (/Users/ts/Sites/node/tests/node_modules/request/request.js:1083:12)
at Object.onceWrapper (events.js:313:30) errors: [ '/ConversationPost/create: 401! body=undefined' ] }```
When I looked at dev tools whilst manually creating a post using the Rally GUI, I see this in my request body:
{
"ConversationPost": {
"Text": "testing",
"Artifact": "/hierarchicalrequirement/287838839156"
}
}
Anyone know how to go about this?
EDIT:
Setting request debug to true shows this in the request, which looks correct:
json:
{ ConversationPost:
{ Text: 'api test comment',
Artifact: '/hierarchicalrequirement/287838839156' } },
gzip: true,
url: 'https://rally1.rallydev.com/slm/webservice/v2.0/ConversationPost/create',
qs: {},
callback: [Function],
method: 'POST' }
I should add the 401 seems odd, since I'm able to query against this user story.
I also noticed the request from the rally node module is a POST request, yet in my browser the GUI does a PUT request?

Turns out this was correct. Annoying small print is that the "ALM WSAPI Read-only" makes Rally ignore the second setting, when configuring your API key in rally.
401 error corresponds with "access denied", aka something wrong with key or key permissions.

Related

Expected argument of type "string", "stdClass" given Error

I'm using mailchimp-api-v3 for nodejs. I'm currently trying to update a user's tag but sometimes this error pops up and I have no idea what it means. I searched around but it doesn't seem like a lot of devs have encountered it.
Any suggestions are welcomed.
try {
await mailchimp.post('/lists/' + listIDUsers + '/members/' + crypto.createHash('md5').update(profileSnap.val().email.toLowerCase()).digest("hex") + '/tags', {
tags: [{name: "traveler", status: "active"}]
});
} catch (error) {
if (error.status === 404) {
await mailchimp.post('/lists/' + listIDUsers + '/members', {
email_address: profileSnap.val().email,
status: 'subscribed',
merge_fields: {
"FNAME": profileSnap.val().firstName,
"LNAME": profileSnap.val().lastName,
"UID": uid,
"EMAIL": profileSnap.val().email
},
tags: [{name: "traveler", status: "active"}]
});
} else {
console.log("Issue for: " + uid);
console.log(error);
}
The error:
Error: Expected argument of type "string", "stdClass" given
at Request._callback (/srv/node_modules/mailchimp-api-v3/index.js:506:30)
at Request.self.callback (/srv/node_modules/request/request.js:185:22)
at emitTwo (events.js:126:13)
at Request.emit (events.js:214:7)
at Request.<anonymous> (/srv/node_modules/request/request.js:1161:10)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at IncomingMessage.<anonymous> (/srv/node_modules/request/request.js:1083:12)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
Okay, I've decided to go ahead and reach out to Mailchimp since this question has been left unanswered for a few days! They got back to me stating that the reason I'm getting the error above is that because I'm trying to set a tag for a subscriber right after adding the subscriber so the system wasn’t able to successfully add the tag because the subscriber hashed id wasn’t quiet created yet.
So all I needed was the following line of code to have my function wait 10 seconds before setting the tag.
await new Promise(resolve => setTimeout(resolve, 10000));
await mailchimp.post('/lists/' + listIDUsers + '/members/' + crypto.createHash('md5').update(profileSnap.val().email.toLowerCase()).digest("hex") + '/tags', {
tags: [{name: "traveler", status: "active"}]
});

Google Cloud Function - SendGrid - 400 Bad Request

I'm trying to send an email using SendGrid in my Google Cloud Function. I have my key in the Firebase environment variables, so that's present.
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(SENDGRID_API_KEY);
Here is my GCF .ts code:
Code
const msg = {
to: to,
from: from,
subject: 'Email Subject',
content: [{
type: "text/html",
value: body
}]
};
await sgMail.send(msg)
.then(r => {
console.log(r);
});
When I trigger the function and check my logs, this is the error I get:
Error
error: { Error: Bad Request
at ResponseError (node_modules/#sendgrid/mail/node_modules/#sendgrid/helpers/classes/response-error.js:19:5)
at Request.http [as _callback] (node_modules/#sendgrid/mail/node_modules/#sendgrid/client/src/classes/client.js:124:25)
at Request.self.callback (node_modules/#sendgrid/mail/node_modules/request/request.js:185:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (node_modules/#sendgrid/mail/node_modules/request/request.js:1161:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (node_modules/#sendgrid/mail/node_modules/request/request.js:1083:12)
at IncomingMessage.g (events.js:292:16)
code: 400,
message: 'Bad Request',
response:
{ headers:
{ server: 'nginx',
date: 'Sun, 16 Dec 2018 16:27:56 GMT',
'content-type': 'application/json',
'content-length': '402',
connection: 'close',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html' },
body: { errors: [Object] } } }
Does anyone have any familiarity with this error? It mentions CORS, but that makes no sense, because it's a cloud function, not browser. The SendGrid API isn't that great, it mostly goes over the field names and provides no examples. Thanks for any help provided!
EDIT
Just to update the question, in the front end response I send myself I found a different error than the console.log(error) in the GCF logs:
"Email failed: Bad Request (400)
The from object must be provided for every email send.
It is an object that requires the email parameter,
but may also contain a name
parameter. e.g. {"email" : "example#example.com"} or
{"email" : "example#example.com", "name" : "Example Recipient"}.
from.email
http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.from"
EDIT 2: SOLUTION
My from email source comes from a document in Firestore, and I was trying to get a field that didn't exist because I was querying the wrong document, therefore from was undefined. Corrected it, as well as removed "content" in the msg object per the suggestion / answer below, and everything works fine.
According to the documentation ...the msg has the wrong elements:
const sg = require('#sendgrid/mail');
sg.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'test#example.com',
from: 'test#example.com',
subject: 'Sending with SendGrid is Fun',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
};
sg.send(msg).then(() => {
/* assume success */
})
.catch(error => {
/* log friendly error */
console.error(error.toString());
/* extract error message */
const {message, code, response} = error;
/* extract response message */
const {headers, body} = response;
});

Firebase: Delete files in Cloud Starage using Cloud Functions

I'm trying to delete all files, related to some specific entry in Realtime Database, from Cloud Storage on the entry deletion, using Cloud Functions. My functions looks as fallows:
exports.onDeleteRequest = functions.database.ref('/requests/{requestid}/').onDelete(event => {
const storage = functions.config().firebase.storageBucket;
const userId = event.data.previous.child('uid').val();
const requestId = event.params.requestid;
const path = storage + '/photos/' + userId + '/' + requestId;
console.log('path: ', path);
return gcs.bucket(path).delete().then(function() {
console.log("Files removed");
}).catch(function(error) {
console.error("Failed removing files", error);
});
});
But, I continue getting following error in log:
Failed removing files { ApiError: Not Found
at Object.parseHttpRespBody (/user_code/node_modules/#google-cloud/storage/node_modules/#google-cloud/common/src/util.js:192:30)
at Object.handleResp (/user_code/node_modules/#google-cloud/storage/node_modules/#google-cloud/common/src/util.js:132:18)
at /user_code/node_modules/#google-cloud/storage/node_modules/#google-cloud/common/src/util.js:465:12
at Request.onResponse [as _callback] (/user_code/node_modules/#google-cloud/storage/node_modules/retry-request/index.js:182:7)
at Request.self.callback (/user_code/node_modules/#google-cloud/storage/node_modules/request/request.js:186:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/#google-cloud/storage/node_modules/request/request.js:1163:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
code: 404,
errors: [ { domain: 'global', reason: 'notFound', message: 'Not Found' } ],
response: undefined,
message: 'Not Found' }
path: photos/gRplE2ujnIb93Ji5HSzEj3O4i3d2/-L-DHkKMhvLH9l6dWmR2
All subfolders are 100% existing at the time of the function execution. Can anyone help?
I apologize for asking the question, that, without a doubt, was asked before in one way or another, but I didn't find any suggestion of how to solve this issue or why does it occurs in the first place.

Cloud Functions for Firebase Image download function Error

I am building a web application using Firebase and the new feature Cloud Functions for Firebase. I have created a function that takes a URL and downloads the image into a 64-bit encoded string as below using the node modules request and request-promise-native:
module.exports = {
downloadImageFromUrl: function (url) {
var options = {
method: 'GET',
uri: url,
resolveWithFullResponse: true,
simple: false,
family: 4
};
return rp.get(options)
.then(function (res) {
return "data:" + res.headers["content-type"] + ";base64," + new Buffer(res.body).toString('base64');
})
.catch(function (error) {
console.log("ERROR GETTING image", error);
return error;
});
}
};
The top function works perfectly running locally but once on firebase it gives the error:
RequestError: Error: getaddrinfo EAI_AGAIN lh6.googleusercontent.com:443
at new RequestError (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/user_code/node_modules/request/request.js:188:22)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at Request.onRequestError (/user_code/node_modules/request/request.js:884:8)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at TLSSocket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at connectErrorNT (net.js:1020:8)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
I am calling the function in the firebase auth trigger when a user is created as below:
exports.createUser = functions.auth.user().onCreate(event => {
if (event.data.photoURL) {
utils.downloadImageFromUrl(event.data.photoURL)
.then(function(res){
console.log("User Photo", res);
})
.catch(function(error){
console.log("Error", error);
})
}
});
Any help would be greatly appreciated.
Not entirely sure yet if this is the answer, but after reading the documentation, I read their free plan which says you cannot make any out bound requests. So I guess getting an image from a Url counts as an outbound request. After I start paying for their service, I will come back to verify if this was the problem.

Loopback 3 with loopback-component-storage hang on POST file

I've a very simple server running under loopback 3 and seeing this issue again: https://github.com/strongloop/loopback-component-storage/issues/9
As the gists and examples don't work any longer I would like to reopen that issue.
I've created a very simple API templated server and added the following code:
module.exports = function (File) {
File.upload = function (ctx, options, cb) {
if (!options) options = {};
ctx.req.params.container = 'common';
console.log("DO");
File.app.models.Storage.upload(ctx.req, ctx.result, options, function (err, fileObj) {
console.log("FILE");
cb(fileObj);
});
};
File.remoteMethod(
'upload',
{
description: 'Uploads a file',
accepts: [
{arg: 'ctx', type: 'object', http: {source: 'context'}},
{arg: 'options', type: 'object', http: {source: 'query'}}
],
returns: {
arg: 'fileObject', type: 'object', root: true
},
http: {verb: 'post'}
}
);
};
The problem is now, that while posting via POSTMAN to the upload function, I see the following behavior in the console:
DO
Error: Request aborted
at IncomingMessage.<anonymous> (...../server/node_modules/formidable/lib/incoming_form.js:120:19)
at emitNone (events.js:86:13)
at IncomingMessage.emit (events.js:188:7)
at abortIncoming (_http_server.js:383:9)
at socketOnClose (_http_server.js:377:3)
at emitOne (events.js:101:20)
at Socket.emit (events.js:191:7)
at TCP._handle.close [as _onclose] (net.js:504:12)
FILE
And Postman returns an empty response...
I'm totally lost as a beginner here at this step!
What is my fault here?
Thx for any input
OMG, it seems that I've found the answer:
https://github.com/strongloop/loopback-component-storage/issues/86
Just use Header "Accept" with value "multipart/form-data", not setting "Content-type". That works for me from Postman

Resources