ampelmaennchen.git

ref: master

matrix/bot.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
package matrix

import (
	"apiote.xyz/p/ampelmaennchen/config"
	"apiote.xyz/p/ampelmaennchen/db"

	"context"
	"fmt"
	"regexp"

	"maunium.net/go/mautrix/appservice"
	"maunium.net/go/mautrix/id"
)

func createRegistration(asToken, hsToken, domain string) *appservice.Registration {
	registration := appservice.CreateRegistration()
	if asToken != "" && hsToken != "" {
		registration.AppToken = asToken
		registration.ServerToken = hsToken
	}
	registration.ID = "ampelmaennchen"
	registration.URL = "null"
	registration.SenderLocalpart = "ampelmaennchen"
	registration.SoruEphemeralEvents = true
	registration.EphemeralEvents = true

	userIDs := appservice.NamespaceList{}
	r := regexp.MustCompile("^" + regexp.QuoteMeta("@ampelmaennchen:"+domain) + "$")
	userIDs.Register(r, true)

	registration.Namespaces = appservice.Namespaces{
		UserIDs: userIDs,
	}
	return registration
}

func createAppService(hsDomain, hsURL, asHostname string, asPort uint16) (*appservice.AppService, error) {
	asToken, hsToken, err := db.GetRegistrationTokens()
	if err != nil {
		return nil, fmt.Errorf("while getting registration tokens: %w", err)
	}
	opts := appservice.CreateOpts{
		Registration:     createRegistration(asToken, hsToken, hsDomain),
		HomeserverDomain: hsDomain,
		HomeserverURL:    hsURL,
		HostConfig: appservice.HostConfig{
			Hostname: asHostname,
			Port:     asPort,
		},
	}
	as, err := appservice.CreateFull(opts)
	if err != nil {
		return nil, fmt.Errorf("while creating app service: %w", err)
	}
	return as, nil
}

func CreateAppService(config config.MatrixConfig, recreate bool) (*appservice.AppService, error) {
	if recreate {
		err := db.DeleteRegistrationTokens()
		if err != nil {
			return nil, fmt.Errorf("while deleting old tokens: %w", err)
		}
	}

	as, err := createAppService(config.Homeserver.Domain, config.Homeserver.Address, config.Homeserver.Address, config.Appservice.Port)
	if err != nil {
		return nil, fmt.Errorf("while creating app service: %w", err)
	}

	err = db.SaveRegistrationTokens(as.Registration.AppToken, as.Registration.ServerToken)
	if err != nil {
		return nil, fmt.Errorf("while saving registraion tokens: %w", err)
	}

	return as, nil
}

func RegistrationExists() (bool, error) {
	as, hs, err := db.GetRegistrationTokens()
	if err != nil {
		return false, err
	}
	return (as != "" && hs != ""), nil
}

func setBotDisplayName(intent *appservice.IntentAPI) error {
	return intent.SetDisplayName(context.Background(), "Ampelmännchen")
}

func setBotAvatar(intent *appservice.IntentAPI, cfg config.MatrixConfig) error {
	uri, err := uploadImage(intent, cfg.BotAvatarPath)
	if err != nil {
		return fmt.Errorf("while uploading avatar: %w", err)
	}

	err = intent.SetAvatarURL(context.Background(), uri)
	if err != nil {
		return fmt.Errorf("while setting avatar: %w", err)
	}
	return nil
}

func ConfigureBot(as *appservice.AppService, cfg config.MatrixConfig) error {
	botuser := id.NewUserID("ampelmaennchen", cfg.Homeserver.Domain)
	intent := as.Intent(botuser)

	displayNameInDB, avatarPathInDB, err := db.GetBot()
	if err != nil {
		return fmt.Errorf("while getting bot from db: %w", err)
	}

	if displayNameInDB != "Ampelmännchen" {
		err = setBotDisplayName(intent)
		if err != nil {
			return fmt.Errorf("while setting bot name: %w", err)
		}
		displayNameInDB = "Ampelmännchen"
		err = db.SaveBot(displayNameInDB, avatarPathInDB)
		if err != nil {
			return fmt.Errorf("while saving bot name: %w", err)
		}
	}

	if avatarPathInDB != cfg.BotAvatarPath {
		err = setBotAvatar(intent, cfg)
		if err != nil {
			return fmt.Errorf("while setting bot avatar: %w", err)
		}
		avatarPathInDB = cfg.BotAvatarPath
		err = db.SaveBot(displayNameInDB, avatarPathInDB)
		if err != nil {
			return fmt.Errorf("while saving bot avatar: %w", err)
		}
	}

	return nil
}