Posting Message to Slack via NodeJS Lambda Function - Data Variable Not Rendering - node.js

I've got an AWS lambda function implemented in Node that posts a message to a Slack channel. I've created a SlackApp, with the incoming webhook feature enabled. I'm sending a message to the hook via https. The lambda calls the following function that formats the message:
function slackConvertFromSNSMessage(sns_event) {
let slack_message;
let slack_message_text;
const slack_message_user = 'foo';
const slack_use_markdown = true;
const sns_message_raw = sns_event.Records[0].Sns.Message;
const sns_message_date_epoc = new Date(sns_message_raw.StateChangeTime).getTime();
slack_message_text = `
*Alert:* One or more errors were report by ${sns_message_raw.AlarmName}
*Date:* <!date^${sns_message_date_epoc}^{date_num} at {time_secs}^|${sns_message_raw.StateChangeTime}>
*Region:* ${sns_message_raw.Region}
*Queue:* ${sns_message_raw.Trigger.Dimensions[0].value}
`
// "*bold* `code` _italic_ ~strike~"
slack_message = {
text: slack_message_text,
username: slack_message_user,
mrkdwn: slack_use_markdown,
}
return JSON.stringify(slack_message);
}
The message in slack appears as follows:
The variable isn't rendering. I just see the statement I'm passing to the slack API. I expect to see the supplied date formatted to the user's local time zone.
UPDATE: There was a good comment noticing the carrot before the pipe in the declaration. I removed it. I'm still getting the problem, but that line in the code now looks like the following:
*Date:* <!date^${sns_message_date_epoc}^{date_num} at {time_secs}^|${sns_message_raw.StateChangeTime}>

If you do not specify a optional_link you have to remove the last ^ delimiter, i.e. the ^ right before the |. Their documentation doesn't seem to specify this but I can reproduce the problem in the Message Builder.
Edit: And Slack expects a epoch in seconds while getTime() returns a epoch in milliseconds.

Related

How to forward message from channel to the groups on telegram bot?

im trying to implement my bot a function. Function that if the channel write any message it will be forwarded to the groups where the bot already is.
Trying to use scope method that worked like a charm on welcome message when new user joined the group.
//index.js
const Telegram = require('telegram-node-bot'),
tg = new Telegram.Telegram('MYAPI', {
workers: 1
});
const ForwardController = require('./controllers/forward')
tg.router.when(new Telegram.TextCommand('/info', 'infoCommand'), new InfoController())
.otherwise(new ForwardController());
//forward.js
const Telegram = require('telegram-node-bot');
class ForwardController extends Telegram.TelegramBaseController {
handle(scope) {
if ('channel' == scope.message.chat._type) {
scope.api.forwardMessage(scope.message._chat._id, _forwardFromChat._text);
}
}
}
module.exports = ForwardController;
I tried many combinations but the message is never forwarded... The bot is already administrator on the channel and is also putted in the groups. (Have also private message opened with bot so i think it should forward also there)
Take a look at the API reference for the library, the documentation page appears to be down so Github is your friend.
The forwardMessage call you are making has incorrect arguments and is accessing the private class variables. It is also returning a promise so you should await the promise or chain a .then to it. You can use the class methods on the Scope instance itself.
It should be more like:
// using async/await - note the containing function must be async for this approach
const result = await forwardMessage(<id of chat here>, scope.message().id());
// or to chain a .then
forwardMessage(<id of chat here>, scope.message().id())
.then(result => /* do something with result */)
.catch(err => /* handle the error */);
This will use the Scopes instance method and handle sending the id of the current chat for you, all you need is the id of the chat you want to send the message to and then replace the <id of chat here> with that id.

How can i set default answer in Q&A Azure bot

