mirror of https://github.com/velour/catbase.git
Merge pull request #84 from velour/slack_parsing
slack: import velour/chat parsing
This commit is contained in:
commit
c399db225a
|
@ -0,0 +1,96 @@
|
|||
package slack
|
||||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// fixText strips all of the Slack-specific annotations from message text,
|
||||
// replacing it with the equivalent display form.
|
||||
// Currently it:
|
||||
// • Replaces user mentions like <@U124356> with @ followed by the user's nick.
|
||||
// This uses the lookupUser function, which must map U1243456 to the nick.
|
||||
// • Replaces user mentions like <U123456|nick> with the user's nick.
|
||||
// • Strips < and > surrounding links.
|
||||
//
|
||||
// This was directly bogarted from velour/chat with emoji conversion removed.
|
||||
func fixText(findUser func(id string) (string, bool), text string) string {
|
||||
var output []rune
|
||||
for len(text) > 0 {
|
||||
r, i := utf8.DecodeRuneInString(text)
|
||||
text = text[i:]
|
||||
switch {
|
||||
case r == '<':
|
||||
var tag []rune
|
||||
for {
|
||||
r, i := utf8.DecodeRuneInString(text)
|
||||
text = text[i:]
|
||||
switch {
|
||||
case r == '>':
|
||||
if t, ok := fixTag(findUser, tag); ok {
|
||||
output = append(output, t...)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case len(text) == 0:
|
||||
output = append(output, '<')
|
||||
output = append(output, tag...)
|
||||
output = append(output, r)
|
||||
default:
|
||||
tag = append(tag, r)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
output = append(output, r)
|
||||
}
|
||||
}
|
||||
return string(output)
|
||||
}
|
||||
|
||||
func fixTag(findUser func(string) (string, bool), tag []rune) ([]rune, bool) {
|
||||
switch {
|
||||
case hasPrefix(tag, "@U"):
|
||||
if i := indexRune(tag, '|'); i >= 0 {
|
||||
return tag[i+1:], true
|
||||
}
|
||||
if findUser != nil {
|
||||
if u, ok := findUser(string(tag[1:])); ok {
|
||||
return []rune(u), true
|
||||
}
|
||||
}
|
||||
return tag, true
|
||||
|
||||
case hasPrefix(tag, "#C"):
|
||||
if i := indexRune(tag, '|'); i >= 0 {
|
||||
return append([]rune{'#'}, tag[i+1:]...), true
|
||||
}
|
||||
|
||||
case hasPrefix(tag, "http"):
|
||||
if i := indexRune(tag, '|'); i >= 0 {
|
||||
tag = tag[:i]
|
||||
}
|
||||
return tag, true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func hasPrefix(text []rune, prefix string) bool {
|
||||
for _, r := range prefix {
|
||||
if len(text) == 0 || text[0] != r {
|
||||
return false
|
||||
}
|
||||
text = text[1:]
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func indexRune(text []rune, find rune) int {
|
||||
for i, r := range text {
|
||||
if r == find {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
|
@ -306,14 +306,13 @@ var urlDetector = regexp.MustCompile(`<(.+)://([^|^>]+).*>`)
|
|||
func (s *Slack) buildMessage(m slackMessage) msg.Message {
|
||||
text := html.UnescapeString(m.Text)
|
||||
|
||||
// remove <> from URLs, URLs may also be <url|description>
|
||||
text = urlDetector.ReplaceAllString(text, "${1}://${2}")
|
||||
text = fixText(s.getUser, text)
|
||||
|
||||
isCmd, text := bot.IsCmd(s.config, text)
|
||||
|
||||
isAction := m.SubType == "me_message"
|
||||
|
||||
u := s.getUser(m.User)
|
||||
u, _ := s.getUser(m.User)
|
||||
if m.Username != "" {
|
||||
u = m.Username
|
||||
}
|
||||
|
@ -460,9 +459,9 @@ func (s *Slack) connect() {
|
|||
}
|
||||
|
||||
// Get username for Slack user ID
|
||||
func (s *Slack) getUser(id string) string {
|
||||
func (s *Slack) getUser(id string) (string, bool) {
|
||||
if name, ok := s.users[id]; ok {
|
||||
return name
|
||||
return name, true
|
||||
}
|
||||
|
||||
log.Printf("User %s not already found, requesting info", id)
|
||||
|
@ -472,17 +471,17 @@ func (s *Slack) getUser(id string) string {
|
|||
if err != nil || resp.StatusCode != 200 {
|
||||
log.Printf("Error posting user info request: %d %s",
|
||||
resp.StatusCode, err)
|
||||
return "UNKNOWN"
|
||||
return "UNKNOWN", false
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var userInfo slackUserInfoResp
|
||||
err = json.NewDecoder(resp.Body).Decode(&userInfo)
|
||||
if err != nil {
|
||||
log.Println("Error decoding response: ", err)
|
||||
return "UNKNOWN"
|
||||
return "UNKNOWN", false
|
||||
}
|
||||
s.users[id] = userInfo.User.Name
|
||||
return s.users[id]
|
||||
return s.users[id], true
|
||||
}
|
||||
|
||||
// Who gets usernames out of a channel
|
||||
|
@ -513,7 +512,8 @@ func (s *Slack) Who(id string) []string {
|
|||
|
||||
handles := []string{}
|
||||
for _, member := range chanInfo.Channel.Members {
|
||||
handles = append(handles, s.getUser(member))
|
||||
u, _ := s.getUser(member)
|
||||
handles = append(handles, u)
|
||||
}
|
||||
log.Printf("Returning %d handles", len(handles))
|
||||
return handles
|
||||
|
|
Loading…
Reference in New Issue