|
@@ -25,6 +25,7 @@ type Registration struct {
|
25
|
25
|
Name string `yaml:"name"`
|
26
|
26
|
Topic string `yaml:"topic"`
|
27
|
27
|
Values []string `yaml:"values"`
|
|
28
|
+ lastValue string
|
28
|
29
|
}
|
29
|
30
|
|
30
|
31
|
type Config struct {
|
|
@@ -155,7 +156,7 @@ func sendMessage(text string, user int64) {
|
155
|
156
|
}
|
156
|
157
|
}
|
157
|
158
|
|
158
|
|
-func sendKeyboardReply(name string, chat int64, message int) {
|
|
159
|
+func sendKeyboardReply(text string, name string, chat int64, message int) {
|
159
|
160
|
var rows [][]tgbotapi.KeyboardButton
|
160
|
161
|
for reg := range config.Registration {
|
161
|
162
|
if name == config.Registration[reg].Name {
|
|
@@ -168,7 +169,7 @@ func sendKeyboardReply(name string, chat int64, message int) {
|
168
|
169
|
}
|
169
|
170
|
keyboard := tgbotapi.NewOneTimeReplyKeyboard(rows...)
|
170
|
171
|
|
171
|
|
- msg := tgbotapi.NewMessage(chat, "Select option below...")
|
|
172
|
+ msg := tgbotapi.NewMessage(chat, text)
|
172
|
173
|
msg.ReplyToMessageID = message
|
173
|
174
|
msg.ReplyMarkup = keyboard
|
174
|
175
|
_, err := bot.Send(msg)
|
|
@@ -231,6 +232,13 @@ func register(name string, topic string, values string) error {
|
231
|
232
|
|
232
|
233
|
config.Registration = append(config.Registration, r)
|
233
|
234
|
writeConfig()
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+ token := mqttClient.Subscribe(topic, 0, onMessageReceived)
|
|
238
|
+ if token.Wait() && token.Error() != nil {
|
|
239
|
+ log.Printf("MQTT sub error: %v", token.Error())
|
|
240
|
+ }
|
|
241
|
+
|
234
|
242
|
return nil
|
235
|
243
|
}
|
236
|
244
|
|
|
@@ -242,8 +250,14 @@ func remove(s []Registration, i int) []Registration {
|
242
|
250
|
func unregister(name string) error {
|
243
|
251
|
for reg := range config.Registration {
|
244
|
252
|
if name == config.Registration[reg].Name {
|
|
253
|
+ token := mqttClient.Unsubscribe(config.Registration[reg].Topic)
|
|
254
|
+ if token.Wait() && token.Error() != nil {
|
|
255
|
+ log.Println("MQTT unsub error: %v", token.Error())
|
|
256
|
+ }
|
|
257
|
+
|
245
|
258
|
config.Registration = remove(config.Registration, reg)
|
246
|
259
|
writeConfig()
|
|
260
|
+
|
247
|
261
|
return nil
|
248
|
262
|
}
|
249
|
263
|
}
|
|
@@ -282,6 +296,34 @@ func topicForName(name string) string {
|
282
|
296
|
return "unknown"
|
283
|
297
|
}
|
284
|
298
|
|
|
299
|
+func lastValueForCommand(name string) string {
|
|
300
|
+ ret := ""
|
|
301
|
+
|
|
302
|
+ for reg := range config.Registration {
|
|
303
|
+ if name == config.Registration[reg].Name {
|
|
304
|
+ if len(config.Registration[reg].lastValue) > 0 {
|
|
305
|
+ ret = "Current state: \""
|
|
306
|
+ ret += config.Registration[reg].lastValue
|
|
307
|
+ ret += "\"\n"
|
|
308
|
+ }
|
|
309
|
+ break
|
|
310
|
+ }
|
|
311
|
+ }
|
|
312
|
+
|
|
313
|
+ ret += "Select option below..."
|
|
314
|
+ return ret
|
|
315
|
+}
|
|
316
|
+
|
|
317
|
+func onMessageReceived(client mqtt.Client, message mqtt.Message) {
|
|
318
|
+ log.Printf("MQTT Rx: %s @ %s", message.Payload(), message.Topic())
|
|
319
|
+
|
|
320
|
+ for reg := range config.Registration {
|
|
321
|
+ if config.Registration[reg].Topic == message.Topic() {
|
|
322
|
+ config.Registration[reg].lastValue = string(message.Payload()[:])
|
|
323
|
+ }
|
|
324
|
+ }
|
|
325
|
+}
|
|
326
|
+
|
285
|
327
|
func main() {
|
286
|
328
|
err := readConfig()
|
287
|
329
|
if err != nil {
|
|
@@ -305,11 +347,20 @@ func main() {
|
305
|
347
|
opts.SetPassword(config.Mqtt.Pass)
|
306
|
348
|
|
307
|
349
|
mqttClient = mqtt.NewClient(opts)
|
308
|
|
- if token := mqttClient.Connect(); token.Wait() && token.Error() != nil {
|
|
350
|
+ token := mqttClient.Connect();
|
|
351
|
+ if token.Wait() && token.Error() != nil {
|
309
|
352
|
log.Printf("MQTT error: %v", token.Error())
|
310
|
353
|
os.Exit(1)
|
311
|
354
|
}
|
312
|
355
|
|
|
356
|
+ // Subscribe to registered topics
|
|
357
|
+ for reg := range config.Registration {
|
|
358
|
+ token := mqttClient.Subscribe(config.Registration[reg].Topic, 0, onMessageReceived)
|
|
359
|
+ if token.Wait() && token.Error() != nil {
|
|
360
|
+ log.Printf("MQTT sub error: %v", token.Error())
|
|
361
|
+ }
|
|
362
|
+ }
|
|
363
|
+
|
313
|
364
|
// Initialize Telegram
|
314
|
365
|
bot, err = tgbotapi.NewBotAPI(config.Key)
|
315
|
366
|
if err != nil {
|
|
@@ -381,6 +432,10 @@ func main() {
|
381
|
432
|
reply = fmt.Sprintf("Error authorizing ID! %v", err)
|
382
|
433
|
} else {
|
383
|
434
|
reply = fmt.Sprintf("Ok, authorized %d.", id)
|
|
435
|
+
|
|
436
|
+ // also notify user
|
|
437
|
+ text := "You have now been authorized by the admin. Try /help for commands."
|
|
438
|
+ sendMessage(text, id)
|
384
|
439
|
}
|
385
|
440
|
}
|
386
|
441
|
} else {
|
|
@@ -460,14 +515,19 @@ func main() {
|
460
|
515
|
}
|
461
|
516
|
} else if isRegisteredCommand(update.Message.Text[1:]) {
|
462
|
517
|
reply = ""
|
463
|
|
- sendKeyboardReply(update.Message.Text[1:], update.Message.Chat.ID, update.Message.MessageID)
|
|
518
|
+ text := lastValueForCommand(update.Message.Text[1:])
|
|
519
|
+ sendKeyboardReply(text, update.Message.Text[1:], update.Message.Chat.ID, update.Message.MessageID)
|
464
|
520
|
}
|
465
|
521
|
}
|
466
|
522
|
} else {
|
467
|
|
- log.Printf("Message from unauthorized user. %s %d", update.Message.From.UserName, update.Message.From.ID)
|
468
|
|
- notifyAdminAuthorization(update.Message.From.ID, update.Message.From.UserName)
|
|
523
|
+ // only request admin-auth when /start has been sent!
|
|
524
|
+ // this avoids most bot spam.
|
|
525
|
+ if update.Message.Text == "/start" {
|
|
526
|
+ log.Printf("Message from unauthorized user. %s %d", update.Message.From.UserName, update.Message.From.ID)
|
|
527
|
+ notifyAdminAuthorization(update.Message.From.ID, update.Message.From.UserName)
|
469
|
528
|
|
470
|
|
- reply = "Sorry, you are not authorized. Administrator confirmation required."
|
|
529
|
+ reply = "Sorry, you are not authorized. Administrator confirmation required."
|
|
530
|
+ }
|
471
|
531
|
}
|
472
|
532
|
|
473
|
533
|
// send a reply
|