I want change Default Answer in Q&A Maker Azure Framework Bot, but I cant find field that respond this value. I'm reading documentation (but it looks like it uses an older interface), and I'm trying to find this field but with result.
Here's my current configuration screen:
I'm assuming that you're referring to these docs: QnaMaker - Change Default Answer
They're a little confusing, but they key part is:
You can override this default response in the bot or application code
calling the endpoint.
Where the docs have this image:
What they actually mean is that in the QnAMaker Test Console, you can edit the default answer from your Application Settings. Be sure to Save, Train, and Publish your app or the setting may not show.
There's also kind of a way that you can use this setting for your default answer in a bot:
In Node/JS, your bot will not receive that DefaultAnswer at all. It receives nothing if there isn't a match, so you have to hard code it with something like:
const qnaResults = await this.qnaMaker.getAnswers(context);
// If an answer was received from QnA Maker, send the answer back to the user.
if (qnaResults[0]) {
await context.sendActivity(qnaResults[0].answer);
// If no answers were returned from QnA Maker, show this reply.
// Note: .getAnswers() does NOT return the default answer from the App Service's Application Settings
} else {
const defaultAnswer = 'No QnA Maker answers were found. This example uses a QnA Maker Knowledge Base that focuses on smart light bulbs. To see QnA Maker in action, ask the bot questions like "Why won\'t it turn on?" or "I need help."'
await context.sendActivity(defaultAnswer);
}
When creating an Azure Web Bot, one of the default Web Chat clients is a fork of microsoft's BotBuilder-Samples project, specifically 49 - QnAMaker All Features
The source code for Dialog/QnAMakerBaseDialog.cs defines the constant DefaultNoAnswer:
public const string DefaultNoAnswer = "No QnAMaker answers found.";
And then uses that value when returning a response from GetQnAResponseOptionsAsync:
protected async override Task<QnADialogResponseOptions> GetQnAResponseOptionsAsync(DialogContext dc)
{
var noAnswer = (Activity)Activity.CreateMessageActivity();
noAnswer.Text = DefaultNoAnswer; // <- used right here
var cardNoMatchResponse = (Activity)MessageFactory.Text(DefaultCardNoMatchResponse);
var responseOptions = new QnADialogResponseOptions
{
ActiveLearningCardTitle = DefaultCardTitle,
CardNoMatchText = DefaultCardNoMatchText,
NoAnswer = noAnswer,
CardNoMatchResponse = cardNoMatchResponse,
};
return responseOptions;
}
This particular sample repo doesn't appear to leverage the DefaultAnswer configuration key anywhere.
You can opt to include it when available by updating the noAnswer.Text like this:
- noAnswer.Text = DefaultNoAnswer;
+ noAnswer.Text = this._configuration["DefaultAnswer"] ?? DefaultNoAnswer;
You'll also have to pass in the configuration object through the dependency management system. See this commit for a full example.
Change the line in qamakerBaseDialog.js as below
var noAnswer = ActivityFactory.DefaultNoAnswer;
Remove ActivityFactory. and rebuild the code.
constructor(knowledgebaseId, authkey, host) {
//ActivityFactory.
var noAnswer = DefaultNoAnswer;
var filters = [];
super(knowledgebaseId, authkey, host, noAnswer, DefaultThreshold, DefaultCardTitle, DefaultCardNoMatchText,
DefaultTopN, ActivityFactory.cardNoMatchResponse, filters, QNAMAKER_BASE_DIALOG);
this.id = QNAMAKER_BASE_DIALOG;
}

An error has occurred: Invalid Lambda Response: Received null response from Lambda

I am trying to build an Lex bot for Pizza delivery using Node.js.
I have 2 intents 1) Customer data 2) Pizza Order.
So currently, my code work perfectly if I just want to get customer data from user and send the response to Bot, I am trying to **save the data to DB(Dynamo DB) and display the data to user. **, this is when I get the above error.
Please view the below code:
function custData(intentRequest,callback){
const sessionAttributes = intentRequest.sessionAttributes;
const slots = intentRequest.currentIntent.slots;
const name = slots.Name;
const phone = slots.Phone;
const address = slots.Address;
callback(checkDB(name,phone,address), close(sessionAttributes,'Fulfilled',
{'contentType': 'PlainText', 'content': 'Thank you, How can I help you today'}));
}
1) If I call "ONLY" the CheckDB function i.e checkDB(name,phone,address), the database is updated by user inputs and I get the above error in Lex test bot console.
2) If I call only the Close i.e( elicit_close) function, the message I pass is displayed in the Bot console.
3) If I call both the function (similar to the code shared above), I get the above error in Bot console and the DB is updated with user submitted values and in this scenario, the last slot value is taken has null in Bot console but saved correctly in DB.
I searched the similar errors but, the solution does not help since I get the error only when I mention the checkDB in the call back or if i call both functions via callback. if not everything works perfect.

