As simple as it may seem, I cannot seem to figure out how to set recipients of a draft with Google's Gmail API. The documentation says that a users.messages Resource object contains a payload object that contains a headers object, and that headers object contains name-value pairs.
// example from google's gmail API documentation
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": string,
"value": string
}
],
"body": users.messages.attachments Resource,
"parts": [
(MessagePart)
]
},
It is within these headers I presume you set the "To" part of a draft, since the documentation says
List of headers on this message part. For the top-level message part, representing the entire message payload, it will contain the standard RFC 2822 email headers such as To, From, and Subject.
however, when I make a request that looks something like this
"payload" : {
"headers" : [
{
"name" : "To",
"value" : "me"
// "me" should direct the draft to myself
}
]
}
the To part of the draft is still left empty. Any solution or advice?
In your request you have this:
"headers" : [ "name" : "To", "value" : "me" ]
"headers" is supposed to be an array of objects but your array contains none.
Instead, it should look like this:
"headers": [ { "name": "To", "value": "me" } ]
Just like their example:
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": "To",
"value": "me"
}
],
"body": users.messages.attachments Resource,
"parts": [
(MessagePart)
]
},
So, it appears that I was misinterpreting documentation on the Gmail API. When you send a request to drafts.create, you do need to supply is a users.messages Resource, however, not all of it is writable. Only threadId, labelIds, and raw are writable objects. As it turns out, you aren't supposed to use the payload at all to set the To, From, etc. You are supposed to include them in your raw.
My new code looks something like this
let create = (toAddress, subject, content, callback) => {
gmail.users.drafts.create(
{
'userId' : 'me',
'resource' : {
'message' : {
'raw' : base64.encodeURI(
`To:${toAddress}\r\n` + // Who were are sending to
`Subject:${subject}\r\n` + // Subject
`Date:\r\n` + // Removing timestamp
`Message-Id:\r\n` + // Removing message id
`From:\r\n` + // Removing from
`${content}` // Adding our actual message
)
}
}
},
(err, response) => {
// Do stuff with response
callback(err, response);
}
)
}
Related
I'm using Dynamoose to simplify my interactions with DynamoDB in a node.js application. I'm trying to write a query using Dynamoose's Model.query function that will search a table using an index, but it seems like Dynamoose is not including all of the info required to process the query and I'm not sure what I'm doing wrong.
Here's what the schema looks like:
const UserSchema = new dynamoose.Schema({
"user_id": {
"hashKey": true,
"type": String
},
"email": {
"type": String,
"index": {
"global": true,
"name": "email-index"
}
},
"first_name": {
"type": String,
"index": {
"global": true,
"name": "first_name-index"
}
},
"last_name": {
"type": String,
"index": {
"global": true,
"name": "last_name-index"
}
}
)
module.exports = dynamoose.model(config.usersTable, UserSchema)
I'd like to be able to search for users by their email address, so I'm writing a query that looks like this:
Users.query("email").contains(query.email)
.using("email-index")
.all()
.exec()
.then( results => {
res.status(200).json(results)
}).catch( err => {
res.status(500).send("Error searching for users: " + err)
})
I have a global secondary index defined for the email field:
When I try to execute this query, I'm getting the following error:
Error searching for users: ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.
Using the Dynamoose debugging output, I can see that the query winds up looking like this:
aws:dynamodb:query:request - {
"FilterExpression": "contains (#a0, :v0)",
"ExpressionAttributeNames": {
"#a0": "email"
},
"ExpressionAttributeValues": {
":v0": {
"S": "mel"
}
},
"TableName": "user_qa",
"IndexName": "email-index"
}
I note that the actual query sent to DynamoDB does not contain KeyConditions or KeyConditionExpression, as the error message indicates. What am I doing wrong that prevents this query from being written correctly such that it executes the query against the global secondary index I've added for this table?
As it turns out, calls like .contains(text) are used as filters, not query parameters. DynamoDB can't figure out if the text in the index contains the text I'm searching for without looking at every single record, which is a scan, not a query. So it doesn't make sense to try to use .contains(text) in this context, even though it's possible to call it in a chain like the one I constructed. What I ultimately needed to do to make this work is turn my call into a table scan with the .contains(text) filter:
Users.scan({ email: { contains: query.email }}).all().exec().then( ... )
I am not familiar with Dynamoose too much but the following code below will do an update on a record using node.JS and DynamoDB. See the key parameter I have below; by the error message you got it seems you are missing this.
To my knowledge, you must specify a key for an UPDATE request. You can checks the AWS DynamoDB docs to confirm.
var params = {
TableName: table,
Key: {
"id": customerID,
},
UpdateExpression: "set customer_name= :s, customer_address= :p, customer_phone= :u, end_date = :u",
ExpressionAttributeValues: {
":s": customer_name,
":p": customer_address,
":u": customer_phone
},
ReturnValues: "UPDATED_NEW"
};
await docClient.update(params).promise();
I am just doing a Q&A web app like SO. I want to count the number of views the page viewed by the user like SO 12 views.
I used loopback as a server and i have a model questions which contain numberOfViews property. Here is the problem that i faced, by default loopback generates /questions/{id} endpoint and this endpoint finds the question by id and returns it but in addition to returning the question i want to increment the numberOfViews property of the question. How to accomplish that?
questions model
[
{
"title": "string",
"body": "string",
"tags": [
"string"
],
"date": "string",
"numberOfViews" : 0,
"questionerId": "string",
"answers": [
"string"
],
"voteNumber": 0,
"shortComments": [
"string"
],
"usersUpVoted": [
"string"
],
"usersDownVoted": [
"string"
],
"id": "string"
}
]
Any help appreciated.
You can try hook for this purpose.
MyModel.observe('access', function logQuery(ctx, next) {
console.log('Accessing %s matching %s', ctx.Model.modelName, ctx.query.where);
next();
});
Note:
You can check what you get in ctx and use your custom condition in observe to fulfill your requirement. As i have not test it.
reference link : github , document
If you need to increment the numberOfViews property only on "findById" remote method better to use after remote hook:
Model.afterRemote('findById', (ctx, result, cb) => {
// You code here...
});
Or the same using async/await (you should return promise here, or you code freeze)
Model.afterRemote('findById', async (ctx, result) => {
// You code here...
});
I am trying to pass json payload in variables as value to start a process definition using engine-rest api as below:-
API:
http://localhost:8080/engine-rest/process-definition/processService:1:9459dbe9-6b2c-11e8-b9e8-28d2447c697a/start
Body :
{
"variables": {
"payload": {
"value": {
"mode": "email",
"meta": [{
"key": "topic",
"value": "weather"
}, {
"key": "qos",
"value": "2"
}]
},
"type": "Json"
}
}
}
but it is giving 400 BAD REQUEST with below error:-
Must provide 'null' or String value for value of SerializableValue type 'Json'.
Also i have used a expression in my BPMN process to fetch a key-value pair like below, it also throwing me error :-
${S(payload).prop("mode").stringValue() == 'email'}
Now working steps:-
when i try to send body json payload in string format then it works fine.
API:
http://localhost:8080/engine-rest/process-definition/processService:1:9459dbe9-6b2c-11e8-b9e8-28d2447c697a/start
Body:
{
"variables": {
"payload": {
"value": "{\"mode\": \"email\",\"meta\": [{\"key\": \"topic\",\"value\": \"weather\"},{\"key\": \"qos\",\"value\": \"2\"}]}",
"type": "String"
}
}
}
same java code i am using here to fetch json payload-
public void notify(DelegateExecution delegateProcessExecution) throws Exception {
Object notificationPayload =
delegateProcessExecution.getVariable("payload");
if (null != notificationPayload) {
String notifyPayload = notificationPayload.toString();
JSONObject inputJson = new JSONObject(notifyPayload);
}
// ...
}
So i want this payload as json for whole process so that i don't need to convert it to string as above working example.
You should only change the type to "json", example:
{
"variables": {
"broker": {
"value": "{\"name\":\"Broker Name\"}",
"type": "json"
}
}
}
This is by design in the rest engine API, they support other data formats, too, so it has to be an escaped JSON String, see https://app.camunda.com/jira/browse/CAM-9617.
The solution is to pass an escaped JSON String as value, as you have pointed out above. One can also use "type": "Object" if the engine has a Jackson Java Bean on the classpath that matches the given value. You supply the bean type name in a valueInfo object:
https://docs.camunda.org/manual/7.10/reference/rest/process-definition/post-start-process-instance/#request-body
For example:
{
"variables": {
"payload": {
"value": "{\"mode\": \"email\",\"meta\": [{\"key\": \"topic\",\"value\": \"weather\"},{\"key\": \"qos\",\"value\": \"2\"}]}",
"type": "String",
"valueInfo": {
"objectTypeName": "my.own.BeanWithModeAndMetaProps",
"serializationDataFormat": "application/json"
}
}
}
}
I already have declared my datasource ,my model and the connector between these.
My model
{
"name": "container",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Datasource
"storage": {
"name": "storage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "./server/storage"
}
My provider
{
"filesystem": {
"root": "./server/storage"
}
}
And the Connector
"container": {
"dataSource": "storage",
"public": true
}
I try posting a object like {"Object":"container1"} into path "./server/storage" but I get the following error from callback.
{
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Path must be a string. Received undefined",
"stack": "TypeError: Path must be a string. Received undefined.."
}
}
Please who can help me to find my issue? Thanks!
You can also use "name" instead of "Object" as key in your JSON object to create a new container/directory using the API.
POST /api/containers {"name":"container1"}
The way to post a container is, without using the loopback api. Create a folder that is gonna be the container into your provider path (being filesystem).
As simple as that!
If you need a programmatic way to add new containers, let's say for example you want to create a filesystem of sorts for new users. You can use the route below. "Container" is the name I called my Model, you can call yours whatever you'd like.
POST localhost:3000/api/container
Inside the body of the post request you have to have an attribute name and the value of the name can be the new container you're creating. The Strongloop/Loopback documentation, which can be found here, is not accurate and neither is the error you get back when you try to post it with their directions.
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Path must be a string. Received undefined"
}
An excerpt of the code to send a post request to create a new container is also below.
var request = require("request");
var options = {
method: 'POST',
url: 'http://localhost:3000/api/containers',
body: { name: 'someNewContainer' },
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
I'm trying to add users to a Custom Audience in Facebook, and I believe I have bungled the payload piece of the request below.
The error returned is:
(#100) Missing required parameter: payload
For reference, I'm generating the hash using Crypto-JS. Here's the code I tried:
var payload = { "payload": [{ "schema": "EMAIL_SHA256", "data": [hash] }]};
FB.api('/000000000/users', 'post', payload, function (response) {
if (response && !response.error) {
alert("This worked");
} else {
alert(response.error.message);
}});
The FB.api documentation shows that it expects 'payload' as a JSON object (https://developers.facebook.com/docs/marketing-api/custom-audience-targeting/v2.3#add). I just haven't been able to figure out the correct syntax yet. The example in the Facebook API documentation shows the following:
payload = {"schema":"EMAIL_SHA256","data":["HASH", "HASH", "HASH" ]}
Here's what I have so far (not working):
var payload = { "payload": [{ "schema": "EMAIL_SHA256", "data": [hash] }]};
Can anyone assist with the syntax? I've found plenty of examples of JSON objects and arrays, but I haven't seen anything that matches this format:
payload = {"schema":"EMAIL_SHA256","data":["HASH", "HASH", "HASH" ]}
For the benefit of any other JS/JSON novices, I finally figured it out after more experimentation:
var payload = { "payload": { "schema": "EMAIL_SHA256", "data": [hash] } };