diff --git a/packages/backend/src/apps/flickr/data.ts b/packages/backend/src/apps/flickr/data.ts new file mode 100644 index 00000000..c9fad235 --- /dev/null +++ b/packages/backend/src/apps/flickr/data.ts @@ -0,0 +1,10 @@ +import { IJSONObject } from '@automatisch/types'; +import ListAlbums from './data/list-albums'; + +export default class Data { + listAlbums: ListAlbums; + + constructor(connectionData: IJSONObject) { + this.listAlbums = new ListAlbums(connectionData); + } +} diff --git a/packages/backend/src/apps/flickr/data/list-albums.ts b/packages/backend/src/apps/flickr/data/list-albums.ts new file mode 100644 index 00000000..83714ff6 --- /dev/null +++ b/packages/backend/src/apps/flickr/data/list-albums.ts @@ -0,0 +1,39 @@ +import FlickrApi from 'flickr-sdk'; +import type { IJSONObject } from '@automatisch/types'; + +export default class ListAlbums { + client?: typeof FlickrApi; + + constructor(connectionData: IJSONObject) { + if ( + connectionData.consumerKey && + connectionData.consumerSecret && + connectionData.accessToken && + connectionData.accessSecret + ) { + this.client = new FlickrApi( + FlickrApi.OAuth.createPlugin( + connectionData.consumerKey, + connectionData.consumerSecret, + connectionData.accessToken, + connectionData.accessSecret + ) + ); + } + } + + async run() { + const { photosets } = (await this.client.photosets.getList()).body; + const allPhotosets = [...photosets.photoset]; + + for (let page = photosets.page + 1; page <= photosets.pages; page++) { + const { photosets } = (await this.client.photosets.getList({ page, })).body; + allPhotosets.push(...photosets.photoset); + } + + return allPhotosets.map((photoset) => ({ + value: photoset.id, + name: photoset.title._content, + })); + } +} diff --git a/packages/backend/src/apps/flickr/index.ts b/packages/backend/src/apps/flickr/index.ts index 4591842a..5a5ca222 100644 --- a/packages/backend/src/apps/flickr/index.ts +++ b/packages/backend/src/apps/flickr/index.ts @@ -6,10 +6,12 @@ import { } from '@automatisch/types'; import Authentication from './authentication'; import Triggers from './triggers'; +import Data from './data'; export default class Flickr implements IService { authenticationClient: IAuthentication; triggers: Triggers; + data: Data; constructor( appData: IApp, @@ -17,6 +19,7 @@ export default class Flickr implements IService { parameters: IJSONObject ) { this.authenticationClient = new Authentication(appData, connectionData); + this.data = new Data(connectionData); this.triggers = new Triggers(connectionData, parameters); } } diff --git a/packages/backend/src/apps/flickr/info.json b/packages/backend/src/apps/flickr/info.json index aeb1dab5..195ca2f7 100644 --- a/packages/backend/src/apps/flickr/info.json +++ b/packages/backend/src/apps/flickr/info.json @@ -218,9 +218,9 @@ "triggers": [ { "name": "New favorite photo", - "key": "favoritePhoto", + "key": "newFavoritePhoto", "interval": "15m", - "description": "Will be triggered when you favorite a photo.", + "description": "Triggers when you favorite a photo.", "substeps": [ { "key": "chooseAccount", @@ -231,6 +231,45 @@ "name": "Test trigger" } ] + }, + { + "name": "New photo in album", + "key": "newPhotoInAlbum", + "interval": "15m", + "description": "Triggers when you add a new photo in an album.", + "substeps": [ + { + "key": "chooseAccount", + "name": "Choose account" + }, + { + "key": "chooseTrigger", + "name": "Set up a trigger", + "arguments": [ + { + "label": "Album", + "key": "album", + "type": "dropdown", + "required": true, + "variables": false, + "source": { + "type": "query", + "name": "getData", + "arguments": [ + { + "name": "key", + "value": "listAlbums" + } + ] + } + } + ] + }, + { + "key": "testStep", + "name": "Test trigger" + } + ] } ] } diff --git a/packages/backend/src/apps/flickr/triggers.ts b/packages/backend/src/apps/flickr/triggers.ts index 27d4e0a1..d73f90f4 100644 --- a/packages/backend/src/apps/flickr/triggers.ts +++ b/packages/backend/src/apps/flickr/triggers.ts @@ -1,10 +1,13 @@ import { IJSONObject } from '@automatisch/types'; import FavoritePhoto from './triggers/favorite-photo'; +import NewPhotoInAlbum from './triggers/new-photo-in-album'; export default class Triggers { favoritePhoto: FavoritePhoto; + newPhotoInAlbum: NewPhotoInAlbum; constructor(connectionData: IJSONObject, parameters: IJSONObject) { this.favoritePhoto = new FavoritePhoto(connectionData); + this.newPhotoInAlbum = new NewPhotoInAlbum(connectionData, parameters); } } diff --git a/packages/backend/src/apps/flickr/triggers/favorite-photo.ts b/packages/backend/src/apps/flickr/triggers/favorite-photo.ts index f6ebaea3..de362f71 100644 --- a/packages/backend/src/apps/flickr/triggers/favorite-photo.ts +++ b/packages/backend/src/apps/flickr/triggers/favorite-photo.ts @@ -24,7 +24,7 @@ export default class FavoritePhoto { } async run(startTime: Date) { - const { photos } = (await this.client.favorites.getList({ per_page: 1, })).body; + const { photos } = (await this.client.favorites.getList()).body; const favPhotos = [...photos.photo]; const newFavPhotos = []; @@ -45,7 +45,7 @@ export default class FavoritePhoto { if (isLastItem && page < photos.pages) { page = page + 1; - const { photos } = (await this.client.favorites.getList({ page, per_page: 1, })).body; + const { photos } = (await this.client.favorites.getList({ page, })).body; favPhotos.push(...photos.photo); } } diff --git a/packages/backend/src/apps/flickr/triggers/new-photo-in-album.ts b/packages/backend/src/apps/flickr/triggers/new-photo-in-album.ts new file mode 100644 index 00000000..3454777d --- /dev/null +++ b/packages/backend/src/apps/flickr/triggers/new-photo-in-album.ts @@ -0,0 +1,81 @@ +import { DateTime } from 'luxon'; +import FlickrApi from 'flickr-sdk'; +import { IJSONObject } from '@automatisch/types'; + +export default class NewPhotoInAlbum { + client?: typeof FlickrApi; + connectionData?: IJSONObject; + albumId?: string; + extraFields = [ + 'license', + 'date_upload', + 'date_taken', + 'owner_name', + 'icon_server', + 'original_format', + 'last_update', + 'geo', + 'tags', + 'machine_tags', + 'o_dims', + 'views', + 'media', + 'path_alias', + 'url_sq', + 'url_t', + 'url_s', + 'url_m', + 'url_o' + ].join(','); + + constructor(connectionData: IJSONObject, parameters: IJSONObject) { + if ( + connectionData.consumerKey && + connectionData.consumerSecret && + connectionData.accessToken && + connectionData.accessSecret + ) { + this.client = new FlickrApi( + FlickrApi.OAuth.createPlugin( + connectionData.consumerKey, + connectionData.consumerSecret, + connectionData.accessToken, + connectionData.accessSecret + ) + ); + + this.connectionData = connectionData; + } + + if (parameters?.album) { + this.albumId = parameters.album as string; + } + } + + async getAlbumPhotos(options: { perPage?: number, page?: number } = {}) { + const { perPage, page } = options; + const payload = { + page, + per_page: perPage, + photoset_id: this.albumId, + user_id: this.connectionData.userId, + extras: this.extraFields, + }; + const { photoset } = (await this.client.photosets.getPhotos(payload)).body; + + return photoset; + } + + async run() { + // TODO: implement pagination on undated entries + const { photo } = await this.getAlbumPhotos({ page: 1 }); + + return photo; + } + + async testRun() { + const { photo } = await this.getAlbumPhotos({ perPage: 1 }); + + return photo; + } +} diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 8d6a5fbf..364bd233 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -367,7 +367,21 @@ type TriggerSubstepArgument { label: String key: String type: String + description: String required: Boolean + variables: Boolean + source: TriggerSubstepArgumentSource +} + +type TriggerSubstepArgumentSource { + type: String + name: String + arguments: [TriggerSubstepArgumentSourceArgument] +} + +type TriggerSubstepArgumentSourceArgument { + name: String + value: String } type User { diff --git a/packages/backend/src/models/step.ts b/packages/backend/src/models/step.ts index 09544669..9590126e 100644 --- a/packages/backend/src/models/step.ts +++ b/packages/backend/src/models/step.ts @@ -13,7 +13,7 @@ class Step extends Base { connectionId?: string; status = 'incomplete'; position!: number; - parameters: Record = {}; + parameters: Record; connection?: Connection; flow: Flow; executionSteps?: [ExecutionStep]; diff --git a/packages/web/src/graphql/queries/get-apps.ts b/packages/web/src/graphql/queries/get-apps.ts index 77592c99..7e9758ef 100644 --- a/packages/web/src/graphql/queries/get-apps.ts +++ b/packages/web/src/graphql/queries/get-apps.ts @@ -61,6 +61,16 @@ export const GET_APPS = gql` key type required + description + variables + source { + type + name + arguments { + name + value + } + } } } }