Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USER_ACTIVATEDイベントを追加 #2266

Merged
merged 3 commits into from Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions event/topic.go
Expand Up @@ -24,6 +24,10 @@ const (
// user_id: uuid.UUID
// datetime: time.Time
UserOffline = "user.offline"
// UserActivated ユーザーの凍結が解除された
// Fields:
// user: *model.User
UserActivated = "user.activated"
// UserViewStateChanged ユーザーの閲覧状態が変化した
// Fields:
// user_id: uuid.UUID
Expand Down
56 changes: 36 additions & 20 deletions repository/gorm/user.go
Expand Up @@ -217,13 +217,15 @@ func (r *userRepository) UpdateUser(id uuid.UUID, args repository.UpdateUserArgs
if id == uuid.Nil {
return repository.ErrNilID
}

var (
u model.User
activate bool
deactivate bool
changed bool
count int
)
err := r.db.Transaction(func(tx *gorm.DB) error {
var u model.User
if err := tx.Preload("Profile").First(&u, model.User{ID: id}).Error; err != nil {
return convertError(err)
}
Expand All @@ -237,7 +239,10 @@ func (r *userRepository) UpdateUser(id uuid.UUID, args repository.UpdateUserArgs
}
if args.UserState.Valid {
changes["status"] = args.UserState.V.Int()
if args.UserState.V.Int() == model.UserAccountStatusDeactivated.Int() {
switch args.UserState.V.Int() {
case model.UserAccountStatusActive.Int():
activate = true
case model.UserAccountStatusDeactivated.Int():
deactivate = true
}
}
Expand Down Expand Up @@ -302,24 +307,35 @@ func (r *userRepository) UpdateUser(id uuid.UUID, args repository.UpdateUserArgs
if args.LastOnline.Valid && count == 1 {
return nil // 最終オンライン日時のみの更新の時はUserUpdatedイベントを発生させない
}
if changed {
r.forgetCache(id)
if args.IconFileID.Valid && count == 1 {
r.hub.Publish(hub.Message{
Name: event.UserIconUpdated,
Fields: hub.Fields{
"user_id": id,
"file_id": args.IconFileID.V,
},
})
} else {
r.hub.Publish(hub.Message{
Name: event.UserUpdated,
Fields: hub.Fields{
"user_id": id,
},
})
}
if !changed {
return nil
}

r.forgetCache(id)
switch {
case args.IconFileID.Valid && count == 1:
r.hub.Publish(hub.Message{
Name: event.UserIconUpdated,
Fields: hub.Fields{
"user_id": id,
"file_id": args.IconFileID.V,
},
})
case activate:
r.hub.Publish(hub.Message{
Name: event.UserActivated,
Fields: hub.Fields{
"user": &u,
},
})
fallthrough
default:
r.hub.Publish(hub.Message{
Name: event.UserUpdated,
Fields: hub.Fields{
"user_id": id,
},
})
}
return nil
}
Expand Down
3 changes: 3 additions & 0 deletions service/bot/event/events.go
Expand Up @@ -31,6 +31,8 @@ const (
ChannelTopicChanged model.BotEventType = "CHANNEL_TOPIC_CHANGED"
// UserCreated ユーザー作成イベント
UserCreated model.BotEventType = "USER_CREATED"
// UserActivated ユーザー凍結解除イベント
UserActivated model.BotEventType = "USER_ACTIVATED"
// StampCreated スタンプ作成イベント
StampCreated model.BotEventType = "STAMP_CREATED"
// TagAdded タグ追加イベント
Expand Down Expand Up @@ -75,6 +77,7 @@ func init() {
ChannelCreated,
ChannelTopicChanged,
UserCreated,
UserActivated,
StampCreated,
TagAdded,
TagRemoved,
Expand Down
20 changes: 20 additions & 0 deletions service/bot/event/payload/ev_user_activated.go
@@ -0,0 +1,20 @@
package payload

import (
"time"

"github.com/traPtitech/traQ/model"
)

// UserActivated USER_ACTIVATEDイベントペイロード
type UserActivated struct {
Base
User User `json:"user"`
}

func MakeUserActivated(et time.Time, user model.UserInfo) *UserActivated {
return &UserActivated{
Base: MakeBase(et),
User: MakeUser(user),
}
}
33 changes: 33 additions & 0 deletions service/bot/handler/ev_user_activated.go
@@ -0,0 +1,33 @@
package handler

import (
"fmt"
"time"

"github.com/leandro-lugaresi/hub"

"github.com/traPtitech/traQ/model"
"github.com/traPtitech/traQ/service/bot/event"
"github.com/traPtitech/traQ/service/bot/event/payload"
)

func UserActivated(ctx Context, datetime time.Time, _ string, fields hub.Fields) error {
user := fields["user"].(model.UserInfo)

bots, err := ctx.GetBots(event.UserActivated)
if err != nil {
return fmt.Errorf("failed to GetBots: %w", err)
}
if len(bots) == 0 {
return nil
}

if err := ctx.Multicast(
event.UserActivated,
payload.MakeUserActivated(datetime, user),
bots,
); err != nil {
return fmt.Errorf("failed to multicast: %w", err)
}
return nil
}
48 changes: 48 additions & 0 deletions service/bot/handler/ev_user_activated_test.go
@@ -0,0 +1,48 @@
package handler

import (
"testing"
"time"

"github.com/gofrs/uuid"
"github.com/golang/mock/gomock"
"github.com/leandro-lugaresi/hub"
"github.com/stretchr/testify/assert"

intevent "github.com/traPtitech/traQ/event"
"github.com/traPtitech/traQ/model"
"github.com/traPtitech/traQ/service/bot/event"
"github.com/traPtitech/traQ/service/bot/event/payload"
"github.com/traPtitech/traQ/service/bot/handler/mock_handler"
)

func TestUserActivated(t *testing.T) {
t.Parallel()

b := &model.Bot{
ID: uuid.NewV3(uuid.Nil, "b"),
BotUserID: uuid.NewV3(uuid.Nil, "bu"),
SubscribeEvents: model.BotEventTypesFromArray([]string{event.UserActivated.String()}),
State: model.BotActive,
}

t.Run("success", func(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
handlerCtx := mock_handler.NewMockContext(ctrl)
registerBot(t, handlerCtx, b)

user := &model.User{
ID: uuid.NewV3(uuid.Nil, "u"),
Name: "activated_user",
Status: model.UserAccountStatusActive,
Bot: false,
}
et := time.Now()

expectMulticast(handlerCtx, event.UserActivated, payload.MakeUserActivated(et, user), []*model.Bot{b})
assert.NoError(t, UserActivated(handlerCtx, et, intevent.UserActivated, hub.Fields{
"user": user,
}))
})
}
1 change: 1 addition & 0 deletions service/bot/handlers.go
Expand Up @@ -19,6 +19,7 @@ var eventHandlerSet = map[string]eventHandler{
intevent.MessageDeleted: handler.MessageDeleted,
intevent.MessageUpdated: handler.MessageUpdated,
intevent.UserCreated: handler.UserCreated,
intevent.UserActivated: handler.UserActivated,
intevent.ChannelCreated: handler.ChannelCreated,
intevent.ChannelTopicUpdated: handler.ChannelTopicUpdated,
intevent.StampCreated: handler.StampCreated,
Expand Down