/
chat_send_common.go
133 lines (115 loc) · 4.21 KB
/
chat_send_common.go
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2016 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
package client
import (
"fmt"
"time"
"golang.org/x/net/context"
"github.com/keybase/client/go/libkb"
"github.com/keybase/client/go/protocol/chat1"
"github.com/keybase/client/go/protocol/gregor1"
"github.com/keybase/client/go/protocol/keybase1"
)
type ChatSendArg struct {
resolvingRequest chatConversationResolvingRequest
// Only one of these should be set
message string
setTopicName string
setHeadline string
clearHeadline bool
deleteHistory *chat1.MessageDeleteHistory
ephemeralLifetime time.Duration
hasTTY bool
nonBlock bool
team bool // TODO is this field used?
mustNotExist bool
}
func chatSend(ctx context.Context, g *libkb.GlobalContext, c ChatSendArg) error {
resolver, err := newChatConversationResolver(g)
if err != nil {
return err
}
createIfNotExists := true
if c.clearHeadline || c.deleteHistory != nil {
createIfNotExists = false
}
conversation, userChosen, err := resolver.Resolve(ctx, c.resolvingRequest, chatConversationResolvingBehavior{
CreateIfNotExists: createIfNotExists,
MustNotExist: c.mustNotExist,
Interactive: c.hasTTY,
IdentifyBehavior: keybase1.TLFIdentifyBehavior_CHAT_CLI,
})
if err != nil {
return err
}
conversationInfo := conversation.Info
var arg chat1.PostLocalArg
arg.ConversationID = conversationInfo.Id
arg.IdentifyBehavior = keybase1.TLFIdentifyBehavior_CHAT_CLI
var msg chat1.MessagePlaintext
// msgV1.ClientHeader.{Sender,SenderDevice} are filled by service
msg.ClientHeader.Conv = conversationInfo.Triple
msg.ClientHeader.TlfName = conversationInfo.TlfName
msg.ClientHeader.TlfPublic = (conversationInfo.Visibility == keybase1.TLFVisibility_PUBLIC)
// Whether the user is really sure they want to send to the selected conversation.
// We require an additional confirmation if the choose menu was used.
confirmed := !userChosen
// Do one of set topic name, set headline, or send message
switch {
case c.setTopicName != "":
msg.ClientHeader.MessageType = chat1.MessageType_METADATA
msg.MessageBody = chat1.NewMessageBodyWithMetadata(chat1.MessageConversationMetadata{ConversationTitle: c.setTopicName})
case c.setHeadline != "":
msg.ClientHeader.MessageType = chat1.MessageType_HEADLINE
msg.MessageBody = chat1.NewMessageBodyWithHeadline(chat1.MessageHeadline{Headline: c.setHeadline})
case c.clearHeadline:
msg.ClientHeader.MessageType = chat1.MessageType_HEADLINE
msg.MessageBody = chat1.NewMessageBodyWithHeadline(chat1.MessageHeadline{Headline: ""})
case c.deleteHistory != nil:
msg.ClientHeader.MessageType = chat1.MessageType_DELETEHISTORY
msg.ClientHeader.DeleteHistory = c.deleteHistory
msg.MessageBody = chat1.NewMessageBodyWithDeletehistory(*c.deleteHistory)
default:
// Ask for message contents
if len(c.message) == 0 {
promptText := "Please enter message content: "
if !confirmed {
promptText = fmt.Sprintf("Send to [%s]? Hit Ctrl-C to cancel, or enter message content to send: ", conversationInfo.TlfName)
}
c.message, err = g.UI.GetTerminalUI().Prompt(PromptDescriptorEnterChatMessage, promptText)
if err != nil {
return err
}
confirmed = true
}
if c.ephemeralLifetime != 0 {
lifetime := gregor1.ToDurationSec(c.ephemeralLifetime)
msg.ClientHeader.EphemeralMetadata = &chat1.MsgEphemeralMetadata{Lifetime: lifetime}
}
msg.ClientHeader.MessageType = chat1.MessageType_TEXT
msg.MessageBody = chat1.NewMessageBodyWithText(chat1.MessageText{Body: c.message})
}
if !confirmed {
promptText := fmt.Sprintf("Send to [%s]? Hit Ctrl-C to cancel, or enter to send.", conversationInfo.TlfName)
_, err = g.UI.GetTerminalUI().Prompt(PromptDescriptorEnterChatMessage, promptText)
if err != nil {
return err
}
confirmed = true
}
arg.Msg = msg
if c.nonBlock {
var nbarg chat1.PostLocalNonblockArg
nbarg.ConversationID = arg.ConversationID
nbarg.Msg = arg.Msg
nbarg.IdentifyBehavior = arg.IdentifyBehavior
if _, err = resolver.ChatClient.PostLocalNonblock(ctx, nbarg); err != nil {
return err
}
} else {
if _, err = resolver.ChatClient.PostLocal(ctx, arg); err != nil {
return err
}
}
return nil
}