API error occurred: invalid_arguments when opening a modal in slack - node.js

I am trying to open a modal in my slack app
I am trying to follow the official github page on the modal section but I ma getting an error
(node:20175) UnhandledPromiseRejectionWarning: Error: An API error occurred: invalid_arguments
at Object.platformErrorFromResult (/node_modules/#slack/web-api/src/errors.ts:94:5)
at WebClient.apiCall (/node_modules/#slack/web-api/src/WebClient.ts:159:13)
at process.internalTickCallback (internal/process/next_tick.js:77:7)
I can successfully receive and start processing interactive actions sent by slack (on my slack app I have registered a Interactive Components > action with appropriate callback id)
I then try to open a modal while processing this interactive action and it crashes
# In my app I build the message adapter
const slackInteractions = createMessageAdapter(process.env.SLACK_SIGNING_SECRET)
slackInteractions.action({ callbackId: CALLBACK_IDS.MY_CALLBACK_ID }, myHandler)
# which is then mounted as an express middleware, no problem so far
# the handler supposed to open a modal
import { WebClient } from '#slack/web-api';
export default (payload, respond) => {
try {
console.info('Slack payload for my callback', payload);
const trigger_id = payload.trigger_id;
const web = new WebClient(process.env.SLACK_OAUTH_ACCESS_TOKEN)
const openModalPayload = {
trigger_id,
view: {
type: 'modal',
callback_id: 'view_identifier',
title: {
type: 'plain_text',
text: 'Modal title'
},
blocks: [
{
type: 'input',
label: {
type: 'plain_text',
text: 'Input label'
},
element: {
type: 'plain_text_input',
action_id: 'value_indentifier'
}
}
]
}
};
console.log(openModalPayload)
web.views.open(openModalPayload) # <<- this async call seems to be crashing

I opened an issue and the documentation was fixed, basically it's not possible to have a view with inputs without a submit button in the view payload
submit: {
type: 'plain_text',
text: 'Submit'
},

Related

GCP Cloud Function for Slash command not working

so i'm trying to make an slash command on my slack using nodejs and Cloud Functions. I'm getting error 403 when the slash command goes out to the function, but i'm having problems to identify why it's giving me the error.
The code of the function is this:
const { WebClient } = require('#slack/web-api');
exports.slashCommand = (req, res) => {
// Verify that the request is coming from Slack
if (!req.body.token || req.body.token !== process.env.SLACK_TOKEN) {
res.status(403).end();
return;
}
// Parse the request body and extract the Slack user ID, command text, and response URL
const { user_id, text, response_url } = req.body;
// Use the Slack Web API client to post a message to the response URL
const web = new WebClient();
web.chat.postMessage({
channel: user_id,
blocks: [
{
type: 'section',
text: {
type: 'plain_text',
text: 'This is a section block'
}
},
{
type: 'divider'
},
{
type: 'section',
fields: [
{
type: 'plain_text',
text: 'This is a field'
},
{
type: 'plain_text',
text: 'This is another field'
}
]
}
]
});
// Send a 200 OK response to acknowledge receipt of the request
res.status(200).end();
};
I'm using nodeJS 18 to build
I also created gen 1 and gen2 with the same code, but the problem persists. I've given permission to allUsers to call the URL, but still no go. My SLACK_TOKEN is configured in the env. I'm suspecting that's something in the payload but i'm not understanding why this is happening. ( i'm new to this, so i'm sorry for the lack of details, if theres something i should add, let me know ).
Tried to give permission to allUsers, and still getting error. I'm really struggling to make slack validate the payload so my guess is the code checking if the payload and the token is valid is breaking everything.

Telegram bot: editMessageReplyMarkup method doesn't work

I've developed a telegram bot using Node.js and node-telegram-bot-api module that sends a message and an inline keyboard to the users, what I'm trying is to achieve that after the user clicks the button, the inline keyboard must disappear. I'm using editMessageReplyMarkup but it gives the mentioned errors
Reference: Method editMessageReplyMarkup removes inline keybord
Part of code:
bot.on('callback_query', function onCallbackQuery(example) {
const action = example.data
const msg_id = example.message.from.id
const chat_id = example.from.id
//console.log(example.from.id)
if (action == 'FM') {
bot.editMessageReplyMarkup({
reply_markup: {
inline_keyboard: [
[
],
]
}
}, {
chat_id: chat_id,
message_id: msg_id
});
}
});
Error:
Unhandled rejection Error: ETELEGRAM: 400 Bad Request: message to edit not found
I've tried the following solution as well but it doesn't work
Reference:
How hide or delete inline button after click?
bot.on('callback_query', function onCallbackQuery(example) {
const action = example.data
const msg_id = example.message.from.id
const chat_id = example.from.id
console.log(example.from.id)
if (action == 'FM') {
console.log(action)
console.log("FM")
console.log(msg_id)
// console.log(example.message.message_id)
bot.editMessageReplyMarkup({
chat_id: chat_id,
message_id: msg_id,
reply_markup: JSON.stringify({
keyboard: []
})
}
);
}
});
Error:
Unhandled rejection Error: ETELEGRAM: 400 Bad Request: message identifier is not specified
You're referring to wrong msg_id.
It should be
const msg_id = example.message.message_id
bot.editMessageReplyMarkup({
reply_markup: {
inline_keyboard: [
[
],
]
}
}, {
chat_id: chat_id,
message_id: msg_id
});
execute console.log(example) to get a clear idea of the response
Use this order parameters
bot.telegram.editMessageReplyMarkup(chatId, messageId, newMarkup);

Action button push-notification not working | Node | sw-push

I've created a web app using MEAN stack and integrated push message notification for certain events. But how do I add link/s in the notification so the user can click and gets redirected to site on browser
here's a specimen I send
const notificationPayload = JSON.stringify({
notification: {
title: "Hello",
body: "World,
icon: <icon link>,
vibrate: [100, 50],
data: {
dateOfArrival: Date.now(),
primaryKey: 1
},
actions: [{
action: "explore",
title: "Checkout",
icon: <icon link>,
click_action: "https://www.google.com", // not working
url: "https://www.google.com" // not working
}]
}
});
Resultant is good, and checkout button is clickable... but no reaction
Okay, firstly, NotificationAction object is only allowed to have 3 keys:
action
title
icon
So Naturally, click_action & url will just be ignored.
Coming to your question on how to handle actions, you need to write handlers for each action in the array based on the NotificationAction.action key in your service worker. A detailed guide can de found here.
example:
self.registration.showNotification("New mail from Alice", {
actions: [
{
action: 'archive',
title: 'Archive'
}
]
});
self.addEventListener('notificationclick', function(event) {
event.notification.close();
if (event.action === 'archive') {
// Archive action was clicked
archiveEmail();
} else {
// Main body of notification was clicked
clients.openWindow('/inbox');
}
}, false);
References:
NotificationAction
NotificationEvent.action
Notification API
Displaying a notification - Web Fundamentals
Notification behaviour
I'll setup the precise answer, that resolved my case with ngsw-worker:
this was the notification that I was sending, with it, you can send data in the data attribute:
notification: {
title: "hello world,
body: "you have a notification",
icon: <user dp url>,
vibrate: [100, 50],
data: {
dateOfArrival: Date.now(),
primaryKey: 1,
url: <user's profile URL> // data to be used
},
actions: [{
action: "explore",
title: "Checkout",
icon: '... some address ... jolly-roger.png',
},
{
action: 'close',
title: 'Close'
}
]
}
Now, open ngsw-worker.js. It's usually in root folder of dist (for production ready rip), or in node_modules\#angular\service-worker\ngsw-worker.js
here, goto line that handles clicks on notification (:1932: in my case)
this.scope.addEventListener('notificationclick', (event) =>
and you can add your code here regarding the ULR to open. example:
this.scope.addEventListener('notificationclick', (event) => {
try {
clients.openWindow("http://localhost:3000/#/"+event.data.url);
} catch (e) {
clients.openWindow("http://localhost:3000/#/");
}
this.onClick(event)
});
alternatively, if you are handling it within angular itself, you can use redefine the function after injecting swPush in constructor:
this._swPush.notificationClicks.subscribe( event => {
console.log("event = ", event);
});
Rest related articles are present in Salvio's answer below.

Send a typing indicator in bot-framework v4 using DirectLine and webchat (Node.js)

The official docs for Microsoft bot-framework SDK v4 do not demonstrate how to send a typing indicator (whereas v3 has these instructions). I'm using DirectLine and botframework-webchat.
How do I do this? Thanks!
You can send a typing indicator by sending an activity with the typing type. Read more about how to send a typing indicator.
await context.sendActivities([
{ type: ActivityTypes.Typing },
{ type: 'delay', value: 3000 },
{ type: ActivityTypes.Message, text: 'Finished typing' }
]);
Also the showTypingMiddleware can be used to automatically send the typing indicator. This snippet will also show how to send a typing indicator, if you are looking for more sample code.
I believe you should do something like this
await context.sendActivities([
{ type: 'typing' },
{ type: 'delay', value: 2000 },
{ type: 'message', text: 'Your message here' }
]);
I think you can just add in OnTurnAsync function before await base.OnTurnAsync(turnContext, cancellationToken); :
await turnContext.SendActivityAsync(new Activity { Type = ActivityTypes.Typing }, cancellationToken);

Trigger Bot with Drag & drop SharePoint Online

I want to be able to trigger my bot who's on my SharePoint online Site by Droping a local file to him.
I created a WebPart to use this bot on the site, and putting the embed code give by Azure.
But when i drop a file in the bot, it open the document in a new tab showing me the content.
I would like to start the conversation while drop a file like this :
Start of bot conversation by putting a file
I'd imagine some solution by using a drop zone on the iframe which contain the bot, but it's not working.
I visit some site who can help but i don't really know how to implement this : Bot in WebChat, DirectLine API, Send Activity to the bot
This GitHub could also be usefull.
You'll need to handle the ondragover and ondrop events (cancelling the default behavior) and post the activity manually:
html:
<div id="bot" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" />
Javascript:
const dl = new BotChat.DirectLine({
secret: 'YourDLSecret',
webSocket: false
});
BotChat.App({
botConnection: dl,
user: { id: 'userid' },
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
function dragover_handler(ev) {
console.log("dragOver");
ev.preventDefault();
}
function drop_handler(ev) {
console.log("Drop");
ev.preventDefault();
ev.stopPropagation();
var files = [];
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[i].kind === 'file') {
var file = ev.dataTransfer.items[i].getAsFile();
files.push({
contentType: file.type,
contentUrl: window.URL.createObjectURL(file),
name: file.name
});
}
}
dl.postActivity({
from: { id: 'userid' },
type: 'message',
attachments: files
})
.subscribe(function (id) {
console.log('files sent');
});
}

Resources