Closed devikaTV closed 5 months ago
I believe the problem is here:
else:
ack(response_action = "update")
...
client.views_update()
You are essentially making two calls to the views.update
API in this code block: once via ack(response_action="update")
and then again view client.views_update
. Both of these calls are doing the same thing: updating the view in response to the user clicking the submit button.
It seems in the ack(response_action="update")
case, you are not using this API correctly. Have a look at Updating View Modals documentation. This part of the documentation has two subsections:
As you can see in the Update a view via response_action
, as part of this API, you should provide the updated view
. In your code, you are not doing this - you are telling Slack "please update the view" but you are not providing what to update the view to.
My suggestion is to use either of these calls, but not both. Your call to the views.update
API via the client looks correct to me: it provides the view ID, the hash (to prevent race conditions) and the updated view contents.
Hi @filmaj
I am still having the same issue even after only usingviews.update
only
This might be confusing, but in response to view_submission requests (meaning within @app.view
listeners in a Bolt app), you must use only ack() to manipulates modals. Calling views.update API etc. does not work stably for you.
It is also feasible to update a modal with ack() method first, and then call views.update API for async update again.
Here is a simple code example I've shared in the past: https://github.com/seratch/deepl-for-slack/blob/d8d3e30f2cc032b77d2da3ac9bdead61b875200f/src/index.ts#L40-L58
If this approach does not work for you, perhaps, your code may not use a valid view_id for views.update API call.
I see But in the docs I can only see examples of views.update API https://slack.dev/bolt-python/concepts Could you please provide me any examples of using ack() to manipulate modals ?
The "client.views_update()" code exmaple in the document is for @app.action
listener use cases. For the pattern, views.update API is the right way to manipulate modals. I've shared an example in the previous reply. Please refer to the code for more details.
Hi @seratch
Same issue with error (We had some trouble connecting), views are being updated after 5 sec
The whole thing works fine but with delay and that error displayed at the top of the modal
slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: https://www.slack.com/api/views.open, status: 200)
The server responded with: {'ok': False, 'error': 'expired_trigger_id'}
It seems that you're trying to open a new modal using views.open API. When you already opened a modal, views.open never works for the same user interaction. You can use either views.update or views.push API in the case.
If you're still confused with the modal APIs, I highly recommend using only ack(response_action="update")
within @app.view
listeners. This approach is very simple, plus you won't be confused with anything. Also, most use cases can be covered by the approach.
So I want a second view on view submission of a modal before the end processing of data
For that I used ack(response_action="update", view= updated_view) only instead of web client API
But now the whole modal is getting closed suddenly once I hit submit
I can see the second view if I am using any listeners inside first view and use web client API
But then the submit button will be there doing nothing (I believe we can't remove it in a modal with input type fields)
Hi @seratch Could you please help ?
Sorry, with given the last two comments, I am not sure what you're struggling with now.
Could you share a simplified code snippet demonstrating what you want to do (or the one that does not work as you expect)? As we are unable to help you out for the entire app development, you don't need to share your complete code. With simple code snippets, we may be able to help you on more specifics.
Sure Please check the below code snippet
@app.command("/editticket")
def open_ticket_modal(ack, body, client):
ack()
res=client.views_open(
trigger_id=body["trigger_id"],
view={
"type": "modal",
"callback_id": "submit_ticket",
"title": {"type": "plain_text", "text": "Edit Ticket"},
"blocks": [
]
}
)
print(res)
@app.view("submit_ticket")
def handle_ticket_submission(ack,body,client):
ack()
values = body["view"]["state"]["values"]
errors = {}
# performs some checks on input entered in previous view and raise errors
if len(errors) > 0:
ack(response_action="errors", errors=errors)
else:
ack()
#a github api call to get values to fill in the next view
updated_view={
"type": "modal",
"callback_id": "submit_edit_ticket",
"blocks": [
]
}
ack(response_action="update", view= updated_view2)
@app.view("submit_edit_ticket")
def handle_edit_submission_event(ack,body,client):
ack()
slack_user_id = body["user"]["id"]
values = body["view"]["state"]["values"]
values[""][""]["value"] if "" in values else None
# fetch values from each block in previous view
errors = {}
#checks for errors
if len(errors) > 0:
ack(response_action="errors", errors=errors)
else:
ack(response_action = "clear" )
#api call for updations
message = f"....."
client.chat_postEphemeral (channel = Channel_name, text = message , user = slack_user_id)
Thanks for sharing it. Here is the complete example code. Your code had a few issues:
import os
import logging
import time
from slack_sdk import WebClient
from slack_bolt import App, Ack
from slack_bolt.adapter.socket_mode import SocketModeHandler
logging.basicConfig(level=logging.DEBUG)
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
@app.command("/editticket")
def open_ticket_modal(ack: Ack, body: dict, client: WebClient):
ack() # ack comamnd execution within 3 seconds
# Open a modal dialog
client.views_open(
trigger_id=body["trigger_id"],
view={
"type": "modal",
"callback_id": "submit_ticket",
"title": {"type": "plain_text", "text": "Edit Ticket"},
"submit": {"type": "plain_text", "text": "Submit"},
"blocks": [
{"type": "section", "text": {"type": "mrkdwn", "text": "First page"}},
],
},
)
@app.view("submit_ticket")
def handle_ticket_submission(ack: Ack, payload: dict, client: WebClient):
# Don't call ack() here, ack with no arg closes this modal
errors = {}
if len(errors) > 0:
ack(response_action="errors", errors=errors)
else:
ack(
response_action="update",
view={
# type, callback_id, title, blocks are required
"type": "modal",
"callback_id": "submit_edit_ticket",
"title": {"type": "plain_text", "text": "Edit Ticket"},
# intentionally removed "submit" here to avoid the end-user submitting this modal before it's ready
"blocks": [
{
"type": "section",
"text": {"type": "mrkdwn", "text": "Loading..."},
},
],
},
)
# demonstrating how to asynchronously update the same modal
time.sleep(3)
client.views_update(
view_id=payload["id"],
view={
"type": "modal",
"callback_id": "submit_edit_ticket",
"title": {"type": "plain_text", "text": "Edit Ticket"},
"submit": {"type": "plain_text", "text": "Submit"},
"blocks": [
{
"type": "section",
"text": {"type": "mrkdwn", "text": "Second page loaded!"},
},
],
},
)
@app.view("submit_edit_ticket")
def handle_edit_submission_event(ack, body, client):
errors = {}
if len(errors) > 0:
ack(response_action="errors", errors=errors)
else:
# If you want to close this modal immediately,
# either ack() or ack(response_action="clear") works
ack(
response_action="update",
view={
"type": "modal",
"callback_id": "submit_edit_ticket",
"title": {"type": "plain_text", "text": "Edit Ticket"},
# intentionally removed "submit" as this is the completion page
"blocks": [
{
"type": "section",
"text": {"type": "mrkdwn", "text": ":white_check_mark: Done!"},
},
],
},
)
if __name__ == "__main__":
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()
I believe this example should answer all the questions you had. Would you mind closing this issue? Whenever you have a new question, please feel free to open a new issue for it!
👋 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.
I am using socket mode python for a modal triggering with slash command
It has three stages
The error message is displayed when hitting the submit in first modal , sometimes the modal flow closes at that point or continue to next modal with the same error, sometimes the modal doesn't closes even after submit but the changes intended are reflected
Please help me in figuring out what is going wrong Attaching the code