Use the Azure DevOps WorkItemTracking sendmail - azure-devops

I am trying to use the sendmail functionality of the Azure DevOps WorkItemTracking api; but get the error "Value cannot be null. Parameter name ClientRecipients"
It's not a field in the API - so frankly I'm lost.. https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/send-mail/send-mail?view=azure-devops-rest-7.1
Response
{"$id":"1","innerException":null,"message":"Value cannot be null.\r\nParameter name: clientRecipients","typeName":"System.ArgumentNullException, mscorlib","typeKey":"ArgumentNullException","errorCode":0,"eventId":0}
Source code
const sessionToken = await VSS.getAccessToken();
const authToken = authTokenManager.getAuthorizationHeader(sessionToken);
$.ajax({
type: 'POST',
url: `https://dev.azure.com/${organization}/${project}/_apis/wit/sendmail?api-version=7.1-preview.1`,
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
message: {
body: 'Hello World',
subject: 'My email',
to: {
tfIds: ['my-profile-id']
}
},
projectId: project
}),
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', authToken);
},
success: (e) => {
console.log(e);
},
error: (e) => {
console.error(e);
}
});
(updated to include token code)

I found through experimentation that the API requires the "cc" field to be present:
"message": {
"body" : "Test Body",
"cc" : {},
"to" : {
"tfsIds" : ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"],
},
"replyTo" : {},
"subject" : "Test Subject"
}

Related

axios is showing data in console but not posting in mongo db

Hi I am using axios to post my string and some buffer data in my mongodb server.Data is working fine with post but when I try to post data using axios it does show on console but it doesnot post data in mongo db here is my axios post code
axios.js
const formData = new FormData();
formData.append("name", this.state.name);
formData.append("title", this.state.title);
formData.append("contact", this.state.contact);
formData.append("price", this.state.price);
formData.append("description", this.state.description);
formData.append("selectedcat", this.state.selectedcat);
formData.append("selectedcity", this.state.selectedcity);
formData.append("imgforsell", this.state.imgforsell);
axios
.post(
// `http://${
// Platform.OS === "android" ? "192.168.88.45" : "localhost"
//}:4000/pets/addpets`,
'http://http://192.168.88.45:4000/pets/addpets',
formData,
{headers: { "Content-Type": "multipart/form-data" }}
)
.then(({ data }) => {
console.log(data);
})
.catch((err) => {
console.error(err.toJSON());
// res.status(500).json(err) 👈 don't do this, it's not Express
})
.finally(() => {
this.setState({
name: "",
title: "",
contact: "",
price: "",
description: "",
selectedcat: "",
selectedcity: "",
imgforsell: "",
});
});
and here is the console data
Object {
"code": undefined,
"columnNumber": undefined,
"config": Object {
"adapter": [Function xhrAdapter],
"data": "{"_parts":[["name","Saad"],["title","Pets"],["contact","12345678900"],["price","123"],["description","Post"],["selectedcat","Pets Accessories"],["selectedcity","Karachi"],["imgforsell",{"cancelled":false,"width":2160,"exif":{"DateTime":"2015:11:04 17:32:48","Software":"Adobe Photoshop CC (Windows)","XResolution":72,"ImageWidth":2160,"Orientation":0,"ImageLength":1620,"ResolutionUnit":2,"LightSource":0,"ColorSpace":1,"JPEGInterchangeFormat":302,"YResolution":72,"Compression":6,"JPEGInterchangeFormatLength":5674},"height":1620,"base64":"/9j/4QG+RXhpZgAATU0AKgAAAAgADAESAAQAAAABAAAAAAEAAAQAAAABAAAIcAEaAAUAAAABAAAAngExAAIAAAAdAAAApgICF/nat node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:388:6 in __callImmediatesat node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:132:6 in __guard$argument_0at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:365:10 in __guardat node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:131:4 in flushedQueue
update.js
const petsObject = {
name: this.state.name,
title: this.state.title,
contact: this.state.contact,
price: this.state.price,
description: this.state.description,
selectedcat:this.state.selectedcat,
imgforsell:this.state.imgforsell
};
axios
.post(
// `http://${
// Platform.OS === "android" ? "192.168.88.45" : "localhost"
// }:4000/pets/addpets`,
//'http://192.168.88.45:4000/pets/addpets/',
'http://localhost:4000/Pets/addpets/',
// formData,
petsObject,
{
headers: {
'Content-Type': 'application/json',
},
transformRequest: (formData,headers) => {
return formData; // this is doing the trick
},
},
)
.then(({ data }) => {
console.log(data);
// .then(res => {
// console.log('Data Posted',res);
// }
}
)
.catch((err) => {
console.error(err.toJSON());
// res.status(500).json(err) 👈 don't do this, it's not Express
})
.finally(() => {
this.setState({
name: "",
title: "",
contact: "",
price: "",
description: "",
selectedcat: "",
selectedcity: "",
imgforsell: "",
});
});
Have you ever checked your backend. Maybe you didn't commit the changes. You need to debug in your backend.

google People API error code: 400, Invalid JSON payload received

Hi guys am working on a projet the uses google people API to do crud operation on an authentiated user using nodejs and express server.
I was able to get all contacts, search for a particular contact and using the resoureName.
but i'm unable to create contact group or label. i have read google documentation for weeks, i am having error
here isresponse from the server
^
GaxiosError: Invalid JSON payload received. Unknown name "contactGroup[name]": Cannot bind query parameter. Field 'contactGroup[name]' could not be found in request message. at Gaxios. (D:#001ADeveloperZone\workSpaces\autmarket\node_modules\gaxios\build\src\gaxios.js:73:27)
at Generator.next ()
at fulfilled (D:#001ADeveloperZone\workSpaces\autmarket\node_modules\gaxios\build\src\gaxios.js:16:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
response: {
config: {
access_token: ',
refresh_token: '',
url: 'https://people.googleapis.com/v1/contactGroups?contactGroup%5Bname%5D=hotmail',
method: 'POST',
paramsSerializer: [Function (anonymous)],
headers: {
'Accept-Encoding': 'gzip',
'User-Agent': 'google-api-nodejs-client/0.7.2 (gzip)',
Authorization: '',
Accept: 'application/json'
},
params: [Object: null prototype] { contactGroup: { name: 'hotmail' } },
validateStatus: [Function (anonymous)],
responseType: 'json'
},
data: {
error: {
code: 400,
message: Invalid JSON payload received. Unknown name "contactGroup[name]": Cannot bind query parameter. Field 'contactGroup[name]' could not be found in request message.,
errors: [
{
message: Invalid JSON payload received. Unknown name "contactGroup[name]": Cannot bind query parameter. Field 'contactGroup[name]' could not be found in request message.,
reason: 'invalid'
}
],
status: 'INVALID_ARGUMENT',
details: [
{
'#type': 'type.googleapis.com/google.rpc.BadRequest',
fieldViolations: [Array]
}
]
}
},
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: 'Tue, 08 Mar 2022 16:27:38 GMT',
server: 'ESF',
'transfer-encoding': 'chunked',
vary: 'Origin, X-Origin, Referer',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0'
},
status: 400,
statusText: 'Bad Request'
},
config: {
access_token: ,
refresh_token: '',
url: 'https://people.googleapis.com/v1/contactGroups?contactGroup%5Bname%5D=hotmail',
method: 'POST',
paramsSerializer: [Function (anonymous)],
headers: {
'Accept-Encoding': 'gzip',
'User-Agent': 'google-api-nodejs-client/0.7.2 (gzip)',
Authorization: '',
Accept: 'application/json'
},
params: [Object: null prototype] { contactGroup: { name: 'hotmail' } },
validateStatus: [Function (anonymous)],
responseType: 'json'
},
code: 400,
errors: [
{
message: Invalid JSON payload received. Unknown name "contactGroup[name]": Cannot bind query parameter. Field 'contactGroup[name]' could not be found in request message.,
reason: 'invalid'
}
]
}
here is my code
create_group: (req, res) => {
try {
//create group or label
let userGoogleContactsGroups = getGroups().then((data) =>
JSON.parse(JSON.stringify(data))
);
let userGroups = userGoogleContactsGroups.then(({ contactGroups }) => {
let names = contactGroups.map((group) => `${group.name}`);
return names;
});
userGroups.then((data) => {
if (data.includes("amazoggn")) {
return res.status(301).json({ code: 301, mesage: "group exist" });
} else {
// let name =" amazoggn";
try {
contactGroup={
name:name
}
let strdata = JSON.parse(JSON.stringify({contactGroup}));
let mydata = people.contactGroups.create(strdata)
if (mydata) {
console.log(mydata)
} else {
return "error occured"
}
} catch (error) {
console.log(error)
}
}
});
} catch (error) {
console.log(error);
}
}
please I need help on this how do you create contact group in google people api
Looking at the docs I think you should specify a field requestBody in the call to people.contactGroups.create.
Try something like this:
const res = await people.contactGroups.create({
requestBody: {
"contactGroup": {
"name": "HelloWorld"
}
}
});

(intermediate value).sendEmail(...).promise is not a function

I'm using aws-sdk in my service to send emails. I'm getting below exception to a code which was working fine before.
const aws = require('aws-sdk');
var params = {
Destination: {
ToAddresses: [
'checkMail#gmail.com'
]
},
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: "HTML_FORMAT_BODY"
},
Text: {
Charset: "UTF-8",
Data: "this is sample"
}
},
Subject: {
Charset: 'UTF-8',
Data: 'Test email'
}
},
Source: 'AWS Services<awsEmails#awsService.com>'
ReplyToAddresses: [
'AwsServices<noreply#awsServices.com>'
],
};
// Create the promise and SES service object
var emailPromise = new aws.SES({apiVersion: '2010-12-01'}).sendEmail(params).promise();
// Handle promise's fulfilled/rejected states
emailPromise.then(
function(data) {
//my logic on success goes here
}).catch(
function(err) {
//my logic on error goes here
});
I have tried using different API calls for email from AWS but all returns the same error.
Avoid require ALL aws-sdk if it's just to use a single service. For using SES, you can yarn add #aws-sdk/client-ses and then use it const { SESClient, SendEmailCommand } = require("#aws-sdk/client-ses");
I show you here a full exemple of sending email with SES in a nodeJS lambda function:
const {
SESClient,
SendEmailCommand,
} = require("#aws-sdk/client-ses");
const REGION = "eu-west-3"; // Use you AWS region
const ses = new SESClient({ region: REGION });
exports.handler = async function (event) {
const path = event.path;
if (path === "/send-email") {
const peopleAmount = 12;
const params = {
Source: "John Wick <john.wick#killer.com>",
Destination: {
ToAddresses: ["adresse1#test.com"],
},
Message: {
Body: {
Html: {
Data: `<span>This email is about <b>${peopleAmount}</b> people.</span>`,
},
},
Subject: {
Data: "Email Title",
},
},
};
try {
const data = await ses.send(new SendEmailCommand(params));
return {
statusCode: 200,
body: peopleAmount,
};
} catch (e) {
console.error(e, e.stack);
return {
statusCode: 400,
body: "Sending failed",
};
}
}
}
I hope it helps, here is documentation to use SES email template.

