misso/utils/get_userinfo.go

61 lines
1.9 KiB
Go

package utils
import (
"context"
"encoding/json"
"fmt"
"misso/consts"
"misso/global"
"misso/misskey"
"misso/types"
)
func GetUserinfo(subject string) (*types.MisskeyUser, error) {
// Check cache key
global.Logger.Debugf("Checking userinfo cache...")
userinfoCacheKey := fmt.Sprintf(consts.REDIS_KEY_SHARE_USER_INFO, subject)
exist, err := global.Redis.Exists(context.Background(), userinfoCacheKey).Result()
if err != nil {
global.Logger.Errorf("Failed to check userinfo exist status with error: %v", err)
} else if exist > 0 {
// Exist, get from cache
userinfoCacheBytes, err := global.Redis.Get(context.Background(), userinfoCacheKey).Bytes()
if err != nil {
global.Logger.Errorf("Userinfo cache exists, but failed to retrieve with error: %v", err)
} else {
// Parse into user
var userinfo types.MisskeyUser
err = json.Unmarshal(userinfoCacheBytes, &userinfo)
if err != nil {
global.Logger.Errorf("Failed to parse userinfo cache into json with error: %v", err)
} else {
// Works!
global.Logger.Debugf("Get cached userinfo successfully.")
return &userinfo, nil
}
}
}
// Fallback to get info directly, we need user's access token.
global.Logger.Debugf("No cached userinfo found (or valid), trying to get latest response.")
accessTokenCacheKey := fmt.Sprintf(consts.REDIS_KEY_SHARE_ACCESS_TOKEN, subject)
accessToken, err := global.Redis.Get(context.Background(), accessTokenCacheKey).Result()
if err != nil {
global.Logger.Errorf("Failed to get user access token with error: %v", err)
return nil, err
}
// Get userinfo with access token
userinfo, err := misskey.GetUserinfo(accessToken)
if err != nil {
global.Logger.Errorf("Failed to get user info with saved access token with error: %v", err)
return nil, err
}
// Save userinfo into redis
_ = SaveUserinfo(subject, userinfo) // Ignore errors
return userinfo, nil
}