Documentation
¶
Index ¶
- Constants
- func AlbumsFromAlbumSimplified(albums []AlbumSimplified) []assets.Album
- func OptionConnectionTimeout(d time.Duration) clientOption
- func OptionDryRun(dryRun bool) clientOption
- func OptionVerifySSL(verify bool) clientOption
- type AboutInfo
- type AlbumContent
- type AlbumSimplified
- type Asset
- type AssetResponse
- type AssetSimplified
- type ExifInfo
- type GetAssetOptions
- type ImmichAlbumInterface
- type ImmichAssetInterface
- type ImmichClient
- func (ic *ImmichClient) AddAssetToAlbum(ctx context.Context, albumID string, assets []string) ([]UpdateAlbumResult, error)
- func (ic *ImmichClient) AssetUpload(ctx context.Context, la *assets.Asset) (AssetResponse, error)
- func (ic *ImmichClient) BulkTagAssets(ctx context.Context, tagIDs []string, assetIDs []string) (struct{ ... }, error)
- func (ic *ImmichClient) CreateAlbum(ctx context.Context, name string, description string, assetsIDs []string) (assets.Album, error)
- func (ic *ImmichClient) CreateJob(ctx context.Context, name JobName) error
- func (ic *ImmichClient) CreateStack(ctx context.Context, ids []string) (string, error)
- func (ic *ImmichClient) DeleteAlbum(ctx context.Context, id string) error
- func (ic *ImmichClient) DeleteAssets(ctx context.Context, id []string, forceDelete bool) error
- func (ic *ImmichClient) DownloadAsset(ctx context.Context, id string) (io.ReadCloser, error)
- func (ic *ImmichClient) EnableAppTrace(w io.Writer)
- func (ic *ImmichClient) GetAboutInfo(ctx context.Context) (AboutInfo, error)
- func (ic *ImmichClient) GetAlbumInfo(ctx context.Context, id string, withoutAssets bool) (AlbumContent, error)
- func (ic *ImmichClient) GetAllAlbums(ctx context.Context) ([]AlbumSimplified, error)
- func (ic *ImmichClient) GetAllAssets(ctx context.Context) ([]*Asset, error)
- func (ic *ImmichClient) GetAllAssetsWithFilter(ctx context.Context, query *SearchMetadataQuery, filter func(*Asset) error) error
- func (ic *ImmichClient) GetAllTags(ctx context.Context) ([]TagSimplified, error)
- func (ic *ImmichClient) GetAssetAlbums(ctx context.Context, assetID string) ([]AlbumSimplified, error)
- func (ic *ImmichClient) GetAssetInfo(ctx context.Context, id string) (*Asset, error)
- func (ic *ImmichClient) GetAssetStatistics(ctx context.Context) (UserStatistics, error)
- func (ic *ImmichClient) GetAssetsAlbums(ctx context.Context, id string) ([]assets.Album, error)
- func (ic *ImmichClient) GetAssetsByHash(ctx context.Context, hash string) ([]*Asset, error)
- func (ic *ImmichClient) GetAssetsByImageName(ctx context.Context, name string) ([]*Asset, error)
- func (ic *ImmichClient) GetEndPoint() string
- func (ic *ImmichClient) GetJobs(ctx context.Context) (map[string]Job, error)
- func (ic *ImmichClient) GetServerStatistics(ctx context.Context) (ServerStatistics, error)
- func (ic *ImmichClient) GetSupportedMediaTypes(ctx context.Context) (filetypes.SupportedMedia, error)
- func (ic *ImmichClient) IsExtensionPrefix(ext string) bool
- func (ic *ImmichClient) IsIgnoredExt(ext string) bool
- func (ic *ImmichClient) PingServer(ctx context.Context) error
- func (ic *ImmichClient) ReplaceAsset(ctx context.Context, ID string, la *assets.Asset) (AssetResponse, error)
- func (ic *ImmichClient) SendJobCommand(ctx context.Context, jobID JobID, command JobCommand, force bool) (resp SendJobCommandResponse, err error)
- func (ic *ImmichClient) SetDeviceUUID(deviceUUID string)
- func (ic *ImmichClient) SetEndPoint(endPoint string)
- func (ic *ImmichClient) SupportedMedia() filetypes.SupportedMedia
- func (ic *ImmichClient) TagAssets(ctx context.Context, tagID string, assetIDs []string) ([]TagAssetsResponse, error)
- func (ic *ImmichClient) TypeFromExt(ext string) string
- func (ic *ImmichClient) UpdateAsset(ctx context.Context, id string, param UpdAssetField) (*Asset, error)
- func (ic *ImmichClient) UpdateAssets(ctx context.Context, ids []string, isArchived bool, isFavorite bool, ...) error
- func (ic *ImmichClient) UpsertTags(ctx context.Context, tags []string) ([]TagSimplified, error)
- func (ic *ImmichClient) ValidateConnection(ctx context.Context) (User, error)
- type ImmichClientInterface
- type ImmichExifTime
- type ImmichInterface
- type ImmichJobInterface
- type ImmichStackInterface
- type ImmichTagInterface
- type ImmichTime
- type Job
- type JobCommand
- type JobID
- type JobName
- type PingResponse
- type SearchMetadataQuery
- type SendJobCommandResponse
- type ServerErrorMessage
- type ServerStatistics
- type TagAssetsResponse
- type TagSimplified
- type TooManyInternalError
- type UnsupportedMedia
- type UpdAssetField
- type UpdateAlbum
- type UpdateAlbumResult
- type User
- type UserStatistics
Constants ¶
const ( UploadCreated = "created" UploadReplaced = "replaced" UploadDuplicate = "duplicate" )
const ( StatusCreated = "created" StatusReplaced = "replaced" StatusDuplicate = "duplicate" )
const ( EndPointGetJobs = "GetJobs" EndPointSendJobCommand = "SendJobCommand" EndPointCreateJob = "CreateJob" EndPointGetAllAlbums = "GetAllAlbums" EndPointGetAlbumInfo = "GetAlbumInfo" EndPointAddAsstToAlbum = "AddAssetToAlbum" EndPointCreateAlbum = "CreateAlbum" EndPointGetAssetAlbums = "GetAssetAlbums" EndPointDeleteAlbum = "DeleteAlbum" EndPointPingServer = "PingServer" EndPointValidateConnection = "ValidateConnection" EndPointGetServerStatistics = "GetServerStatistics" EndPointGetAssetStatistics = "GetAssetStatistics" EndPointGetSupportedMediaTypes = "GetSupportedMediaTypes" EndPointGetAllAssets = "GetAllAssets" EndPointUpsertTags = "UpsertTags" EndPointTagAssets = "TagAssets" EndPointBulkTagAssets = "BulkTagAssets" EndPointGetAllTags = "GetAllTags" EndPointAssetUpload = "AssetUpload" EndPointAssetReplace = "AssetReplace" EndPointGetAboutInfo = "GetAboutInfo" )
const (
TimeFormat string = "2006-01-02T15:04:05Z"
)
Variables ¶
This section is empty.
Functions ¶
func AlbumsFromAlbumSimplified ¶
func AlbumsFromAlbumSimplified(albums []AlbumSimplified) []assets.Album
func OptionConnectionTimeout ¶
func OptionDryRun ¶
func OptionDryRun(dryRun bool) clientOption
func OptionVerifySSL ¶
func OptionVerifySSL(verify bool) clientOption
Types ¶
type AboutInfo ¶ added in v0.24.3
type AboutInfo struct { Version string `json:"version"` VersionURL string `json:"versionUrl"` Licensed bool `json:"licensed"` Build string `json:"build"` BuildURL string `json:"buildUrl"` BuildImage string `json:"buildImage"` BuildImageURL string `json:"buildImageUrl"` Repository string `json:"repository"` RepositoryURL string `json:"repositoryUrl"` SourceRef string `json:"sourceRef"` SourceCommit string `json:"sourceCommit"` SourceURL string `json:"sourceUrl"` Nodejs string `json:"nodejs"` Exiftool string `json:"exiftool"` Ffmpeg string `json:"ffmpeg"` Libvips string `json:"libvips"` Imagemagick string `json:"imagemagick"` }
getAboutInfo
type AlbumContent ¶
type AlbumSimplified ¶
type AlbumSimplified struct { ID string `json:"id,omitempty"` AlbumName string `json:"albumName"` Description string `json:"description,omitempty"` // OwnerID string `json:"ownerId"` // CreatedAt time.Time `json:"createdAt"` // UpdatedAt time.Time `json:"updatedAt"` // AlbumThumbnailAssetID string `json:"albumThumbnailAssetId"` // SharedUsers []string `json:"sharedUsers"` // Owner User `json:"owner"` // Shared bool `json:"shared"` // AssetCount int `json:"assetCount"` // LastModifiedAssetTimestamp time.Time `json:"lastModifiedAssetTimestamp" AssetIds []string `json:"assetIds,omitempty"` }
type Asset ¶
type Asset struct { ID string `json:"id"` DeviceAssetID string `json:"deviceAssetId"` OwnerID string `json:"ownerId"` DeviceID string `json:"deviceId"` Type string `json:"type"` OriginalPath string `json:"originalPath"` OriginalFileName string `json:"originalFileName"` Resized bool `json:"resized"` Thumbhash string `json:"thumbhash"` FileCreatedAt ImmichTime `json:"fileCreatedAt"` FileModifiedAt ImmichTime `json:"fileModifiedAt"` UpdatedAt ImmichTime `json:"updatedAt"` IsFavorite bool `json:"isFavorite"` IsArchived bool `json:"isArchived"` IsTrashed bool `json:"isTrashed"` Duration string `json:"duration"` Rating int `json:"rating"` ExifInfo ExifInfo `json:"exifInfo"` LivePhotoVideoID string `json:"livePhotoVideoId"` Checksum string `json:"checksum"` StackParentID string `json:"stackParentId"` Albums []AlbumSimplified `json:"-"` // Albums that asset belong to Tags []TagSimplified `json:"tags"` LibraryID string `json:"libraryId,omitempty"` }
immich Asset simplified
type AssetResponse ¶
type AssetSimplified ¶
immich Asset simplified
type ExifInfo ¶
type ExifInfo struct { Make string `json:"make"` Model string `json:"model"` ExifImageWidth int `json:"exifImageWidth"` ExifImageHeight int `json:"exifImageHeight"` FileSizeInByte int64 `json:"fileSizeInByte"` Orientation string `json:"orientation"` DateTimeOriginal ImmichExifTime `json:"dateTimeOriginal,omitempty"` // ModifyDate time.Time `json:"modifyDate"` TimeZone string `json:"timeZone"` // LensModel string `json:"lensModel"` // FNumber float64 `json:"fNumber"` // FocalLength float64 `json:"focalLength"` // Iso int `json:"iso"` // ExposureTime string `json:"exposureTime"` Latitude float64 `json:"latitude,omitempty"` Longitude float64 `json:"longitude,omitempty"` // City string `json:"city"` // State string `json:"state"` // Country string `json:"country"` Description string `json:"description"` }
type GetAssetOptions ¶
type GetAssetOptions struct { UserID string IsFavorite bool IsArchived bool WithoutThumbs bool Skip string }
func (*GetAssetOptions) Values ¶
func (o *GetAssetOptions) Values() url.Values
type ImmichAlbumInterface ¶
type ImmichAlbumInterface interface { GetAllAlbums(ctx context.Context) ([]AlbumSimplified, error) GetAlbumInfo(ctx context.Context, id string, withoutAssets bool) (AlbumContent, error) CreateAlbum( ctx context.Context, tilte string, description string, ids []string, ) (assets.Album, error) // GetAssetAlbums get all albums that an asset belongs to GetAssetAlbums(ctx context.Context, assetID string) ([]AlbumSimplified, error) DeleteAlbum(ctx context.Context, id string) error }
type ImmichAssetInterface ¶
type ImmichAssetInterface interface { GetAssetInfo(ctx context.Context, id string) (*Asset, error) DownloadAsset(ctx context.Context, id string) (io.ReadCloser, error) UpdateAsset(ctx context.Context, id string, param UpdAssetField) (*Asset, error) ReplaceAsset(ctx context.Context, ID string, la *assets.Asset) (AssetResponse, error) GetAllAssets(ctx context.Context) ([]*Asset, error) AddAssetToAlbum(context.Context, string, []string) ([]UpdateAlbumResult, error) UpdateAssets( ctx context.Context, IDs []string, isArchived bool, isFavorite bool, latitude float64, longitude float64, removeParent bool, stackParentID string, ) error GetAllAssetsWithFilter(context.Context, *SearchMetadataQuery, func(*Asset) error) error GetAssetsByHash(ctx context.Context, hash string) ([]*Asset, error) GetAssetsByImageName(ctx context.Context, name string) ([]*Asset, error) AssetUpload(context.Context, *assets.Asset) (AssetResponse, error) DeleteAssets(context.Context, []string, bool) error }
type ImmichClient ¶
type ImmichClient struct { DeviceUUID string // Device Retries int // Number of attempts on 500 errors RetriesDelay time.Duration // Duration between retries // contains filtered or unexported fields }
func NewImmichClient ¶
func NewImmichClient(endPoint string, key string, options ...clientOption) (*ImmichClient, error)
Create a new ImmichClient
func (*ImmichClient) AddAssetToAlbum ¶
func (ic *ImmichClient) AddAssetToAlbum(ctx context.Context, albumID string, assets []string) ([]UpdateAlbumResult, error)
func (*ImmichClient) AssetUpload ¶
func (ic *ImmichClient) AssetUpload(ctx context.Context, la *assets.Asset) (AssetResponse, error)
func (*ImmichClient) BulkTagAssets ¶
func (*ImmichClient) CreateAlbum ¶
func (*ImmichClient) CreateJob ¶
func (ic *ImmichClient) CreateJob(ctx context.Context, name JobName) error
func (*ImmichClient) CreateStack ¶
CreateStack create a stack with the given assets, the 1st asset is the cover, return the stack ID
func (*ImmichClient) DeleteAlbum ¶
func (ic *ImmichClient) DeleteAlbum(ctx context.Context, id string) error
func (*ImmichClient) DeleteAssets ¶
func (*ImmichClient) DownloadAsset ¶
func (ic *ImmichClient) DownloadAsset(ctx context.Context, id string) (io.ReadCloser, error)
func (*ImmichClient) EnableAppTrace ¶
func (ic *ImmichClient) EnableAppTrace(w io.Writer)
func (*ImmichClient) GetAboutInfo ¶ added in v0.24.3
func (ic *ImmichClient) GetAboutInfo(ctx context.Context) (AboutInfo, error)
func (*ImmichClient) GetAlbumInfo ¶
func (ic *ImmichClient) GetAlbumInfo(ctx context.Context, id string, withoutAssets bool) (AlbumContent, error)
func (*ImmichClient) GetAllAlbums ¶
func (ic *ImmichClient) GetAllAlbums(ctx context.Context) ([]AlbumSimplified, error)
func (*ImmichClient) GetAllAssets ¶
func (ic *ImmichClient) GetAllAssets(ctx context.Context) ([]*Asset, error)
func (*ImmichClient) GetAllAssetsWithFilter ¶
func (ic *ImmichClient) GetAllAssetsWithFilter(ctx context.Context, query *SearchMetadataQuery, filter func(*Asset) error) error
func (*ImmichClient) GetAllTags ¶
func (ic *ImmichClient) GetAllTags(ctx context.Context) ([]TagSimplified, error)
func (*ImmichClient) GetAssetAlbums ¶
func (ic *ImmichClient) GetAssetAlbums(ctx context.Context, assetID string) ([]AlbumSimplified, error)
func (*ImmichClient) GetAssetInfo ¶
func (*ImmichClient) GetAssetStatistics ¶
func (ic *ImmichClient) GetAssetStatistics(ctx context.Context) (UserStatistics, error)
func (*ImmichClient) GetAssetsAlbums ¶
func (*ImmichClient) GetAssetsByHash ¶
GetAssetByHash returns the asset with the given hash The hash is the base64 encoded sha1 of the file
func (*ImmichClient) GetAssetsByImageName ¶
GetAssetByHash returns the asset with the given hash The hash is the base64 encoded sha1 of the file
func (*ImmichClient) GetEndPoint ¶
func (ic *ImmichClient) GetEndPoint() string
func (*ImmichClient) GetServerStatistics ¶
func (ic *ImmichClient) GetServerStatistics(ctx context.Context) (ServerStatistics, error)
func (*ImmichClient) GetSupportedMediaTypes ¶
func (ic *ImmichClient) GetSupportedMediaTypes(ctx context.Context) (filetypes.SupportedMedia, error)
func (*ImmichClient) IsExtensionPrefix ¶
func (ic *ImmichClient) IsExtensionPrefix(ext string) bool
func (*ImmichClient) IsIgnoredExt ¶
func (ic *ImmichClient) IsIgnoredExt(ext string) bool
func (*ImmichClient) PingServer ¶
func (ic *ImmichClient) PingServer(ctx context.Context) error
Ping server
func (*ImmichClient) ReplaceAsset ¶
func (ic *ImmichClient) ReplaceAsset(ctx context.Context, ID string, la *assets.Asset) (AssetResponse, error)
func (*ImmichClient) SendJobCommand ¶
func (ic *ImmichClient) SendJobCommand( ctx context.Context, jobID JobID, command JobCommand, force bool, ) (resp SendJobCommandResponse, err error)
func (*ImmichClient) SetDeviceUUID ¶
func (ic *ImmichClient) SetDeviceUUID(deviceUUID string)
func (*ImmichClient) SetEndPoint ¶
func (ic *ImmichClient) SetEndPoint(endPoint string)
func (*ImmichClient) SupportedMedia ¶
func (ic *ImmichClient) SupportedMedia() filetypes.SupportedMedia
func (*ImmichClient) TagAssets ¶
func (ic *ImmichClient) TagAssets( ctx context.Context, tagID string, assetIDs []string, ) ([]TagAssetsResponse, error)
func (*ImmichClient) TypeFromExt ¶
func (ic *ImmichClient) TypeFromExt(ext string) string
func (*ImmichClient) UpdateAsset ¶
func (ic *ImmichClient) UpdateAsset(ctx context.Context, id string, param UpdAssetField) (*Asset, error)
func (*ImmichClient) UpdateAssets ¶
func (*ImmichClient) UpsertTags ¶
func (ic *ImmichClient) UpsertTags(ctx context.Context, tags []string) ([]TagSimplified, error)
func (*ImmichClient) ValidateConnection ¶
func (ic *ImmichClient) ValidateConnection(ctx context.Context) (User, error)
type ImmichClientInterface ¶
type ImmichClientInterface interface { SetEndPoint(string) EnableAppTrace(w io.Writer) SetDeviceUUID(string) PingServer(ctx context.Context) error ValidateConnection(ctx context.Context) (User, error) GetServerStatistics(ctx context.Context) (ServerStatistics, error) GetAssetStatistics(ctx context.Context) (UserStatistics, error) SupportedMedia() filetypes.SupportedMedia GetAboutInfo(ctx context.Context) (AboutInfo, error) }
type ImmichExifTime ¶
func (ImmichExifTime) MarshalJSON ¶
func (t ImmichExifTime) MarshalJSON() ([]byte, error)
func (*ImmichExifTime) UnmarshalJSON ¶
func (t *ImmichExifTime) UnmarshalJSON(b []byte) error
type ImmichInterface ¶
type ImmichInterface interface { ImmichAssetInterface ImmichClientInterface ImmichAlbumInterface ImmichTagInterface ImmichStackInterface ImmichJobInterface }
ImmichInterface is an interface that implements the minimal immich client set of features for uploading interface used to mock up the client
type ImmichJobInterface ¶
type ImmichStackInterface ¶
type ImmichTagInterface ¶
type ImmichTagInterface interface { GetAllTags(ctx context.Context) ([]TagSimplified, error) UpsertTags(ctx context.Context, tags []string) ([]TagSimplified, error) TagAssets( ctx context.Context, tagID string, assetIDs []string, ) ([]TagAssetsResponse, error) BulkTagAssets( ctx context.Context, tagIDs []string, assetIDs []string, ) (struct { Count int `json:"count"` }, error) }
type ImmichTime ¶
func (ImmichTime) MarshalJSON ¶
func (t ImmichTime) MarshalJSON() ([]byte, error)
func (*ImmichTime) UnmarshalJSON ¶
func (t *ImmichTime) UnmarshalJSON(b []byte) error
type Job ¶
type Job struct { JobCounts struct { Active int `json:"active"` Completed int `json:"completed"` Failed int `json:"failed"` Delayed int `json:"delayed"` Waiting int `json:"waiting"` Paused int `json:"paused"` } `json:"jobCounts"` QueueStatus struct { IsActive bool `json:"isActive"` IsPaused bool `json:"isPaused"` } `json:"queueStatus"` }
type JobCommand ¶
type JobCommand string
const ( Start JobCommand = "start" Pause JobCommand = "pause" Resume JobCommand = "resume" Empty JobCommand = "empty" ClearFailed JobCommand = "clear-failed" )
type JobID ¶
type JobID string
const (
StorageTemplateMigration JobID = "storageTemplateMigration"
)
type PingResponse ¶
type PingResponse struct {
Res string `json:"res"`
}
type SearchMetadataQuery ¶
type SearchMetadataQuery struct { // pagination Page int `json:"page"` Size int `json:"size,omitempty"` // filters WithExif bool `json:"withExif,omitempty"` IsVisible bool `json:"isVisible,omitempty"` // For motion stuff you need to pass isVisible=true to hide the motion ones (dijrasm91 — https://discord.com/channels/979116623879368755/1178366369423700080/1201206313699508295) WithDeleted bool `json:"withDeleted,omitempty"` WithArchived bool `json:"withArchived,omitempty"` TakenBefore string `json:"takenBefore,omitempty"` TakenAfter string `json:"takenAfter,omitempty"` Model string `json:"model,omitempty"` Make string `json:"make,omitempty"` Checksum string `json:"checksum,omitempty"` OriginalFileName string `json:"originalFileName,omitempty"` }
type SendJobCommandResponse ¶
type SendJobCommandResponse struct { JobCounts struct { Active int `json:"active"` Completed int `json:"completed"` Delayed int `json:"delayed"` Failed int `json:"failed"` Paused int `json:"paused"` Waiting int `json:"waiting"` } `json:"jobCounts"` QueueStatus struct { IsActive bool `json:"isActive"` IsPause bool `json:"isPause"` } }
type ServerErrorMessage ¶
type ServerStatistics ¶
type ServerStatistics struct { Photos int `json:"photos"` Videos int `json:"videos"` Usage int64 `json:"usage"` UsageByUser []struct { UserID string `json:"userId"` UserName string `json:"userName"` Photos int `json:"photos"` Videos int `json:"videos"` Usage int64 `json:"usage"` QuotaSizeInBytes any `json:"quotaSizeInBytes"` } `json:"usageByUser"` }
type TagAssetsResponse ¶
type TagSimplified ¶
type TagSimplified struct { ID string `json:"id"` Name string `json:"name"` Value string `json:"value"` }
func (TagSimplified) AsTag ¶
func (ts TagSimplified) AsTag() assets.Tag
type TooManyInternalError ¶
type TooManyInternalError struct {
// contains filtered or unexported fields
}
func (TooManyInternalError) Is ¶
func (e TooManyInternalError) Is(target error) bool
type UnsupportedMedia ¶
type UnsupportedMedia struct {
// contains filtered or unexported fields
}
func (UnsupportedMedia) Error ¶
func (u UnsupportedMedia) Error() string
func (UnsupportedMedia) Is ¶
func (u UnsupportedMedia) Is(target error) bool
type UpdAssetField ¶
type UpdAssetField struct { IsArchived bool `json:"isArchived,omitempty"` IsFavorite bool `json:"isFavorite,omitempty"` Latitude float64 `json:"latitude,omitempty"` Longitude float64 `json:"longitude,omitempty"` Description string `json:"description,omitempty"` Rating int `json:"rating,omitempty"` DateTimeOriginal time.Time `json:"dateTimeOriginal,omitempty"` }
UpdAssetField is used to update asset with fields given in the struct fields
func (UpdAssetField) MarshalJSON ¶ added in v0.25.2
func (u UpdAssetField) MarshalJSON() ([]byte, error)
MarshalJSON customizes the JSON marshaling for the UpdAssetField struct. If either Latitude or Longitude is non-zero, it includes them in the JSON output. Otherwise, it omits them by using the alias type.
type UpdateAlbum ¶
type UpdateAlbum struct {
IDS []string `json:"ids"`
}
type UpdateAlbumResult ¶
type User ¶
type User struct { ID string `json:"id"` Email string `json:"email"` FirstName string `json:"firstName"` LastName string `json:"lastName"` StorageLabel string `json:"storageLabel"` ExternalPath string `json:"externalPath"` ProfileImagePath string `json:"profileImagePath"` ShouldChangePassword bool `json:"shouldChangePassword"` IsAdmin bool `json:"isAdmin"` CreatedAt time.Time `json:"createdAt"` DeletedAt time.Time `json:"deletedAt"` UpdatedAt time.Time `json:"updatedAt"` OauthID string `json:"oauthId"` }