Skip to content

Commit 5b063b2

Browse files
committed
add /ticket functionality for requesting credentials, email accounts, etc
1 parent 917ef52 commit 5b063b2

9 files changed

Lines changed: 158 additions & 21 deletions

File tree

pybot/endpoints/slack/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from pybot.endpoints.slack import messages
2-
from . import events, actions, commands
1+
from . import events, actions, commands, messages
32

43

54
def create_endpoints(plugin):

pybot/endpoints/slack/actions.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
import logging
2+
from pprint import pprint
3+
14
from sirbot import SirBot
25
from slack import methods
36
from slack.actions import Action
47

58
from pybot.endpoints.slack.utils.action_messages import *
69
from pybot.endpoints.slack.utils import COMMUNITY_CHANNEL
710

11+
logger = logging.getLogger(__name__)
12+
813

914
def create_endpoints(plugin):
1015
plugin.on_action("resource_buttons", resource_buttons, wait=False)
@@ -18,6 +23,33 @@ def create_endpoints(plugin):
1823
plugin.on_action("claimed", reset_claim, name='reset_claim', wait=False)
1924
plugin.on_action("report_message", open_report_dialog, wait=False)
2025
plugin.on_action("report_dialog", send_report, wait=False)
26+
plugin.on_action("open_ticket", open_ticket, wait=False)
27+
plugin.on_action("ticket_status", ticket_status, wait=False)
28+
29+
30+
async def ticket_status(action: Action, app: SirBot):
31+
"""
32+
Updates the ticket status dropdown. (I don't know why we need to manually
33+
update the message for this..)
34+
"""
35+
logger.info(action)
36+
response = updated_ticket_status(action)
37+
await app.plugins["slack"].api.query(methods.CHAT_UPDATE, response)
38+
39+
40+
async def open_ticket(action: Action, app: SirBot):
41+
"""
42+
Called when a user submits the ticket dialog. Parses the submission and posts
43+
the new ticket details to the required channel
44+
"""
45+
attachments = ticket_attachments(action)
46+
response = {
47+
'channel': MODERATOR_CHANNEL,
48+
'attachments': attachments,
49+
'text': 'New Ticket Submission',
50+
}
51+
52+
await app["plugins"]["slack"].api.query(methods.CHAT_POST_MESSAGE, response)
2153

2254

2355
async def send_report(action: Action, app: SirBot):
@@ -119,7 +151,13 @@ async def claimed(action: Action, app: SirBot):
119151
"""
120152
response = base_response(action)
121153
user_id = action['user']['id']
122-
response['attachments'] = claimed_attachment(user_id)
154+
155+
attachments = action['original_message']['attachments']
156+
157+
for index, attachment in enumerate(attachments):
158+
if attachment['callback_id'] == 'claimed':
159+
attachments[index] = claimed_attachment(user_id)
160+
response['attachments'] = attachments
123161

124162
await app.plugins['slack'].api.query(methods.CHAT_UPDATE, response)
125163

@@ -131,7 +169,13 @@ async def reset_claim(action: Action, app: SirBot):
131169
Updates the button back to its initial state
132170
"""
133171
response = base_response(action)
134-
response['attachments'] = not_claimed_attachment()
172+
173+
attachments = action['original_message']['attachments']
174+
for index, attachment in enumerate(attachments):
175+
if attachment['callback_id'] == 'claimed':
176+
attachments[index] = not_claimed_attachment()
177+
178+
response['attachments'] = attachments
135179
await app.plugins['slack'].api.query(methods.CHAT_UPDATE, response)
136180

137181

pybot/endpoints/slack/commands.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from slack import methods
66
from slack.commands import Command
77

