From 7c4a1b7ba41d831b1ef0b5f7260e32740c68e1ac Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 21 Jul 2019 21:30:39 -0400 Subject: [PATCH] Combine ChatIn and ChatOut structs to ChatAPI and move them to types.go --- chatIn.go | 126 +++------------------------------------- chatOut.go | 94 +++++++----------------------- keybase.go | 10 ++-- types.go | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+), 196 deletions(-) create mode 100644 types.go diff --git a/chatIn.go b/chatIn.go index 332464b..a770e68 100644 --- a/chatIn.go +++ b/chatIn.go @@ -7,118 +7,6 @@ import ( "time" ) -// ChatIn holds information about a message received by the `keybase chat api-listen` command -type ChatIn struct { - Type string `json:"type"` - Source string `json:"source"` - Msg chatInMsg `json:"msg"` -} -type chatInSender struct { - UID string `json:"uid"` - Username string `json:"username"` - DeviceID string `json:"device_id"` - DeviceName string `json:"device_name"` -} -type chatInAddedtoteam struct { - Team string `json:"team"` - Adder string `json:"adder"` - Addee string `json:"addee"` - Owners []string `json:"owners"` - Admins []string `json:"admins"` - Writers []string `json:"writers"` - Readers []string `json:"readers"` -} -type chatInBulkaddtoconv struct { - Usernames []string `json:"usernames"` -} -type chatInCommits struct { - CommitHash string `json:"commitHash"` - Message string `json:"message"` - AuthorName string `json:"authorName"` - AuthorEmail string `json:"authorEmail"` - Ctime int `json:"ctime"` -} -type chatInRefs struct { - RefName string `json:"refName"` - Commits []chatInCommits `json:"commits"` - MoreCommitsAvailable bool `json:"moreCommitsAvailable"` - IsDelete bool `json:"isDelete"` -} -type chatInGitpush struct { - Team string `json:"team"` - Pusher string `json:"pusher"` - RepoName string `json:"repoName"` - RepoID string `json:"repoID"` - Refs []chatInRefs `json:"refs"` - PushType int `json:"pushType"` - PreviousRepoName string `json:"previousRepoName"` -} -type chatInSystem struct { - SystemType int `json:"systemType"` - Addedtoteam chatInAddedtoteam `json:"addedtoteam"` - Bulkaddtoconv chatInBulkaddtoconv `json:"bulkaddtoconv"` - Gitpush chatInGitpush `json:"gitpush"` -} -type chatInResult struct { - ResultTyp int `json:"resultTyp"` - Sent string `json:"sent"` -} -type chatInPayments struct { - Username string `json:"username"` - PaymentText string `json:"paymentText"` - Result chatInResult `json:"result"` -} -type chatInUserMentions struct { - Text string `json:"text"` - UID string `json:"uid"` -} -type chatInTeamMentions struct { - Name string `json:"name"` - Channel string `json:"channel"` -} -type chatInReaction struct { - M int `json:"m"` - B string `json:"b"` -} -type chatInDelete struct { - MessageIDs []int `json:"messageIDs"` -} -type chatInEdit struct { - MessageID int `json:"messageID"` - Body string `json:"body"` - Payments []chatInPayments `json:"payments"` - UserMentions []chatInUserMentions `json:"userMentions"` - TeamMentions []chatInTeamMentions `json:"teamMentions"` -} -type chatInText struct { - Body string `json:"body"` - Payments []chatInPayments `json:"payments"` - UserMentions []chatInUserMentions `json:"userMentions"` - TeamMentions []chatInTeamMentions `json:"teamMentions"` -} -type chatInContent struct { - Type string `json:"type"` - Delete chatInDelete `json:"delete"` - Edit chatInEdit `json:"edit"` - Reaction chatInReaction `json:"reaction"` - System chatInSystem `json:"system"` - Text chatInText `json:"text"` -} -type chatInMsg struct { - ID int `json:"id"` - Channel Channel `json:"channel"` - Sender chatInSender `json:"sender"` - SentAt int `json:"sent_at"` - SentAtMs int64 `json:"sent_at_ms"` - Content chatInContent `json:"content"` - Unread bool `json:"unread"` - AtMentionUsernames []string `json:"at_mention_usernames"` - IsEphemeral bool `json:"is_ephemeral"` - Etime int64 `json:"etime"` - HasPairwiseMacs bool `json:"has_pairwise_macs"` - ChannelMention string `json:"channel_mention"` -} - // RunOptions holds a set of options to be passed to Run type RunOptions struct { Heartbeat int64 // Send a heartbeat through the channel every X minutes (0 = off) @@ -149,7 +37,7 @@ func createFiltersString(channels []Channel) string { } // Run `keybase chat api-listen` to get new messages coming into keybase and send them into the channel -func getNewMessages(k *Keybase, c chan<- ChatIn, execOptions []string) { +func getNewMessages(k *Keybase, c chan<- ChatAPI, execOptions []string) { execString := []string{"chat", "api-listen"} if len(execOptions) > 0 { execString = append(execString, execOptions...) @@ -159,8 +47,8 @@ func getNewMessages(k *Keybase, c chan<- ChatIn, execOptions []string) { stdOut, _ := execCmd.StdoutPipe() execCmd.Start() scanner := bufio.NewScanner(stdOut) - go func(scanner *bufio.Scanner, c chan<- ChatIn) { - var jsonData ChatIn + go func(scanner *bufio.Scanner, c chan<- ChatAPI) { + var jsonData ChatAPI for scanner.Scan() { json.Unmarshal([]byte(scanner.Text()), &jsonData) c <- jsonData @@ -171,7 +59,7 @@ func getNewMessages(k *Keybase, c chan<- ChatIn, execOptions []string) { } // Run runs `keybase chat api-listen`, and passes incoming messages to the message handler func -func (k *Keybase) Run(handler func(ChatIn), options ...RunOptions) { +func (k *Keybase) Run(handler func(ChatAPI), options ...RunOptions) { var heartbeatFreq int64 runOptions := make([]string, 0) if len(options) > 0 { @@ -197,7 +85,7 @@ func (k *Keybase) Run(handler func(ChatIn), options ...RunOptions) { runOptions = append(runOptions, createFilterString(options[0].FilterChannel)) } } - c := make(chan ChatIn, 50) + c := make(chan ChatAPI, 50) defer close(c) if heartbeatFreq > 0 { go heartbeat(c, time.Duration(heartbeatFreq)*time.Minute) @@ -209,8 +97,8 @@ func (k *Keybase) Run(handler func(ChatIn), options ...RunOptions) { } // heartbeat sends a message through the channel with a message type of `heartbeat` -func heartbeat(c chan<- ChatIn, freq time.Duration) { - m := ChatIn{ +func heartbeat(c chan<- ChatAPI, freq time.Duration) { + m := ChatAPI{ Type: "heartbeat", } count := 0 diff --git a/chatOut.go b/chatOut.go index 935043e..8ccc69a 100644 --- a/chatOut.go +++ b/chatOut.go @@ -6,89 +6,39 @@ import ( "strings" ) -// chatOut holds data to be sent to the Chat API -type chatOut struct { - Method string `json:"method"` - Params chatOutParams `json:"params"` -} -type Channel struct { - Name string `json:"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 Channel `json:"channel"` - MessageID int `json:"message_id"` - Message chatOutMessage `json:"message"` -} -type chatOutParams struct { - Options chatOutOptions `json:"options"` -} - -// chatOutResult holds data received after sending to API -type chatOutResult struct { - Result ChatOut `json:"result"` -} -type chatOutResultRatelimits struct { - Tank string `json:"tank,omitempty"` - Capacity int `json:"capacity,omitempty"` - Reset int `json:"reset,omitempty"` - Gas int `json:"gas,omitempty"` -} -type conversation struct { - ID string `json:"id"` - 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 { - Message string `json:"message,omitempty"` - ID int `json:"id,omitempty"` - Ratelimits []chatOutResultRatelimits `json:"ratelimits,omitempty"` - Conversations []conversation `json:"conversations,omitempty"` - Offline bool `json:"offline,omitempty"` -} - // chatAPIOut sends JSON requests to the chat API and returns its response. -func chatAPIOut(keybasePath string, c chatOut) (chatOutResult, error) { +func chatAPIOut(keybasePath string, c ChatAPI) (ChatAPI, error) { jsonBytes, _ := json.Marshal(c) cmd := exec.Command(keybasePath, "chat", "api", "-m", string(jsonBytes)) cmdOut, err := cmd.Output() if err != nil { - return chatOutResult{}, err + return ChatAPI{}, err } - var r chatOutResult + var r ChatAPI json.Unmarshal(cmdOut, &r) return r, nil } // Send sends a chat message -func (c Chat) Send(message ...string) (ChatOut, error) { - m := chatOut{} +func (c Chat) Send(message ...string) (ChatAPI, error) { + m := ChatAPI{} m.Method = "send" m.Params.Options.Channel = c.Channel m.Params.Options.Message.Body = strings.Join(message, " ") r, err := chatAPIOut(c.keybase.Path, m) if err != nil { - return ChatOut{}, err + return ChatAPI{}, err } - return r.Result, nil + return r, nil } // Edit edits a previously sent chat message -func (c Chat) Edit(messageId int, message ...string) (ChatOut, error) { - m := chatOut{} +func (c Chat) Edit(messageId int, message ...string) (ChatAPI, error) { + m := ChatAPI{} m.Method = "edit" m.Params.Options.Channel = c.Channel m.Params.Options.Message.Body = strings.Join(message, " ") @@ -96,14 +46,14 @@ func (c Chat) Edit(messageId int, message ...string) (ChatOut, error) { r, err := chatAPIOut(c.keybase.Path, m) if err != nil { - return ChatOut{}, err + return ChatAPI{}, err } - return r.Result, nil + return r, nil } // React sends a reaction to a message. -func (c Chat) React(messageId int, reaction string) (ChatOut, error) { - m := chatOut{} +func (c Chat) React(messageId int, reaction string) (ChatAPI, error) { + m := ChatAPI{} m.Method = "reaction" m.Params.Options.Channel = c.Channel m.Params.Options.Message.Body = reaction @@ -111,30 +61,30 @@ func (c Chat) React(messageId int, reaction string) (ChatOut, error) { r, err := chatAPIOut(c.keybase.Path, m) if err != nil { - return ChatOut{}, err + return ChatAPI{}, err } - return r.Result, nil + return r, nil } // Delete deletes a chat message -func (c Chat) Delete(messageId int) (ChatOut, error) { - m := chatOut{} +func (c Chat) Delete(messageId int) (ChatAPI, error) { + m := ChatAPI{} m.Method = "delete" m.Params.Options.Channel = c.Channel m.Params.Options.MessageID = messageId r, err := chatAPIOut(c.keybase.Path, m) if err != nil { - return ChatOut{}, err + return ChatAPI{}, err } - return r.Result, nil + return r, nil } // ChatList returns a list of all conversations. -func (k *Keybase) ChatList() ([]conversation, error) { - m := chatOut{} +func (k *Keybase) ChatList() (ChatAPI, error) { + m := ChatAPI{} m.Method = "list" r, err := chatAPIOut(k.Path, m) - return r.Result.Conversations, err + return r, err } diff --git a/keybase.go b/keybase.go index 8ec674c..680603c 100644 --- a/keybase.go +++ b/keybase.go @@ -32,15 +32,15 @@ type Chat struct { } type chat interface { - Send(message ...string) (ChatOut, error) - Edit(messageId int, message ...string) (ChatOut, error) - React(messageId int, reaction string) (ChatOut, error) - Delete(messageId int) (ChatOut, error) + Send(message ...string) (ChatAPI, error) + Edit(messageId int, message ...string) (ChatAPI, error) + React(messageId int, reaction string) (ChatAPI, error) + Delete(messageId int) (ChatAPI, error) } type keybase interface { NewChat(channel Channel) Chat - Run(handler func(ChatIn), options ...RunOptions) + Run(handler func(ChatAPI), options ...RunOptions) ChatList() ([]conversation, error) loggedIn() bool username() string diff --git a/types.go b/types.go new file mode 100644 index 0000000..6899926 --- /dev/null +++ b/types.go @@ -0,0 +1,166 @@ +package keybase + +// ChatAPI holds information about a message received by the `keybase chat api-listen` command +type ChatAPI struct { + Type string `json:"type,omitempty"` + Source string `json:"source,omitempty"` + Msg msg `json:"msg,omitempty"` + Method string `json:"method,omitempty"` + Params params `json:"params,omitempty"` + Message string `json:"message,omitempty"` + ID int `json:"id,omitempty"` + Ratelimits []rateLimits `json:"ratelimits,omitempty"` + Conversations []conversation `json:"conversations,omitempty"` + Offline bool `json:"offline,omitempty"` + Result result `json:"result,omitempty"` +} +type sender struct { + UID string `json:"uid"` + Username string `json:"username"` + DeviceID string `json:"device_id"` + DeviceName string `json:"device_name"` +} +type addedtoteam struct { + Team string `json:"team"` + Adder string `json:"adder"` + Addee string `json:"addee"` + Owners []string `json:"owners"` + Admins []string `json:"admins"` + Writers []string `json:"writers"` + Readers []string `json:"readers"` +} +type bulkaddtoconv struct { + Usernames []string `json:"usernames"` +} +type commits struct { + CommitHash string `json:"commitHash"` + Message string `json:"message"` + AuthorName string `json:"authorName"` + AuthorEmail string `json:"authorEmail"` + Ctime int `json:"ctime"` +} +type refs struct { + RefName string `json:"refName"` + Commits []commits `json:"commits"` + MoreCommitsAvailable bool `json:"moreCommitsAvailable"` + IsDelete bool `json:"isDelete"` +} +type gitpush struct { + Team string `json:"team"` + Pusher string `json:"pusher"` + RepoName string `json:"repoName"` + RepoID string `json:"repoID"` + Refs []refs `json:"refs"` + PushType int `json:"pushType"` + PreviousRepoName string `json:"previousRepoName"` +} +type system struct { + SystemType int `json:"systemType"` + Addedtoteam addedtoteam `json:"addedtoteam"` + Bulkaddtoconv bulkaddtoconv `json:"bulkaddtoconv"` + Gitpush gitpush `json:"gitpush"` +} +type paymentsResult struct { + ResultTyp int `json:"resultTyp"` + Sent string `json:"sent"` +} +type payments struct { + Username string `json:"username"` + PaymentText string `json:"paymentText"` + Result paymentsResult `json:"result"` +} +type userMentions struct { + Text string `json:"text"` + UID string `json:"uid"` +} +type teamMentions struct { + Name string `json:"name"` + Channel string `json:"channel"` +} +type reaction struct { + M int `json:"m"` + B string `json:"b"` +} +type delete struct { + MessageIDs []int `json:"messageIDs"` +} +type edit struct { + MessageID int `json:"messageID"` + Body string `json:"body"` + Payments []payments `json:"payments"` + UserMentions []userMentions `json:"userMentions"` + TeamMentions []teamMentions `json:"teamMentions"` +} +type text struct { + Body string `json:"body"` + Payments []payments `json:"payments"` + UserMentions []userMentions `json:"userMentions"` + TeamMentions []teamMentions `json:"teamMentions"` +} +type content struct { + Type string `json:"type"` + Delete delete `json:"delete"` + Edit edit `json:"edit"` + Reaction reaction `json:"reaction"` + System system `json:"system"` + Text text `json:"text"` +} +type msg struct { + ID int `json:"id"` + Channel Channel `json:"channel"` + Sender sender `json:"sender"` + SentAt int `json:"sent_at"` + SentAtMs int64 `json:"sent_at_ms"` + Content content `json:"content"` + Unread bool `json:"unread"` + AtMentionUsernames []string `json:"at_mention_usernames"` + IsEphemeral bool `json:"is_ephemeral"` + Etime int64 `json:"etime"` + HasPairwiseMacs bool `json:"has_pairwise_macs"` + ChannelMention string `json:"channel_mention"` +} +type Channel struct { + Name string `json:"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 message struct { + Body string `json:"body"` +} +type options struct { + Channel Channel `json:"channel"` + MessageID int `json:"message_id"` + Message message `json:"message"` + Pagination pagination `json:"pagination"` +} +type params struct { + Options options `json:"options"` +} +type pagination struct { + Next string `json:"next"` + Previous string `json:"previous"` + Num int `json:"num"` +} +type result struct { + Messages []messages `json:"messages,omitempty"` + Pagination pagination `json:"pagination"` +} +type messages struct { + Msg msg `json:"msg,omitempty"` +} +type rateLimits struct { + Tank string `json:"tank,omitempty"` + Capacity int `json:"capacity,omitempty"` + Reset int `json:"reset,omitempty"` + Gas int `json:"gas,omitempty"` +} +type conversation struct { + ID string `json:"id"` + Channel Channel `json:"channel"` + Unread bool `json:"unread"` + ActiveAt int `json:"active_at"` + ActiveAtMs int64 `json:"active_at_ms"` + MemberStatus string `json:"member_status"` +}