I'm sending push notifications for android and iOS using SNS with nodejs (GCM, APNS). My payload looks like this:
const payload = {
default: body,
GCM: {
notification: {
body,
title,
},
data: {
type
},
},
APNS: {
aps: {
alert: {
title,
body,
},
},
data: {
type
},
},
};
payload.GCM = JSON.stringify(payload.GCM);
payload.APNS = JSON.stringify(payload.APNS);
return JSON.stringify(payload);
The mobile devices are getting the notifications with title and body but the type inside data is not present in the object for APNS. Is the object structure wrong?
I have created one sample index using elasticsearch and node.js with below code setup.
const { Client } = require('#elastic/elasticsearch');
const { ELASTIC_SEARCH } = require('../config');
// Elastic Search Cloud Client Setup
const elasticClient = new Client({
cloud: { id: ELASTIC_SEARCH.CLOUDID },
auth: {
apiKey: ELASTIC_SEARCH.API_KEY
}
});
async function prepareIndex() {
const merchantIndexExists = await elasticClient.indices.exists({ index: 'index2' });
if (merchantIndexExists) return;
await elasticClient.indices.create({
index: 'index2',
body: {
mappings: {
dynamic: 'strict',
properties: {
company_name: { type: 'text' },
company_email: { type: 'keyword' },
name: { type: 'text' },
price: { type: 'scaled_float', scaling_factor: 10 },
created_date: { type: 'date' },
is_delete: { type: 'boolean', doc_values: false },
merchant: { type: 'keyword', index: 'true' }
}
}
}
});
}
After index creation i have added document with below code:
const { company_name, company_email, price } = req.body;
const response = await elasticClient.index({
index: 'index2',
document: {
company_email,
company_name,
price
}
});
Now when I'm calling search API from my kibana cloud console it's returning the exact search results with all the fileds. like
But when I'm hitting same search query via code in postman it's returning blank _source. Here is the search query with postman response
const response = await elasticClient.search({
index: 'index2',
query: {
match_all: {}
}
});
Can anyone please help me out of this?
When using the Node.js ElasticSearch client, you have to wrap the query into a body property and pass it to the search.
const response = await elasticClient.search({
index: 'index2',
body: {
query: {
match_all: {}
}
}
});
I am working on a serverless/nodejs12 project. The project deploys fine, but when I try to invoke the endpoint with postman I get the following error. I have browsed through many postings of similar errors but still failed to understand what's going on. Will appreciate any pointers.
Thank you
at createError (/var/task/src/handlers/webpack:/home/serverless-workspace/notification/node_modules/#middy/util/index.js:259:1)
at validatorMiddlewareBefore (/var/task/src/handlers/webpack:/home/serverless-workspace/notification/node_modules/#middy/validator/index.js:55:1)
at runMiddlewares (/var/task/src/handlers/webpack:/home/serverless-workspace/notification/node_modules/#middy/core/index.js:120:1)
at runRequest (/var/task/src/handlers/webpack:/home/serverless-workspace/notification/node_modules/#middy/core/index.js:80:1) {
details: [
{
instancePath: '/body',
schemaPath: '#/properties/body/type',
keyword: 'type',
params: [Object],
message: 'must be object'
}
]
createNotification.js
--------------------------
async function createNotification(event, context) {
const { title } = event.body;
const { destination } = event.body;
const { destinationType } = event.body
const notification = {
id: uuid(),
title,
destination,
destinationType,
status: 'OPEN',
createdAt: new Date().toISOString(),
}
try {
await dynamodb.put({
TableName: process.env.NOTIFY_TABLE_NAME,
Item: notification
}).promise();
} catch (error) {
console.error(error);
throw new createError.InternalServerError(error);
}
return {
statusCode: 200,
body: JSON.stringify(notification),
};
}
export const handler = commonMiddleware(createNotification)
.use(validator({ inputSchema: createNotificationSchema }));
and the schema
----------------------
const schema = {
type: 'object',
properties: {
body: {
type: 'object',
required: ['status'],
default: { status: 'OPEN' },
properties: {
status: {
default: 'OPEN',
enum: ['OPEN', 'CLOSED'],
},
},
},
},
required: ['body'],
};
export default schema;
You're getting the error must be object. I'm guessing your input looks like { event: { body: 'JSON string' } }. You'll need to use another middy middleware to parse the body prior to validating the input. Which middleware will depend on what AWS event it's expecting. Middy >3.0.0 supports all AWS events.
I want to intercept all the messages exchanged between user and bot. PFB code that I have used to intercept. I am using Bot Diaolog framework for webchat. Here the issue is I am not able to extract values from activities object which contains messages sent from bot to user.
adapter.use(async (turnContext, next) => {
// pre-processing of the current incoming activity
console.log("adapture use::turnContext::" + turnContext.activity.text);
// hook up a handler to process any outgoing activities sent during this turn
turnContext.onSendActivities(async (sendContext, activities, nextSend) => {
// pre-processing of outgoing activities
await nextSend();
console.log("adapture use::activities::POST##::" + flat.stringify(activities));
// post-processing outgoing activities
});
await next();
// post-processing of the current incoming activity
console.log(`Processing activity ${turnContext.activity.id} finishing. `);
});
To access the bot's responses, you can update the bot.js file (i.e. the file with the activity handlers defined) to something like the below.
In short, the onSendActivities() method keeps an array of the activities that have been passed in. You can cycle thru the activities pushing them into an array and then acting on a particular one. Or, react as each arrives. Further below are examples of each output.
const { ActivityHandler, MessageFactory } = require('botbuilder');
class EchoBot extends ActivityHandler {
constructor() {
super();
[...]
const transcript = [];
this.onTurn(async (context, next1) => {
let responses = {};
logActivity(transcript, cloneActivity(context.activity));
context.onSendActivities(async (ctx, activities, next2) => {
responses = await next2();
activities.forEach((a) => logActivity(transcript, cloneActivity(a)));
console.log('TRANSCRIPT ', activities);
return responses;
});
await next1();
});
}
}
const logActivity = (transcript, activity) => {
if (!activity.timestamp) {
activity.timestamp = new Date();
}
transcript.push(activity);
};
const cloneActivity = (activity) => {
return Object.assign({}, activity);
};
module.exports.EchoBot = EchoBot;
Logging the transcript array: Shows the list of activities.
[
{
type: 'conversationUpdate',
id: '1hEUP37Da8S',
timestamp: 2021-09-07T23:01:04.910Z,
serviceUrl: 'https://directline.botframework.com/',
channelId: 'directline',
from: { id: 'dl_16310556645490.nc93iu9jr1' },
conversation: { id: '5JgOxxxxxxxxxxxxv6sw-g' },
recipient: { id: 'somebot#QaeuoeEamLg', name: 'Some Bot' },
membersAdded: [ [Object], [Object] ],
rawTimestamp: '2021-09-07T23:01:04.9109865Z',
callerId: 'urn:botframework:azure'
},
{
type: 'message',
text: 'Hello and welcome!',
inputHint: 'acceptingInput',
speak: 'Hello and welcome!',
channelId: 'directline',
locale: undefined,
serviceUrl: 'https://directline.botframework.com/',
conversation: { id: '5JgOxxxxxxxxxxxxv6sw-g' },
from: { id: 'somebot#QaeuoeEamLg', name: 'Some Bot' },
recipient: { id: 'dl_16310556645490.nc93iu9jr1' },
timestamp: 2021-09-07T23:01:06.547Z
},
{
type: 'message',
id: '5JgOxxxxxxxxxxxxv6sw-g|0000001',
timestamp: 2021-09-07T23:01:08.704Z,
localTimestamp: 2021-09-07T23:01:08.527Z,
localTimezone: 'America/Los_Angeles',
serviceUrl: 'https://directline.botframework.com/',
channelId: 'directline',
from: { id: 'dl_16310556645490.nc93iu9jr1', name: '' },
conversation: { id: '5JgOxxxxxxxxxxxxv6sw-g' },
recipient: { id: 'somebot#QaeuoeEamLg', name: 'Some Bot' },
textFormat: 'plain',
locale: 'en-US',
text: 'Hi',
entities: [ [Object] ],
channelData: {
clientActivityID: '1631055668527tzwhm47a4qd',
clientTimestamp: '2021-09-07T23:01:08.527Z'
},
rawTimestamp: '2021-09-07T23:01:08.704318Z',
rawLocalTimestamp: '2021-09-07T16:01:08.527-07:00',
callerId: 'urn:botframework:azure'
},
{
type: 'message',
text: 'Echo: Hi',
inputHint: 'acceptingInput',
speak: 'Echo: Hi',
channelId: 'directline',
locale: 'en-US',
serviceUrl: 'https://directline.botframework.com/',
conversation: { id: '5JgOxxxxxxxxxxxxv6sw-g' },
from: { id: 'somebot#QaeuoeEamLg', name: 'Some Bot' },
recipient: { id: 'dl_16310556645490.nc93iu9jr1', name: '' },
replyToId: '5JgOxxxxxxxxxxxxv6sw-g|0000001',
timestamp: 2021-09-07T23:01:09.147Z
}
]
Logging activities only: Shows the last item to have passed thru from either the bot or user.
[
{
type: 'message',
text: 'Echo: Hi',
inputHint: 'acceptingInput',
speak: 'Echo: Hi',
channelId: 'directline',
locale: 'en-US',
serviceUrl: 'https://directline.botframework.com/',
conversation: { id: 'AURKxxxxxxxxxJHpO-f' },
from: { id: 'somebot#QaeuoeEamLg', name: 'Some Bot' },
recipient: { id: 'dl_16310605730140.3nrm4evq6um', name: '' },
replyToId: 'AURKxxxxxxxxxJHpO-f|0000001'
}
]
Thank you Rajeesh Menoth. Posting your suggestions as an answer to help other community members.
For updating existing message we can pass NewActivityObject with the existing activity ID to the UpdateActivity method of the TurnContext Object
Below is the sample to pass new object ID
const newActivity = MessageFactory.text('The new text for the activity');
newActivity.id = activityId;
await turnContext.updateActivity(newActivity);
To update the existing card on button selection, you can use ReplyToId of incoming activity.
const message = MessageFactory.attachment(card);
message.id = context.activity.replyToId;
await context.updateActivity(message);
For Further information check Update Messages.
const payload = {
payload: {
google: {
expectUserResponse: true,
richResponse: {
items: [
{
simpleResponse: {
ssml: 'hi i am vamsi',
}
}
]
},
},
},
};
I'm using above payload for sending a response to google assistant.
I want to know payload to send as the default response because this response only displays on google assistant. I need a default to display for every platform.
The webhook response can be as simple as
{
"fulfillmentText": "Hi I am Vamsi"
}