Loopback 4 - POST request dtasource template

I am having issue to declare POST operation in Loopback 4 datasource file.
My template is as follows:
{
"template": {
"method": "POST",
"url": "https://reqres.in/api/login"
},
"functions": {
"login": []
}
}
My service interface
login(email: string, password: string): Promise<any>;
My Controller
#post('/loginTest')
async testingLogin(
#requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(TestModel, {
title: 'Post',
}),
},
},
})
testModel: TestModel, )
: Promise<any> {
// TEST MODEL CONTAIN JSON OBJECT {email: "" , password: ""}
console.log("Test Model Representation: ", testModel)
try {
var response = await this.loginService.login(testModel.email, testModel.password);
} catch (error) {
console.log("error", error)
}
console.log("Fake POST response", response)
return response;
};
I am using this fake API : https://reqres.in/api/login
I am getting following error:
Test Model Representation: { email: 'string', password: 'string' }
error Error: {"error":"Missing email or username"}
at callback (D:\loginApp\node_modules\loopback-connector-rest\lib\rest-builder.js:541:21)
at D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:269:22
at doNotify (D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:157:49)
at RestConnector.ObserverMixin._notifyBaseObservers (D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:180:5) {
statusCode: 400,
message: '{"error":"Missing email or username"}'
}
Fake POST response undefined
It look like my email and password is not passed ? Thanks for any help.
The login function you defined in the datasource file should match with the service interface. That means it would be something like:
"functions": {
"login": ["email", "password"]
}

