feat: workflow action to add tags to assets

This commit is contained in:
Ben Beckford
2026-06-29 07:14:06 -07:00
parent 6b5e91ba5b
commit 4f52891095
4 changed files with 46 additions and 0 deletions
+22
View File
@@ -203,6 +203,28 @@
},
"uiHints": ["Filter"]
},
{
"name": "assetAddTags",
"title": "Add Tags",
"description": "Add tags to an asset",
"types": ["AssetV1"],
"hostFunctions": true,
"schema": {
"type": "object",
"properties": {
"tags": {
"title": "Tags",
"description": "Tags to add to the asset",
"type": "string",
"array": true,
"uiHint": {
"type": "TagId"
}
}
},
"required": ["tags"]
}
},
{
"name": "assetTagFilter",
"title": "Filter by tags",
+7
View File
@@ -3,6 +3,11 @@ import { AssetVisibility } from '@immich/sdk';
import type { Manifest } from '../dist/index.d.ts';
const methods = wrapper<Manifest>({
assetAddTags: ({ config, data, functions }) => {
functions.bulkTagAssets({ assetIds: [data.asset.id], tagIds: config.tags });
return {};
},
assetAddToAlbums: ({ config, data, functions }) => {
const assetId = data.asset.id;
@@ -188,6 +193,7 @@ const methods = wrapper<Manifest>({
});
const {
assetAddTags,
assetAddToAlbums,
assetArchive,
assetFavorite,
@@ -205,6 +211,7 @@ const {
} = methods;
export {
assetAddTags,
assetAddToAlbums,
assetArchive,
assetFavorite,
@@ -4,6 +4,8 @@ import {
type BulkIdResponseDto,
type BulkIdsDto,
type CreateAlbumDto,
type TagBulkAssetsDto,
type TagBulkAssetsResponseDto,
} from '@immich/sdk';
declare module 'extism:host' {
@@ -47,6 +49,7 @@ export const availableFunctions = [
'addAssetsToAlbum',
'addAssetsToAlbums',
'httpRequest',
'bulkTagAssets',
] as const;
export const hostFunctions = (authToken: string) => {
@@ -96,5 +99,11 @@ export const hostFunctions = (authToken: string) => {
authToken,
[url, options],
),
bulkTagAssets: (dto: TagBulkAssetsDto) =>
call<[TagBulkAssetsDto], TagBulkAssetsResponseDto>(
'bulkTagAssets',
authToken,
[dto],
),
} satisfies Record<(typeof availableFunctions)[number], unknown>;
};
@@ -13,6 +13,7 @@ import { AlbumsAddAssetsDto, CreateAlbumDto, GetAlbumsDto } from 'src/dtos/album
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { PluginManifestDto } from 'src/dtos/plugin-manifest.dto';
import { TagBulkAssetsDto } from 'src/dtos/tag.dto';
import {
BootstrapEventPriority,
DatabaseLock,
@@ -27,6 +28,7 @@ import { ArgOf } from 'src/repositories/event.repository';
import { AlbumService } from 'src/services/album.service';
import { AssetService } from 'src/services/asset.service';
import { BaseService } from 'src/services/base.service';
import { TagService } from 'src/services/tag.service';
import { JobOf } from 'src/types';
const dummy = () => {
@@ -69,6 +71,7 @@ export class WorkflowExecutionService extends BaseService {
this.jwtSecret = this.cryptoRepository.randomBytesAsText(32);
const albumService = BaseService.create(AlbumService, this);
const tagService = BaseService.create(TagService, this);
const searchAlbums = this.wrap<[dto: GetAlbumsDto]>((authDto, ctx, args) => albumService.getAll(authDto, ...args));
const createAlbum = this.wrap<[dto: CreateAlbumDto]>((authDto, ctx, args) => albumService.create(authDto, ...args));
@@ -105,6 +108,9 @@ export class WorkflowExecutionService extends BaseService {
throw new Error('Hostname did not match any listed in methods[].allowedHosts in the plugin manifest');
});
const bulkTagAssets = this.wrap<[dto: TagBulkAssetsDto]>((authDto, ctx, args) =>
tagService.bulkTagAssets(authDto, ...args),
);
const functions = {
searchAlbums,
@@ -112,6 +118,7 @@ export class WorkflowExecutionService extends BaseService {
addAssetsToAlbum,
addAssetsToAlbums,
httpRequest,
bulkTagAssets,
};
const stubs: typeof functions = {
@@ -120,6 +127,7 @@ export class WorkflowExecutionService extends BaseService {
addAssetsToAlbum: dummy,
addAssetsToAlbums: dummy,
httpRequest: dummy,
bulkTagAssets: dummy,
};
const plugins = await this.pluginRepository.getForLoad();