Skip to content

Commit 5b88fef

Browse files
committed
Add feedback submission modal
1 parent 7e5ebf1 commit 5b88fef

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This bot requires the following scopes:
2222
- `commands` to add and receive slash command interactions
2323
- `chat:write` to send messages
2424
- `users:read` to extract `user.real_name` from `command.user_id`
25+
- `channels:manage`, `groups:write`, `im:write`, and `mpim:write` to create and send messages in DMs and group DMs
2526

2627
### Google
2728
To use the sheets API, create a [Google cloud project](https://console.cloud.google.com) and enable the [Google Sheets

bot.ts

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {App, MessageShortcut, UsersSelectAction} from '@slack/bolt';
22
import {WebClient} from '@slack/web-api';
3-
import {Actions, Header, Input, Message, Modal, Section, TextInput, UserSelect} from 'slack-block-builder';
3+
import {Actions, BlockCollection, Header, Input, Message, Modal, Option, Section, StaticSelect, TextInput, UserSelect} from 'slack-block-builder';
4+
5+
// Utilities
46
import {getInfo} from './util/sheets';
57
import {capitalize, parseCellPhone} from './util/parsing';
68
import { signingSecret, token, port } from './config';
@@ -127,37 +129,78 @@ app.command('/help', async ({ack, respond}) => {
127129
Section().fields(
128130
'*/help*\nSends info about other commands.',
129131
'*/info @[user]?*\nGets the contact info of a given user.'
132+
),
133+
Section().fields(
134+
'*/submit-feedback*\nSubmits feedback about the slack bot.'
130135
)
131136
)
132137
.buildToObject()
133138
);
134139
});
135140

136-
app.command('/modaltest', async ({ack, client, payload}) => {
141+
// /submit-feedback
142+
// Submits feedback about the slack bot.
143+
app.command('/submit-feedback', async ({ack, client, payload}) => {
137144
await ack();
138-
const modal = Modal({title: 'This is a modal.', submit: 'Submit', callbackId: 'test-modal'})
145+
146+
const feedbackTypes = [
147+
Option({text: 'Feature suggestion', value: 'feature_suggestion'}),
148+
Option({text: 'Feature feedback', value: 'feature_feedback'}),
149+
Option({text: 'Bug report', value: 'bug_report'})
150+
];
151+
152+
const modal = Modal({title: 'SEC Slack Bot Feedback', submit: 'Submit', callbackId: 'feedback-modal'})
139153
.blocks(
140-
Section({text: 'Please input your personal information so that your data may be harvested.'}),
141-
Input({label: 'Name', blockId: 'name-input'})
142-
.element(TextInput({actionId: 'name-action', placeholder: 'John Doe'}))
154+
Section({text: 'Please select what type of feedback to give, what feature your feedback concerns, and a brief description of your suggestion.'}),
155+
Input({label: 'Feedback type', blockId: 'type-select'})
156+
.element(StaticSelect({actionId: 'type-action', placeholder: 'Select a feedback type'})
157+
.options(feedbackTypes)
158+
.initialOption(feedbackTypes[0]))
143159
.optional(false),
144-
Input({label: 'Email address', blockId: 'email-input'})
145-
.element(TextInput({actionId: 'email-action', placeholder: '[email protected]'}))
160+
Input({label: 'Feature name', blockId: 'name-input'})
161+
.element(TextInput({actionId: 'name-action', placeholder: 'The feature your feedback concerns.'}))
146162
.optional(false),
147-
Input({label: 'Phone number', blockId: 'phone-input'})
148-
.element(TextInput({actionId: 'phone-action', placeholder: '(650)-000-0000'}))
149-
.optional(true)
163+
Input({label: 'Feedback description', blockId: 'desc-input'})
164+
.element(TextInput({actionId: 'desc-action', placeholder: 'A brief description of your feedback.'})
165+
.multiline(true))
166+
.optional(false)
150167
)
151168
.buildToObject();
152169
await client.views.open({trigger_id: payload.trigger_id, view: modal});
153170
});
154171

155-
app.view('test-modal', async ({ack, view}) => {
156-
await ack();
172+
app.view('feedback-modal', async ({ack, client, body, view}) => {
173+
// Update feedback modal with close message
174+
await ack({
175+
response_action: 'update',
176+
view: Modal({title: 'SEC Slack Bot Feedback'})
177+
.blocks(
178+
Header({text: 'Your feedback was successfully submitted.'}),
179+
Section({text: 'This modal can be safely closed. Have a nice day!'})
180+
)
181+
.buildToObject()
182+
});
183+
184+
// Log feedback with relevant persons
185+
const type = view.state.values['type-select']['type-action'].selected_option?.value;
157186
const name = view.state.values['name-input']['name-action'].value;
158-
const email = view.state.values['email-input']['email-action'].value;
159-
const phone = view.state.values['phone-input']['phone-action'].value;
160-
console.log(`Received: name=${name} email=${email} phone=${phone}`)
187+
const desc = view.state.values['desc-input']['desc-action'].value;
188+
189+
const users = ['U03GQC0A9MJ', 'U03GFNM1XA6']; // Kevin Yu, Ethan Liang
190+
const res = await client.conversations.open({users: users.join(',')});
191+
if (!res.ok || !res.channel?.id) return;
192+
193+
const blocks = BlockCollection(
194+
Header({text: `${body.user.name} submitted a new ${type}`}),
195+
Section({text: `*Name:* ${name}`}),
196+
Section({text: `*Desc:* ${desc}`})
197+
);
198+
199+
await client.chat.postMessage({
200+
channel: res.channel.id,
201+
blocks,
202+
text: `${body.user.name} submitted a new ${type}`
203+
});
161204
});
162205

163206
;(async () => {

0 commit comments

Comments
 (0)