8-
from pybot.endpoints.slack.utils import PYBACK_HOST, PYBACK_PORT, PYBACK_TOKEN, REPORT_CHANNEL, YELP_TOKEN
8+
from pybot.endpoints.slack.message_templates.commands import ticket_dialog
9+
from pybot.endpoints.slack.utils import PYBACK_HOST, PYBACK_PORT, PYBACK_TOKEN, MODERATOR_CHANNEL, YELP_TOKEN
910
from pybot.endpoints.slack.utils.action_messages import not_claimed_attachment
1011
from pybot.endpoints.slack.utils.command_utils import get_slash_here_messages, get_slash_repeat_messages, response_type
1112
from pybot.endpoints.slack.utils.slash_lunch import LunchCommand
@@ -24,6 +25,23 @@ def create_endpoints(plugin: SlackPlugin):
2425
plugin.on_command('/lunch', slash_lunch, wait=False)
2526
plugin.on_command('/repeat', slash_repeat, wait=False)
2627
plugin.on_command('/report', slash_report, wait=False)
28+
plugin.on_command('/ticket', slash_ticket, wait=False)
29+
30+
31+
async def slash_ticket(command: Command, app: SirBot):
32+
trigger_id = command['trigger_id']
33+
user_id = command['user_id']
34+
logger.warning(command['text'])
35+
36+
user_info = await app.plugins['slack'].api.query(methods.USERS_INFO, {'user': user_id})
37+
clicker_email = user_info['user']['profile']['email']
38+
39+
response = {
40+
"trigger_id": trigger_id,
41+
"dialog": ticket_dialog(clicker_email, command['text'])
42+
}
43+
44+
await app.plugins["slack"].api.query(methods.DIALOG_OPEN, response)
2745

2846

2947
async def slash_report(command: Command, app: SirBot):
@@ -40,8 +58,8 @@ async def slash_report(command: Command, app: SirBot):
4058

4159
response = {
4260
'text': message,
43-
'channel': REPORT_CHANNEL,
44-
'attachments': not_claimed_attachment(),
61+
'channel': MODERATOR_CHANNEL,
62+
'attachments': [not_claimed_attachment()],
4563
}
4664

4765
await slack.query(methods.CHAT_POST_MESSAGE, response)
File renamed without changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
def ticket_dialog(clicker_email, text):
2+
return {
3+
"callback_id": "open_ticket",
4+
"title": "Open New Ticket",
5+
"submit_label": "Submit",
6+
"elements": [
7+
{
8+
"type": "text",
9+
"label": "Email",
10+
"name": "email",
11+
"subtype": "email",
12+
"value": clicker_email
13+
14+
},
15+
{
16+
"type": "text",
17+
"label": "Request Type",
18+
"name": "type",
19+
"value": text
20+
},
21+
{
22+
"type": "textarea",
23+
"label": "Details",
24+
"name": "details"
25+
}
26+
]
27+
}
File renamed without changes.

pybot/endpoints/slack/messages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from slack.events import Message
55
from slack import methods
66

7-
from pybot.endpoints.slack.event_messages.tech import TechTerms
7+
from .message_templates.tech import TechTerms
88

99
logger = logging.getLogger(__name__)
1010

pybot/endpoints/slack/utils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
load_dotenv()
66

77
COMMUNITY_CHANNEL = os.environ.get("COMMUNITY_CHANNEL") or "G12343"
8-
REPORT_CHANNEL = os.environ.get('REPORT_CHANNEL') or 'G8NDRJJF9'
8+
MODERATOR_CHANNEL = os.environ.get('REPORT_CHANNEL') or 'G8NDRJJF9'
99
APP_TOKEN = os.environ.get('APP_TOKEN') or "123"
1010
YELP_TOKEN = os.environ.get('YELP_TOKEN') or 'token'
1111
PYBACK_HOST = os.environ.get('PYBACK_HOST') or 'pyback'

pybot/endpoints/slack/utils/action_messages.py

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
from time import time
33
from typing import List
44

5-
from slack.events import Message
5+
from pybot.endpoints.slack.utils import MODERATOR_CHANNEL
66

