-
Notifications
You must be signed in to change notification settings - Fork 6
/
main.go
162 lines (145 loc) · 4.72 KB
/
main.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// This is a small bot that messages someone (ZX9TZZ7P) and replies to everything with a qouted echo
package main
import (
"fmt"
"log"
"os"
"github.com/o3ma/o3"
)
func main() {
var (
pass = []byte{0xA, 0xB, 0xC, 0xD, 0xE}
tr o3.ThreemaRest
idpath = "threema.id"
abpath = "address.book"
tid o3.ThreemaID
pubnick = "parrot"
rid = "ZX9TZZ7P" //remote ID. Change this to the ID you want to send the initial message to.
)
// check whether an id file exists or else create a new one
if _, err := os.Stat(idpath); err != nil {
var err error
tid, err = tr.CreateIdentity()
if err != nil {
fmt.Println("CreateIdentity failed")
log.Fatal(err)
}
fmt.Printf("Saving ID to %s\n", idpath)
err = tid.SaveToFile(idpath, pass)
if err != nil {
fmt.Println("saving ID failed")
log.Fatal(err)
}
} else {
fmt.Printf("Loading ID from %s\n", idpath)
tid, err = o3.LoadIDFromFile(idpath, pass)
if err != nil {
log.Fatal(err)
}
}
fmt.Printf("Using ID: %s\n", tid.String())
tid.Nick = o3.NewPubNick(pubnick)
ctx := o3.NewSessionContext(tid)
//check if we can load an addressbook
if _, err := os.Stat(abpath); !os.IsNotExist(err) {
fmt.Printf("Loading addressbook from %s\n", abpath)
err = ctx.ID.Contacts.ImportFrom(abpath)
if err != nil {
fmt.Println("loading addressbook failed")
log.Fatal(err)
}
}
// check if we know the remote ID for
// (just demonstration purposes \bc sending and receiving functions do this lookup for us)
if _, b := ctx.ID.Contacts.Get(rid); b == false {
//retrieve the ID from Threema's servers
myID := o3.NewIDString(rid)
fmt.Printf("Retrieving %s from directory server\n", myID.String())
myContact, err := tr.GetContactByID(myID)
if err != nil {
log.Fatal(err)
}
// add them to our address book
ctx.ID.Contacts.Add(myContact)
//and save the address book
fmt.Printf("Saving addressbook to %s\n", abpath)
err = ctx.ID.Contacts.SaveTo(abpath)
if err != nil {
fmt.Println("saving addressbook failed")
log.Fatal(err)
}
}
//start asyncronous error handling
go func() {
for e := range ctx.ErrorChan {
fmt.Println(e)
os.Exit(1)
}
}()
// let the session begin
fmt.Println("Starting session")
sendMsgChan, receiveMsgChan, err := ctx.Run()
if err != nil {
log.Fatal(err)
}
// send our initial message to our recipient
fmt.Println("Sending initial message")
err = ctx.SendTextMessage(rid, "Say something!", sendMsgChan)
if err != nil {
log.Fatal(err)
}
// handle incoming messages
for receivedMessage := range receiveMsgChan {
if receivedMessage.Err != nil {
fmt.Printf("Error Receiving Message: %s\n", receivedMessage.Err)
continue
}
switch msg := receivedMessage.Msg.(type) {
case o3.ImageMessage:
// display the image if you like
case o3.AudioMessage:
// play the audio if you like
case o3.TextMessage:
// respond with a quote of what was send to us.
// but only if it's no a message we sent to ourselves, avoid recursive neverending qoutes
if tid.String() == msg.Sender().String() {
continue
}
// to make the quote render nicely in the app we use "markdown"
// of the form "> PERSONWEQUOTE: Text of qoute\nSomething we wanna add."
qoute := fmt.Sprintf("> %s: %s\n%s", msg.Sender(), msg.Text(), "Exactly!")
// we use the convinient "SendTextMessage" function to send
err = ctx.SendTextMessage(msg.Sender().String(), qoute, sendMsgChan)
if err != nil {
log.Fatal(err)
}
// confirm to the sender that we received the message
// this is how one can send messages manually without helper functions like "SendTextMessage"
drm, err := o3.NewDeliveryReceiptMessage(&ctx, msg.Sender().String(), msg.ID(), o3.MSGDELIVERED)
if err != nil {
log.Fatal(err)
}
sendMsgChan <- drm
// give a thumbs up
upm, err := o3.NewDeliveryReceiptMessage(&ctx, msg.Sender().String(), msg.ID(), o3.MSGAPPROVED)
if err != nil {
log.Fatal(err)
}
sendMsgChan <- upm
case o3.GroupTextMessage:
fmt.Printf("%s for Group [%x] created by [%s]:\n%s\n", msg.Sender(), msg.GroupID(), msg.GroupCreator(), msg.Text())
case o3.GroupManageSetNameMessage:
fmt.Printf("Group [%x] is now called %s\n", msg.GroupID(), msg.Name())
case o3.GroupManageSetMembersMessage:
fmt.Printf("Group [%x] now includes %v\n", msg.GroupID(), msg.Members())
case o3.GroupMemberLeftMessage:
fmt.Printf("Member [%s] left the Group [%x]\n", msg.Sender(), msg.GroupID())
case o3.DeliveryReceiptMessage:
fmt.Printf("Message [%x] has been acknowledged by the server.\n", msg.MsgID())
case o3.TypingNotificationMessage:
fmt.Printf("Typing Notification from %s: [%x]\n", msg.Sender(), msg.OnOff)
default:
fmt.Printf("Unknown message type from: %s\nContent: %#v", msg.Sender(), msg)
}
}
}