Sengrid template substitution tags not replaced when sending email in Meteor app

In Meteor application that incorporates Sendgrid transaction email templates for user invitations and notifications, I can't manage to replace substitution tags. Templated email is received, but without any difference.
Email.send({
from: "hello#domain.com",
to:email,
subject: "Subject",
sub: {
"{name}":post.createdBy,
"{title}":post.title,
},
headers: {
"X-SMTPAPI": {
"filters": {
"templates": {
"settings": {
"enable": 1,
"template_id": "xxxx"
}
}
}
},
"Content-Type" : "text/html"
}
});
I'm not using API directly, but rather Meteor Email package, but don't see that possible issue:
Meteor.startup(function () {
process.env.MAIL_URL = 'smtp://username:password#smtp.sendgrid.net:587';
});
This is my shortened email template:
Hey {name},
your post {title} has a new comment.
You need to put the subs in the X-SMTPAPI header as well. The X-SMTPAPI header itself should also contain valid JSON in a string.
Try this:
var xsmtpapi = {
"filters": {
"templates": {
"settings": {
"enable": 1,
"template_id": "xxxx"
}
}
},
"sub": {
"{name}": post.createdBy,
"{title}": post.title
}
}
Email.send({
from: "hello#domain.com",
to:email,
subject: "Subject",
sub: {
"{name}":post.createdBy,
"{title}":post.title,
},
headers: {
"X-SMTPAPI": JSON.stringify(xsmtpapi),
"Content-Type" : "text/html"
}
});
What I ended up doing was using smtpapi-nodejs NPM package.
The simple example would be:
var nodemailer = require('nodemailer');
var smtpapi = require('smtpapi');
var header = new smtpapi();
header.setFilters({
"templates": {
"settings": {
"enable": 1,
"template_id": xxx-template-id-xxx
}
}
});
header.addSubstitution('-name-', post.createdBy);
header.addSubstitution(-title-', post.title);
var headers = { 'x-smtpapi': header.jsonString() };
// Use nodemailer to send the email
var settings = {
host: "smtp.sendgrid.net",
port: parseInt(587, 10),
requiresAuth: true,
auth: {
user: "sendgrid_username",
pass: "sendgrid_password"
}
};
var smtpTransport = nodemailer.createTransport(settings);
var mailOptions = {
from: "Fred Foo <foo#blurdybloop.com>",
to: "bar#blurdybloop.com",
subject: "Hello",
text: "Hello world",
html: "<b>Hello world</b>",
headers: headers
}
smtpTransport.sendMail(mailOptions, function(error, response) {
smtpTransport.close();
if (error) {
console.log(error);
} else {
console.log("Message sent: " + response.message);
}
});