7-
from pybot.endpoints.slack.utils import REPORT_CHANNEL
7+
TICKET_OPTIONS = {
8+
'notStarted': 'Not Started',
9+
'inProgress': 'In-progress',
10+
'waitingOnUser': 'Waiting on User',
11+
'complete': 'Complete'
12+
}
813

914

1015
def now():
@@ -16,14 +21,57 @@ def now():
1621

1722

1823
def base_response(action):
19-
response = Message()
24+
response = {
25+
'text': action['original_message'].get('text', None),
26+
'channel': action['channel']['id'],
27+
'ts': action['message_ts'],
28+
}
29+
return response
30+
31+
32+
def updated_ticket_status(action):
33+
selected_option = action['actions'][0]['selected_options'][0]
34+
selected_option['text'] = TICKET_OPTIONS[selected_option['value']]
2035

21-
response['text'] = action['original_message']['text']
22-
response['channel'] = action['channel']['id']
23-
response['ts'] = action['message_ts']
36+
updated_attachments = action['original_message']['attachments']
37+
updated_attachments[0]['actions'][0]['selected_options'] = [selected_option]
38+
response = {
39+
**base_response(action),
40+
'attachments': updated_attachments
41+
}
2442
return response
2543

2644

45+
def ticket_attachments(action):
46+
user_id = action['user']['id']
47+
request_type = action['submission']['type']
48+
email = action['submission']['email']
49+
details = action['submission']['details']
50+
attachments = [
51+
{
52+
'text': '',
53+
'callback_id': 'ticket_status',
54+
"response_type": "in_channel",
55+
"fallback": "request details should have been here",
56+
"fields": [
57+
{"title": "User", "value": f"<@{user_id}>", "short": True},
58+
{"title": "Email", "value": f"{email}", "short": True},
59+
{"title": "Request Type", "value": f"{request_type}", "short": True},
60+
{"title": "Details", "value": f"{details}", "short": True},
61+
],
62+
'actions': [
63+
{
64+
'name': 'status', 'text': 'Current Status', 'type': 'select',
65+
'selected_options': [{'text': 'Not Started', 'value': 'notStarted'}],
66+
'options': [{'text': text, 'value': value} for value, text in TICKET_OPTIONS.items()]
67+
}
68+
]
69+
},
70+
not_claimed_attachment()
71+
]
72+
return attachments
73+
74+
2775
def greeted_attachment(user_id: str) -> List[dict]:
2876
return [{
2977
"text": f":100:<@{user_id}> has greeted the new user!:100:\n"
@@ -60,24 +108,25 @@ def not_greeted_attachment():
60108

61109

62110
def not_claimed_attachment():
63-
return [{
111+
return {
64112
'text': "",
65-
"fallback": "",
113+
"fallback": "not claimed attachment",
66114
"color": "#3AA3E3",
67115
"callback_id": "claimed",
68116
"attachment_type": "default",
117+
'short': True,
69118
"actions": [{
70119
"name": "claimed",
71120
"text": "Claim",
72121
"type": "button",
73122
"style": "primary",
74123
"value": "claimed"
75124
}]
76-
}]
125+
}
77126

78127

79128
def claimed_attachment(user_id):
80-
return [{
129+
return {
81130
"text": f"Claimed by <@{user_id}>\n"
82131
f"<!date^{now()}^Claimed at {{date_num}} {{time_secs}}|Failed to parse time>",
83132
"fallback": "",
@@ -91,7 +140,7 @@ def claimed_attachment(user_id):
91140
"style": "danger",
92141
"value": "reset_claim",
93142
}]
94-
}]
143+
}
95144

96145

97146
def reset_greet_message(user_id):
@@ -165,7 +214,7 @@ def build_report_message(slack_id, details, message_details):
165214

166215
return {
167216
"text": message,
168-
"channel": REPORT_CHANNEL,
217+
"channel": MODERATOR_CHANNEL,
169218
"attachments": attachment
170219
}
171220

0 commit comments

Comments
 (0)