Skip to content

Commit 28fac70

Browse files
committed
Fix #708 default_to_current_conversation in (multi_)conversations_select
1 parent 29d4182 commit 28fac70

File tree

3 files changed

+125
-2
lines changed

3 files changed

+125
-2
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# ------------------
2+
# Only for running this script here
3+
import json
4+
import logging
5+
import sys
6+
from os.path import dirname
7+
8+
sys.path.insert(1, f"{dirname(__file__)}/../../..")
9+
logging.basicConfig(level=logging.DEBUG)
10+
11+
# ---------------------
12+
# Slack WebClient
13+
# ---------------------
14+
15+
import os
16+
17+
from slack import WebClient
18+
from slack.errors import SlackApiError
19+
from slack.signature import SignatureVerifier
20+
from slack.web.classes.blocks import InputBlock
21+
from slack.web.classes.elements import ConversationMultiSelectElement, ConversationSelectElement
22+
from slack.web.classes.objects import PlainTextObject
23+
from slack.web.classes.views import View
24+
25+
client = WebClient(token=os.environ["SLACK_API_TOKEN"])
26+
signature_verifier = SignatureVerifier(os.environ["SLACK_SIGNING_SECRET"])
27+
28+
# ---------------------
29+
# Flask App
30+
# ---------------------
31+
32+
# pip3 install flask
33+
from flask import Flask, request, make_response
34+
35+
app = Flask(__name__)
36+
37+
38+
def open_modal(trigger_id: str):
39+
try:
40+
view = View(
41+
type="modal",
42+
callback_id="modal-id",
43+
title=PlainTextObject(text="Awesome Modal"),
44+
submit=PlainTextObject(text="Submit"),
45+
close=PlainTextObject(text="Cancel"),
46+
blocks=[
47+
InputBlock(
48+
block_id="b-id-1",
49+
label=PlainTextObject(text="Input label"),
50+
element=ConversationSelectElement(
51+
action_id="a",
52+
default_to_current_conversation=True,
53+
)
54+
),
55+
InputBlock(
56+
block_id="b-id-2",
57+
label=PlainTextObject(text="Input label"),
58+
element=ConversationMultiSelectElement(
59+
action_id="a",
60+
max_selected_items=2,
61+
default_to_current_conversation=True,
62+
)
63+
),
64+
]
65+
)
66+
response = client.views_open(
67+
trigger_id=trigger_id,
68+
view=view
69+
)
70+
return make_response("", 200)
71+
except SlackApiError as e:
72+
code = e.response["error"]
73+
return make_response(f"Failed to open a modal due to {code}", 200)
74+
75+
76+
@app.route("/slack/events", methods=["POST"])
77+
def slack_app():
78+
if not signature_verifier.is_valid_request(request.get_data(), request.headers):
79+
return make_response("invalid request", 403)
80+
81+
if "command" in request.form \
82+
and request.form["command"] == "/view":
83+
trigger_id = request.form["trigger_id"]
84+
return open_modal(trigger_id)
85+
86+
elif "payload" in request.form:
87+
payload = json.loads(request.form["payload"])
88+
if payload["type"] == "view_submission" \
89+
and payload["view"]["callback_id"] == "modal-id":
90+
submitted_data = payload["view"]["state"]["values"]
91+
print(submitted_data) # {'b-id': {'a-id': {'type': 'plain_text_input', 'value': 'your input'}}}
92+
return make_response("", 200)
93+
if payload["type"] == "shortcut" \
94+
and payload["callback_id"] == "view-test":
95+
return open_modal(payload["trigger_id"])
96+
97+
return make_response("", 404)
98+
99+
100+
if __name__ == "__main__":
101+
# export SLACK_SIGNING_SECRET=***
102+
# export SLACK_API_TOKEN=xoxb-***
103+
# export FLASK_ENV=development
104+
# python3 integration_tests/samples/basic_usage/views_default_to_current_conversation.py
105+
app.run("localhost", 3000)
106+
107+
# ngrok http 3000

slack/web/classes/elements.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,12 @@ class ConversationSelectElement(InputInteractiveElement):
786786
@property
787787
def attributes(self) -> Set[str]:
788788
return super().attributes.union(
789-
{"initial_conversation", "response_url_enabled", "filter"}
789+
{
790+
"initial_conversation",
791+
"response_url_enabled",
792+
"filter",
793+
"default_to_current_conversation",
794+
}
790795
)
791796

792797
def __init__(
@@ -797,6 +802,7 @@ def __init__(
797802
initial_conversation: Optional[str] = None,
798803
confirm: Optional[Union[dict, ConfirmObject]] = None,
799804
response_url_enabled: Optional[bool] = None,
805+
default_to_current_conversation: Optional[bool] = None,
800806
filter: Optional[ConversationFilter] = None,
801807
**others: dict,
802808
):
@@ -815,6 +821,7 @@ def __init__(
815821

816822
self.initial_conversation = initial_conversation
817823
self.response_url_enabled = response_url_enabled
824+
self.default_to_current_conversation = default_to_current_conversation
818825
self.filter = filter
819826

820827

@@ -824,7 +831,12 @@ class ConversationMultiSelectElement(InputInteractiveElement):
824831
@property
825832
def attributes(self) -> Set[str]:
826833
return super().attributes.union(
827-
{"initial_conversations", "max_selected_items", "filter"}
834+
{
835+
"initial_conversations",
836+
"max_selected_items",
837+
"default_to_current_conversation",
838+
"filter",
839+
}
828840
)
829841

830842
def __init__(
@@ -835,6 +847,7 @@ def __init__(
835847
initial_conversations: Optional[List[str]] = None,
836848
confirm: Optional[Union[dict, ConfirmObject]] = None,
837849
max_selected_items: Optional[int] = None,
850+
default_to_current_conversation: Optional[bool] = None,
838851
filter: Optional[Union[dict, ConversationFilter]] = None,
839852
**others: dict,
840853
):
@@ -853,6 +866,7 @@ def __init__(
853866

854867
self.initial_conversations = initial_conversations
855868
self.max_selected_items = max_selected_items
869+
self.default_to_current_conversation = default_to_current_conversation
856870
self.filter = ConversationFilter.parse(filter)
857871

858872

tests/web/classes/test_elements.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ def test_document(self):
652652
},
653653
"initial_conversations": ["C123", "C234"],
654654
"max_selected_items": 2,
655+
"default_to_current_conversation": True,
655656
"filter": {
656657
"include": [
657658
"public",
@@ -674,6 +675,7 @@ def test_document(self):
674675
},
675676
"initial_conversation": "C123",
676677
"response_url_enabled": True,
678+
"default_to_current_conversation": True,
677679
"filter": {
678680
"include": [
679681
"public",

0 commit comments

Comments
 (0)