diff --git a/bot/command.go b/bot/command.go index 99f9fac..d647958 100644 --- a/bot/command.go +++ b/bot/command.go @@ -109,6 +109,26 @@ func (b *Bot) parseCommand(message string) []string { return strings.Split(message, " ") } +func (b *Bot) sendIntroduction(ctx context.Context, roomID id.RoomID) { + span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("sendIntroduction")) + defer span.Finish() + + var msg strings.Builder + msg.WriteString("Hello!\n\n") + msg.WriteString("This is Postmoogle - a bot that bridges Email to Matrix.\n\n") + msg.WriteString(fmt.Sprintf( + "To get started, assign an email address to this room by sending a `%s %s SOME_INBOX` command.\n", + b.prefix, + optionMailbox, + )) + msg.WriteString(fmt.Sprintf( + "You will then be able to send emails to `SOME_INBOX@%s` and have them appear in this room.", + b.domain, + )) + + b.Notice(ctx, roomID, msg.String()) +} + func (b *Bot) sendHelp(ctx context.Context, roomID id.RoomID) { span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("sendHelp")) defer span.Finish() diff --git a/bot/sync.go b/bot/sync.go index 81f6b64..4cc7af6 100644 --- a/bot/sync.go +++ b/bot/sync.go @@ -9,6 +9,16 @@ import ( ) func (b *Bot) initSync() { + b.lp.OnEventType( + event.StateMember, + func(_ mautrix.EventSource, evt *event.Event) { + // Trying to debug the membership=join event being handled twice here. + eventJSON, _ := evt.MarshalJSON() + b.log.Debug(string(eventJSON)) + + go b.onMembership(evt) + }, + ) b.lp.OnEventType( event.EventMessage, func(_ mautrix.EventSource, evt *event.Event) { @@ -21,6 +31,31 @@ func (b *Bot) initSync() { }) } +func (b *Bot) onMembership(evt *event.Event) { + hub := sentry.CurrentHub().Clone() + hub.ConfigureScope(func(scope *sentry.Scope) { + scope.SetUser(sentry.User{ID: evt.Sender.String()}) + scope.SetContext("event", map[string]string{ + "id": evt.ID.String(), + "room": evt.RoomID.String(), + "sender": evt.Sender.String(), + }) + }) + + if evt.Sender == b.lp.GetClient().UserID { + // Handle membership events related to our own (bot) user first + + switch evt.Content.AsMember().Membership { + case event.MembershipJoin: + b.onBotJoin(evt, hub) + } + + return + } + + // Handle membership events related to other users +} + func (b *Bot) onMessage(evt *event.Event) { // ignore own messages if evt.Sender == b.lp.GetClient().UserID { @@ -70,3 +105,13 @@ func (b *Bot) onEncryptedMessage(evt *event.Event) { b.handle(span.Context(), decrypted) } + +// onBotJoin handles the "bot joined the room" event +func (b *Bot) onBotJoin(evt *event.Event, hub *sentry.Hub) { + ctx := sentry.SetHubOnContext(context.Background(), hub) + span := sentry.StartSpan(ctx, "http.server", sentry.TransactionName("onBotJoin")) + defer span.Finish() + + b.sendIntroduction(ctx, evt.RoomID) + b.sendHelp(ctx, evt.RoomID) +}