-
Notifications
You must be signed in to change notification settings - Fork 3
/
slackwrapper.py
122 lines (91 loc) · 3.75 KB
/
slackwrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
SlackWrapper
This handles the incoming message events from Slack by:
1. Determining if we need to translate the message
2. Converting user ids in the message to names
3. Sending the text out to get translated
4. Posting the translated text into the "other" channel
"""
import os
import requests
import json
from openaiwrapper import OpenAIWrapper
from threading import Thread
class SlackWrapper:
# Init is responsible for fetching the environment variables that have
# API keys, endpoints, and channel ids for our particular org
def __init__(self):
self.channel_english = os.getenv('SLACK_ENG_CHAN_ID')
self.channel_spanish = os.getenv('SLACK_ESP_CHAN_ID')
self.slack_token = os.getenv('SLACK_TOKEN')
self.post_english = os.getenv('SLACK_ENG_URL')
self.post_spanish = os.getenv('SLACK_ESP_URL')
self.slack_verification = os.getenv('SLACK_VERIFY')
# Lookup a user's name from their id
def get_user_name(self, id:str):
payload = {'token': self.slack_token, 'user': id}
print(self.slack_token[:10], flush=True)
resp = requests.post('https://slack.com/api/users.info', data=payload)
print(resp, flush=True)
data = json.loads(resp.content)
if 'error' in data:
print(f'get_user_name({id}): Error {data["error"]}', flush=True)
if 'user' in data and 'name' in data['user']:
return data['user']['name']
return '-system-'
# Take a line of text with 0 or more embedded <@id> in it and expand the
# ids to user names
def expand_users(self, text):
result = ''
while (loc := text.find('<@')) != -1:
result = result + text[:loc] + '@'
text = text[loc + 2:]
end = text.find('>')
if end == -1:
break
user_id = text[:end]
text = text[end + 1:]
user_name = self.get_user_name(user_id)
result = result + user_name
result = result + text
return result
@staticmethod
def post_text(url, text):
headers = { 'content-type': 'application/json' }
data = { 'text': text }
r = requests.post(url, data=json.dumps(data), headers=headers)
return r # Not that anyone cares...
# This runs in the background so we can respond to slack quickly
def do_translate(self, to_lang, text, user):
text = self.expand_users(text)
if user is not None:
user = self.get_user_name(user)
oai = OpenAIWrapper()
if to_lang == 'english':
new_text = oai.to_english(text)
if user is not None:
new_text = f"_{user} said:_\n" + new_text
self.post_text(self.post_english, new_text)
else:
new_text = oai.to_spanish(text)
if user is not None:
new_text = f"_{user} dijo:_\n" + new_text
self.post_text(self.post_spanish, new_text)
# Handle an event notification from slack
# Because the call to open
def handle_event(self, event):
c = event['channel']
# We may get a lot more traffic than we'd like, so make sure
# it's coming from the channels we're interested in
if c not in [self.channel_english, self.channel_spanish]:
return ''
if 'user' not in event:
# system message
return ''
# Make sure there's something to translate
if 'text' not in event or len(event['text'].strip()) == 0:
return ''
to_language = ['english', 'spanish'][c != self.channel_spanish]
th = Thread(target=self.do_translate, args=(to_language, event['text'], event['user']))
th.start()
return ''