Browse Source

Add support for incoming messages. This breaks NewChat() in previous versions

main
Sam 5 years ago
parent
commit
ae3ed73adc
  1. 55
      chatIn.go
  2. 43
      chatOut.go
  3. 44
      keybase.go

55
chatIn.go

@ -1,19 +1,17 @@ @@ -1,19 +1,17 @@
package keybase
import ()
import (
"bufio"
"encoding/json"
"fmt"
"os/exec"
)
type chatIn struct {
type ChatIn struct {
Type string `json:"type"`
Source string `json:"source"`
Msg chatInMsg `json:"msg"`
}
type chatInChannel struct {
Name string `json:"name"`
Public bool `json:"public"`
MembersType string `json:"members_type"`
TopicType string `json:"topic_type"`
TopicName string `json:"topic_name"`
}
type chatInSender struct {
UID string `json:"uid"`
Username string `json:"username"`
@ -84,7 +82,7 @@ type chatInContent struct { @@ -84,7 +82,7 @@ type chatInContent struct {
}
type chatInMsg struct {
ID int `json:"id"`
Channel chatInChannel `json:"channel"`
Channel Channel `json:"channel"`
Sender chatInSender `json:"sender"`
SentAt int `json:"sent_at"`
SentAtMs int64 `json:"sent_at_ms"`
@ -96,3 +94,40 @@ type chatInMsg struct { @@ -96,3 +94,40 @@ type chatInMsg struct {
HasPairwiseMacs bool `json:"has_pairwise_macs"`
ChannelMention string `json:"channel_mention"`
}
// Creates a string of json-encoded channels to pass to keybase chat api-listen --filter-channels
func createFilterString(channelFilters ...Channel) string {
if len(channelFilters) == 0 {
return "[]"
}
jsonBytes, _ := json.Marshal(channelFilters)
return fmt.Sprintf("%s", string(jsonBytes))
}
// Get new messages coming into keybase and send them into the channel
func getNewMessages(k Keybase, c chan<- ChatIn, filterString string) {
keybaseListen := exec.Command(k.Path, "chat", "api-listen", "--filter-channels", filterString)
keybaseOutput, _ := keybaseListen.StdoutPipe()
keybaseListen.Start()
scanner := bufio.NewScanner(keybaseOutput)
var jsonData ChatIn
for scanner.Scan() {
json.Unmarshal([]byte(scanner.Text()), &jsonData)
c <- jsonData
}
}
// Runner() runs keybase chat api-listen, and passes incoming messages to the message handler func
func (k Keybase) Runner(handler func(ChatIn), channelFilters ...Channel) {
c := make(chan ChatIn, 10)
defer close(c)
go getNewMessages(k, c, createFilterString(channelFilters...))
for {
chat, ok := <-c
if ok {
go handler(chat)
}
}
}

43
chatOut.go

@ -7,21 +7,22 @@ import ( @@ -7,21 +7,22 @@ import (
)
// ---- Struct for sending to API
type chatOut struct { // not exported
type chatOut struct {
Method string `json:"method"`
Params chatOutParams `json:"params"`
}
type chatOutChannel struct {
type Channel struct {
Name string `json:"name"`
Public bool `json:"public"`
MembersType string `json:"members_type"`
TopicName string `json:"topic_name"`
Public bool `json:"public,omitempty"`
MembersType string `json:"members_type,omitempty"`
TopicType string `json:"topic_type,omitempty"`
TopicName string `json:"topic_name,omitempty"`
}
type chatOutMessage struct {
Body string `json:"body"`
}
type chatOutOptions struct {
Channel chatOutChannel `json:"channel"`
Channel Channel `json:"channel"`
MessageID int `json:"message_id"`
Message chatOutMessage `json:"message"`
}
@ -41,22 +42,15 @@ type chatOutResultRatelimits struct { @@ -41,22 +42,15 @@ type chatOutResultRatelimits struct {
Reset int `json:"reset,omitempty"`
Gas int `json:"gas,omitempty"`
}
type chatOutResultChannel struct {
Name string `json:"name"`
Public bool `json:"public"`
MembersType string `json:"members_type"`
TopicType string `json:"topic_type,omitempty"`
TopicName string `json:"topic_name,omitempty"`
}
type conversation struct {
ID string `json:"id"`
Channel chatOutResultChannel `json:"channel"`
Channel Channel `json:"channel"`
Unread bool `json:"unread"`
ActiveAt int `json:"active_at"`
ActiveAtMs int64 `json:"active_at_ms"`
MemberStatus string `json:"member_status"`
}
type ChatOut struct { // exported
type ChatOut struct {
Message string `json:"message,omitempty"`
ID int `json:"id,omitempty"`
Ratelimits []chatOutResultRatelimits `json:"ratelimits,omitempty"`
@ -86,10 +80,7 @@ func chatAPIOut(keybasePath string, c chatOut) (chatOutResult, error) { @@ -86,10 +80,7 @@ func chatAPIOut(keybasePath string, c chatOut) (chatOutResult, error) {
func (c Chat) Send(message ...string) (ChatOut, error) {
m := chatOut{}
m.Method = "send"
m.Params.Options.Channel.Name = c.Name
m.Params.Options.Channel.Public = c.Public
m.Params.Options.Channel.MembersType = c.MembersType
m.Params.Options.Channel.TopicName = c.TopicName
m.Params.Options.Channel = c.Channel
m.Params.Options.Message.Body = strings.Join(message, " ")
r, err := chatAPIOut(c.keybase.Path, m)
@ -103,10 +94,7 @@ func (c Chat) Send(message ...string) (ChatOut, error) { @@ -103,10 +94,7 @@ func (c Chat) Send(message ...string) (ChatOut, error) {
func (c Chat) Edit(messageId int, message ...string) (ChatOut, error) {
m := chatOut{}
m.Method = "edit"
m.Params.Options.Channel.Name = c.Name
m.Params.Options.Channel.Public = c.Public
m.Params.Options.Channel.MembersType = c.MembersType
m.Params.Options.Channel.TopicName = c.TopicName
m.Params.Options.Channel = c.Channel
m.Params.Options.Message.Body = strings.Join(message, " ")
m.Params.Options.MessageID = messageId
@ -121,9 +109,7 @@ func (c Chat) Edit(messageId int, message ...string) (ChatOut, error) { @@ -121,9 +109,7 @@ func (c Chat) Edit(messageId int, message ...string) (ChatOut, error) {
func (c Chat) React(messageId int, reaction string) (ChatOut, error) {
m := chatOut{}
m.Method = "reaction"
m.Params.Options.Channel.Name = c.Name
m.Params.Options.Channel.MembersType = c.MembersType
m.Params.Options.Channel.TopicName = c.TopicName
m.Params.Options.Channel = c.Channel
m.Params.Options.Message.Body = reaction
m.Params.Options.MessageID = messageId
@ -138,10 +124,7 @@ func (c Chat) React(messageId int, reaction string) (ChatOut, error) { @@ -138,10 +124,7 @@ func (c Chat) React(messageId int, reaction string) (ChatOut, error) {
func (c Chat) Delete(messageId int) (ChatOut, error) {
m := chatOut{}
m.Method = "delete"
m.Params.Options.Channel.Name = c.Name
m.Params.Options.Channel.Public = c.Public
m.Params.Options.Channel.MembersType = c.MembersType
m.Params.Options.Channel.TopicName = c.TopicName
m.Params.Options.Channel = c.Channel
m.Params.Options.MessageID = messageId
r, err := chatAPIOut(c.keybase.Path, m)

44
keybase.go

@ -25,17 +25,10 @@ type Keybase struct { @@ -25,17 +25,10 @@ type Keybase struct {
Version string
}
// Channel is a map of options that can be passed to NewChat()
type Channel map[string]interface{}
// Chat holds basic information about a specific conversation
type Chat struct {
keybase Keybase
Name string
Public bool
MembersType string
TopicName string
TopicType string
Channel Channel
}
type chat interface {
@ -46,7 +39,8 @@ type chat interface { @@ -46,7 +39,8 @@ type chat interface {
}
type keybase interface {
NewChat(channel map[string]interface{}) Chat
NewChat(channel Channel) Chat
Runner(handler func(ChatIn), channelFilters ...Channel)
ChatList() ([]conversation, error)
loggedIn() bool
username() string
@ -75,35 +69,11 @@ func NewKeybase(path ...string) Keybase { @@ -75,35 +69,11 @@ func NewKeybase(path ...string) Keybase {
}
// Return a new Chat instance
func (k Keybase) NewChat(channel map[string]interface{}) Chat {
var c Chat = Chat{}
c.keybase = k
if value, ok := channel["Name"].(string); ok == true {
c.Name = value
}
if value, ok := channel["Public"].(bool); ok == true {
c.Public = value
} else {
c.Public = false
}
if value, ok := channel["MembersType"].(string); ok == true {
c.MembersType = value
} else {
c.MembersType = USER
}
if value, ok := channel["TopicName"].(string); ok == true {
c.TopicName = value
} else {
if c.MembersType == TEAM {
c.TopicName = "general"
}
}
if value, ok := channel["TopicType"].(string); ok == true {
c.TopicType = value
} else {
c.TopicType = CHAT
func (k Keybase) NewChat(channel Channel) Chat {
return Chat{
keybase: k,
Channel: channel,
}
return c
}
// username() returns the username of the currently logged-in Keybase user.

Loading…
Cancel
Save