AWS SNS - Invalid Parameter - Phone Number is not valid to publish to. On specific phone number only

We are using AWS SNS to send SMS messages. In testing, it works for all but one of our devs who isn't receiving messages, the logs show the following:
Invalid parameter: PhoneNumber Reason: +1‬207XXXXXXX is not valid to publish to
I left his area code in case it's relevant. Again, this is the only number we've had issues with, it's an iPhone. It works fine for all the other numbers we've tried. I can also successfully SMS that number via the AWS SNS Console without issue.
I should note, we're only sending a 6 character string (for 2 factor auth).
We're doing this from a Lambda. Here's the relevant portion of the code:
export function sendSNS(PhoneNumber, Message) {
return new Promise<boolean>((resolve, reject) => {
const sns = new AWS.SNS({ region: 'us-east-1' })
const params = {
MessageStructure: 'String',
Message,
PhoneNumber
}
sns.setSMSAttributes({
attributes: {
DefaultSenderID: 'mycompany',
DefaultSMSType: 'Transactional'
}
})
sns.publish(params, function(err, data) {
if (err) {
console.log(err)
reject(false)
} else {
console.log(`Sent this SMS via Amazon: ${Message} to ${PhoneNumber}`)
console.log(data)
resolve(true)
}
})
})
}
I was able to fix this by updating the user's phone number directly in our MySQL DB by hand. Not sure if it was a character encoding issue or similar, but am assuming it must've been. I'll post back if I determine the exact cause.
UPDATE:
This was definitely caused by an encoding issue, paste the code below into jsfiddle, and mouseover to see the warning on the first plus sign which reads:
This character may get silently deleted by one or more browsers
var x = '+1‬207XXXXXXX'
var y = '+1207XXXXXXX'
You can also try deleting/backspacing the + or 1 in the offending string (var x). Some weird results.
This data was initially entered into the MySQL DB via a GraphQL mutation from Prisma Playground using Chrome on Mac.
If I convert both strings above to hex to inspect, you can see they are indeed different:
2b31202c32303758585858585858 (bad)
2b3132303758585858585858 (good)
Also be aware that not all AWS regions support sending SMS's and you'll see this same error "InvalidParameter: Invalid parameter: PhoneNumber Reason: +614##### is not valid to publish" when sending messages to a region that doesn't support it (in my case us-west-1).
For a list of regions that do support sending SMS's, see the sns amazon docs on supported regions.
Credit to user RichPeaua in this comment of the AWS forums.

Changing Wit.ai Default Max Steps

For some reason I'm unable to increase the default max steps for my chat bot.
It seems that this number is now defined in lib/config.js rather than lib/wit.js like it used to be. No matter what I change the DEFAULT_MAX_STEPS constant to in my config file my bot seems to hit the same limit (5) before throwing the 'Max steps reached, stopping' error in my log when I want the bot to send a few responses/execute a few actions in a row.
I've tried linking the file the same way the example project seems to link to the wit.js and log.js files in the module via node-wit/lib
The config file:
How I've tried to link it to my index.js file:
I'm assuming I'm not referencing the config.js file properly...
I'll write example steps of using node-wit
1) create and app folder, go to it and run: npm init
2) run npm i --save node-wit
3) app.js :
const {Wit, log, config} = require('node-wit');
const client = new Wit({accessToken: 'MY_TOKEN'});
4) from documentation:
runActions
A higher-level method to the Wit converse API. runActions resets the
last turn on new messages and errors.
Takes the following parameters:
sessionId - a unique identifier describing the user session
message - the text received from the user
context - the object representing the session state
maxSteps - (optional) the maximum number of actions to execute (defaults to 5)
so I'll add MAX_STEPS to example there:
const MAX_STEPS = 25;
const sessionId = 'some-session-id';
const context0 = {};
client
.runActions(sessionId, 'events nearby', context0, MAX_STEPS)
.then((context1) => {
return client.runActions(sessionId, 'how about in London?', context1, MAX_STEPS - 1);
})
.then((context2) => {
console.log('The session state is now: ' + JSON.stringify(context2));
})
.catch((e) => {
console.log('Oops! Got an error: ' + e);
});

Resources