-
Notifications
You must be signed in to change notification settings - Fork 390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Getting We had some trouble connecting. Try again? after updating a view. Using aws lambda. #2150
Comments
Hi @tusharwagh-mdsol, thanks for asking the question! When you want to update the submitted modal in |
Hi @seratch In above code when we submit the comments i want to display processing modal and after that the modal should get updated with another message as this task is completed but here task completion will take some time to complete because we have some api calls as well and also after task completion I have to refresh the homeview as well to remove the completed task. Can you please suggest best way to do this ? below is the full code for the same. // Handle submission of the reason modal
app.view('reason_modal', async ({ ack, body, view, client }) => {
await ack({ response_action: "update", view: view})
const viewId = view.id;
// Open a quick loading modal
await client.views.update({
view_id: viewId,
"response_action": "update",
view: {
type: "modal",
title: {
type: "plain_text",
text: ":man-biking:Processing..",
},
blocks: [
{
type: "section",
text: {
type: "plain_text",
text: ":hourglass_flowing_sand: Please wait while we process your request...",
},
},
],
},
});
const { selectedOption, selectedApplicationId, userEmail } = JSON.parse(view.private_metadata);
const reason = view.state.values.reason_input.reason.value;
const approveruserId = body.user.id;
const pendingTasksUrl = `${process.env.slack_local_api}/pending-tasks?user_email=${userEmail}`;
try {
const response = await axios.get(pendingTasksUrl, {
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.X_API_KEY,
},
});
const tasks = response.data.tasks;
const task = tasks.find(task => task.application_req_ref_id == selectedApplicationId);
if (!task) {
throw new Error("Task not found");
}
const payload = {
_id: task._id,
recordedAction: capitalizeFirstCharacter(selectedOption),
tasktoken: task.tasktoken,
application_req_ref_id: selectedApplicationId,
requestingApplication: task.requestingApplication,
actioned_at: new Date().toISOString().slice(0, 10),
taskName: task.taskName,
description: task.description,
userEmail: userEmail,
reason: reason,
approveruserId: approveruserId,
approvalScheme: task.approvalScheme
};
const approvalUrl = `${process.env.slack_local_api}/slack-approval`;
// Ensure the post request is awaited
await axios.post(approvalUrl, payload, {
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.X_API_KEY,
},
});
// Determine the final title and message based on the selected option
let titleTxt = "";
let blockMsg = "";
switch (selectedOption) {
case "Approve":
titleTxt = "Approved";
blockMsg = "Requested action is completed :white_check_mark:";
break;
case "Reject":
titleTxt = "Rejected";
blockMsg = "Requested action is rejected :x:";
break;
case "Ignore":
titleTxt = "Ignored";
blockMsg = "Requested action is ignored :no_entry_sign:";
break;
default:
titleTxt = "Unknown Action";
blockMsg = "An unknown action was selected.";
}
// Update the modal with the final content
await client.views.update({
view_id: viewId,
"response_action": "update",
view: {
type: "modal",
callback_id: "modal-1",
title: {
type: "plain_text",
text: titleTxt,
},
blocks: [
{
type: "section",
block_id: "section-1",
text: {
type: "mrkdwn",
text: blockMsg,
},
},
],
},
});
try{
// Optionally refresh the pending tasks view
const refreshResponse = await axios.get(pendingTasksUrl, {
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.X_API_KEY,
},
});
const refreshedTasks = refreshResponse.data.tasks;
// Always include the Pending and Completed Tasks buttons
const baseViewBlocks = [
{
type: "section",
text: {
type: "mrkdwn",
text: ":wave: *Welcome to the Approval Application!*\n Please choose between the options to check tasks..",
},
},
{
type: "actions",
elements: [
{
type: "button",
text: {
type: "plain_text",
text: "Pending Tasks",
emoji: true,
},
action_id: "pending_button",
style: "danger",
},
{
type: "button",
text: {
type: "plain_text",
text: "Completed Tasks",
emoji: true,
},
action_id: "completed_button",
style: "primary",
},
],
},
];
if (refreshedTasks.length === 0) {
baseViewBlocks.push(
{
type: "section",
text: {
type: "mrkdwn",
text: "*You have no pending tasks at the moment.*",
},
},
{
type: "section",
text: {
type: "mrkdwn",
text: "*Please check back later or contact support if you believe this is an error.*",
},
}
);
await client.views.publish({
user_id: body.user.id,
"response_action": "clear",
view: {
type: "home",
blocks: baseViewBlocks,
},
});
return;
}
const uniqueCategories = [...new Set(refreshedTasks.map(task => task.requestingApplication))];
const defaultCategory = uniqueCategories.includes(task.requestingApplication) ? task.requestingApplication : uniqueCategories[0];
const tasksForDefaultCategory = getTasksForCategory(defaultCategory, refreshedTasks);
const categoryButtons = uniqueCategories.map(category => {
const tasksForCategory = getTasksForCategory(category, refreshedTasks);
const pendingTasksCount = tasksForCategory.length;
return {
type: "button",
text: {
type: "plain_text",
text: `${category} (${pendingTasksCount})`,
},
action_id: `pending_category_${category.replace(/\s/g, "_")}_button`,
style: selectedCategory === category ? "primary" : "danger",
};
});
const tasksBlocks = tasksForDefaultCategory.map((task, index) => [
{
type: "section",
block_id: `${task.application_req_ref_id}`,
text: {
type: "mrkdwn",
text: `:clipboard: *Task ${index + 1}:* <${task.req_app_redirect_url}| ${task.application_req_ref_id}> ${task.taskName}`,
},
accessory: {
type: "static_select",
action_id: `pending_task_action_${index + 1}`,
placeholder: {
type: "plain_text",
text: "Select an action",
},
options: getOptionsForTaskActions(task.actions),
},
},
{
type: "divider",
},
]).flat();
const view = {
type: "home",
blocks: [
...baseViewBlocks,
{
type: "section",
text: {
type: "mrkdwn",
text: "*Please choose between below tasks category*",
},
},
{
type: "actions",
elements: categoryButtons,
},
{
type: "divider",
},
{
type: "section",
text: {
type: "mrkdwn",
text: `Selected Category Tasks (${defaultCategory}):`,
},
},
...tasksBlocks,
],
};
await client.views.publish({
user_id: body.user.id,
"response_action": "clear",
view,
});
}catch (error) {
// Always include the Pending and Completed Tasks buttons
const baseViewBlocks = [
{
type: "section",
text: {
type: "mrkdwn",
text: ":wave: *Welcome to the Approval Application!*\n Please choose between the options to check tasks..",
},
},
{
type: "actions",
elements: [
{
type: "button",
text: {
type: "plain_text",
text: "Pending Tasks",
emoji: true,
},
action_id: "pending_button",
style: "danger",
},
{
type: "button",
text: {
type: "plain_text",
text: "Completed Tasks",
emoji: true,
},
action_id: "completed_button",
style: "primary",
},
],
},
];
baseViewBlocks.push(
{
type: "section",
text: {
type: "mrkdwn",
text: "*You have no pending tasks at the moment.*",
},
},
{
type: "section",
text: {
type: "mrkdwn",
text: "*Please check back later or contact support if you believe this is an error.*",
},
}
);
await client.views.publish({
user_id: body.user.id,
"response_action": "clear",
view: {
type: "home",
blocks: baseViewBlocks,
},
});
return;
}
} catch (error) {
let errorMessage = "Something went wrong while processing your request.";
if (error.response && error.response.status === 404) {
errorMessage = "You have caught up with all tasks! :white_check_mark:";
}
await client.views.update({
view_id: viewId,
"response_action": "update",
view: {
type: "modal",
title: {
type: "plain_text",
text: "Congratulations!",
},
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: errorMessage,
},
},
],
},
});
}
}); |
bolt-python's lazy listeners could be the best solution for your use case: https://slack.dev/bolt-python/concepts#lazy-listeners However, unfortunately the same functionality does not exist in bolt-js due to its design restrictions. Also, we don't have plans to enhance bolt-js for the need. If we want to write your app using bolt-js + AWS Lambda, the only suggestion I can give is to have a queue for delegating the time-consuming task to a different Lambda function. You can store the event payload and view_id etc. into the queue message. With that, the async task worker function can update the end-user once the task completes. I hope this helps. Is everyting clear now? If yes, would you mind closing this? |
👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized. |
As this issue has been inactive for more than one month, we will be closing it. Thank you to all the participants! If you would like to raise a related issue, please create a new issue which includes your specific details and references this issue number. |
Below code will open a comment modal.
And After comment we will update the existing view with
**
**
The text was updated successfully, but these errors were encountered: