Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-pinterest
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-pinterest` to build the library.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@activepieces/piece-pinterest",
|
||||
"version": "0.0.2"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-pinterest",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/pinterest/src",
|
||||
"projectType": "library",
|
||||
"release": {
|
||||
"version": {
|
||||
"currentVersionResolver": "git-tag",
|
||||
"preserveLocalDependencyProtocols": false,
|
||||
"manifestRootsToUpdate": [
|
||||
"dist/{projectRoot}"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/pinterest",
|
||||
"tsConfig": "packages/pieces/community/pinterest/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/pinterest/package.json",
|
||||
"main": "packages/pieces/community/pinterest/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/pinterest/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/pinterest/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/{projectRoot}"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/pinterest",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Verbinden Sie Ihr Pinterest Business Konto",
|
||||
"Create Pin": "Pin erstellen",
|
||||
"Create Board": "Board erstellen",
|
||||
"Delete Pin": "Pin löschen",
|
||||
"Find Board by Name": "Brett nach Namen suchen",
|
||||
"Find Pin by Title/Keyword": "Pin nach Titel/Stichwort finden",
|
||||
"Update Board": "Board aktualisieren",
|
||||
"Upload an image or video to create a new Pin on a board.": "Ein Bild oder Video hochladen, um einen neuen Pin auf einem Board zu erstellen.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Erstellen Sie ein neues Pinterest Board für die Organisation von Pins.",
|
||||
"Permanently delete a specific Pin.": "Einen bestimmten Pin dauerhaft löschen.",
|
||||
"Search for boards by name using Pinterest's search API.": "Suchen Sie nach Boards mit der Suche API von Pinterest nach Namen.",
|
||||
"Search for Pins using title, description, or keywords.": "Suche nach Pins mit Titel, Beschreibung oder Schlüsselwörtern.",
|
||||
"Update a board's name, description, or privacy settings.": "Name, Beschreibung oder Privatsphäre-Einstellungen eines Boards aktualisieren.",
|
||||
"Ad account Id": "Anzeigen-Konto-Id",
|
||||
"Board Id": "Board-Id",
|
||||
"Board Section Id": "Board-Sektion-Id",
|
||||
"Title": "Titel",
|
||||
"Description": "Beschreibung",
|
||||
"Media Source Type": "Medienquellentyp",
|
||||
"Media URL": "Medien-URL",
|
||||
"Destination Link": "Ziellink",
|
||||
"Dominant Color": "Dominante Farbe",
|
||||
"Alt Text": "Alt Text",
|
||||
"Parent Pin ID": "Übergeordnete Pin-ID",
|
||||
"Sponsor ID": "Sponsor ID",
|
||||
"Product Tags": "Produkt-Tags",
|
||||
"Note": "Notiz",
|
||||
"Is Removable": "Ist abnehmbar",
|
||||
"Board Name": "Boardname",
|
||||
"Privacy": "Privatsphäre",
|
||||
"Ads Only Board": "Nur Werbung Board",
|
||||
"pin Id": "pin Id",
|
||||
"Search Query": "Suchanfrage",
|
||||
"Bookmark": "Lesezeichen",
|
||||
"Pagination Bookmark": "Seiten-Lesezeichen",
|
||||
"Maximum Results": "Maximale Ergebnisse",
|
||||
"The title of the Pin (max 100 characters).": "Der Titel des Pin (max. 100 Zeichen).",
|
||||
"The description of the Pin (max 800 characters).": "Die Beschreibung des Pin (max. 800 Zeichen).",
|
||||
"The type of media source for the Pin.": "Der Typ der Medienquelle für den Pin.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "Die URL des Bildes oder Videos zum Hochladen. Muss eine gültige URL sein.",
|
||||
"The destination URL that the Pin will link to when clicked.": "Die Ziel-URL, auf die der Pin verlinkt, wenn angeklickt.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "Die dominante Farbe des Pins als Hex-Farbcode (z.B. \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Alternativer Text für Barrierefreiheit und Screenreader (max. 500 Zeichen).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "Die ID des ursprünglichen Pins wenn es sich um einen gespeicherten/reparierten Pin handelt.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "Die Sponsor Konto-ID für kostenpflichtige Partnerschaften. Verfügbar nur um Benutzer in der geschlossenen Beta auszuwählen.",
|
||||
"Select one or more options": "Wählen Sie eine oder mehrere Optionen",
|
||||
"A private note for this Pin that only you can see.": "Eine private Notiz für diesen Pin, die nur Sie sehen können.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Auf true setzen um einen ad-only Pin zu erstellen, der leicht entfernt werden kann.",
|
||||
"The name of the board (max 180 characters).": "Der Name des Boards (max. 180 Zeichen).",
|
||||
"Optional description for your board.": "Optionale Beschreibung für Ihr Board.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Board-Privatsphäre-Einstellung (automatisch auf \"PROTECTED\" für Nur-Werbung-Boards gesetzt).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Erstellen Sie ein Werbe-Board, das nur Werbe-Pins speichern kann. Hinweis: Der Board-Name wird zu \"Werbe-Nur-Pins\" und die Privatsphäre wird auf \"PROTECTED\" gesetzt.",
|
||||
"The search term to find boards (required).": "Der Suchbegriff zu finden Boards (erforderlich).",
|
||||
"Pagination bookmark from previous response.": "Lesezeichen für Paginierung von vorheriger Antwort.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Suchbegriffe für Pin-Titel, Beschreibungen oder Tags. Sie können auch mit Komma-getrennten Pin-IDs suchen.",
|
||||
"Bookmark token from previous search results for pagination.": "Lesezeichen-Token von vorherigen Suchergebnissen für die Seiteninierung.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Maximale Anzahl an Pins die zurückgegeben werden (nützlich für große Ergebnisse).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "Der neue Name des Boards (max. 180 Zeichen). Leer lassen, um den aktuellen Namen zu behalten.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "Die neue Beschreibung des Boards (max. 500 Zeichen). Leer lassen, um die aktuelle Beschreibung zu behalten.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Datenschutzeinstellungen des Boards aktualisieren. Leer lassen, um die aktuelle Einstellung zu behalten.",
|
||||
"Image URL": "Bild-URL",
|
||||
"Base64 Image": "Base64-Bild",
|
||||
"Video URL": "Video-URL",
|
||||
"Public": "Öffentlich",
|
||||
"Protected": "Geschützt",
|
||||
"Secret": "Geheimnis",
|
||||
"New Board": "Neues Board",
|
||||
"New Follower": "Neuer Follower",
|
||||
"New Pin on Board": "Neuer Pin auf dem Board",
|
||||
"Fires when a new board is created in the account.": "Feuert ab, wenn ein neues Board im Konto erstellt wird.",
|
||||
"Triggers when a user gains a new follower.": "Wird ausgelöst, wenn ein Benutzer einen neuen Follower erhält.",
|
||||
"Fires when a new Pin is added to a specific board.": "Feuert ab, wenn ein neuer Pin einem bestimmten Board hinzugefügt wird.",
|
||||
"Board Privacy Filter": "Datenschutz-Filter",
|
||||
"Page Size": "Einträge pro Seite",
|
||||
"Pin Types to Watch": "Zu beobachtende Typen anheften",
|
||||
"Filter boards by privacy setting (optional).": "Foren nach Datenschutzeinstellungen filtern (optional).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Anzahl der Boards pro Seite (1-250, Standard: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Nach bestimmten Pin-Typen filtern. Leer lassen, um alle Typen zu beobachten.",
|
||||
"All Boards": "Alle Boards",
|
||||
"Public Only": "Nur öffentlich",
|
||||
"Protected Only": "Nur Geschützt",
|
||||
"Secret Only": "Nur Geheimnis",
|
||||
"Public and Secret": "Öffentliche und geheime",
|
||||
"Regular Pins": "Normale Pins",
|
||||
"Video Pins": "Video-Pins",
|
||||
"Shopping Pins": "Einkaufsstifte",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Ideenstifte"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Conecte su cuenta de Pinterest Business",
|
||||
"Create Pin": "Crear pin",
|
||||
"Create Board": "Crear tablero",
|
||||
"Delete Pin": "Eliminar pin",
|
||||
"Find Board by Name": "Buscar foro por nombre",
|
||||
"Find Pin by Title/Keyword": "Buscar alfileres por título/palabra clave",
|
||||
"Update Board": "Actualizar Tablero",
|
||||
"Upload an image or video to create a new Pin on a board.": "Sube una imagen o vídeo para crear un nuevo Pin en un foro.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Crear un nuevo tablero de Pinterest para organizar Pins.",
|
||||
"Permanently delete a specific Pin.": "Elimina permanentemente un pin específico.",
|
||||
"Search for boards by name using Pinterest's search API.": "Buscar tableros por nombre usando la API de búsqueda de Pinterest.",
|
||||
"Search for Pins using title, description, or keywords.": "Buscar Pines usando título, descripción o palabras clave.",
|
||||
"Update a board's name, description, or privacy settings.": "Actualizar el nombre, la descripción o la configuración de privacidad de un tablero.",
|
||||
"Ad account Id": "Id de cuenta de anuncio",
|
||||
"Board Id": "Tablero Id",
|
||||
"Board Section Id": "Id de la sección del foro",
|
||||
"Title": "Título",
|
||||
"Description": "Descripción",
|
||||
"Media Source Type": "Tipo de fuente Multimedia",
|
||||
"Media URL": "URL de medios",
|
||||
"Destination Link": "Enlace de destino",
|
||||
"Dominant Color": "Color dominante",
|
||||
"Alt Text": "Texto Alt",
|
||||
"Parent Pin ID": "Pin ID padre",
|
||||
"Sponsor ID": "ID del patrocinador",
|
||||
"Product Tags": "Etiquetas de producto",
|
||||
"Note": "Nota",
|
||||
"Is Removable": "Es eliminable",
|
||||
"Board Name": "Nombre del foro",
|
||||
"Privacy": "Privacidad",
|
||||
"Ads Only Board": "Solo tablero de anuncios",
|
||||
"pin Id": "pin Id",
|
||||
"Search Query": "Buscar consulta",
|
||||
"Bookmark": "Marcador",
|
||||
"Pagination Bookmark": "Marcador de paginación",
|
||||
"Maximum Results": "Resultados máximos",
|
||||
"The title of the Pin (max 100 characters).": "El título del Pin (máximo 100 caracteres).",
|
||||
"The description of the Pin (max 800 characters).": "La descripción del Pin (máximo 800 caracteres).",
|
||||
"The type of media source for the Pin.": "El tipo de fuente de medios para el Pin.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "La URL de la imagen o vídeo a cargar. Debe ser una URL válida.",
|
||||
"The destination URL that the Pin will link to when clicked.": "La URL de destino a la que el Pin enlazará cuando se haga clic.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "El color dominante del Pin como código hexadecimal de color (por ejemplo, \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Texto alternativo para accesibilidad y lectores de pantalla (máximo 500 caracteres).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "El ID del Pin original si es un Pin guardado/repinnado.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "El ID de la cuenta de patrocinador para el contenido de la asociación pagada. Disponible sólo para seleccionar usuarios en beta cerrada.",
|
||||
"Select one or more options": "Seleccione una o más opciones",
|
||||
"A private note for this Pin that only you can see.": "Una nota privada para este Pin que sólo usted puede ver.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Establecer en true para crear un pin de sólo anuncios que se puede eliminar fácilmente.",
|
||||
"The name of the board (max 180 characters).": "El nombre del tablero (máximo 180 caracteres).",
|
||||
"Optional description for your board.": "Descripción opcional para tu foro.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Configuración de privacidad del foro (auto-set a \"PROTECTED\" para tableros de sólo anuncios).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Crear un tablero de sólo publicidad que sólo puede almacenar alfileres promocionales. Nota: El nombre del tablero se convertirá en \"Pines de sólo anuncios\" y la privacidad se establecerá en \"PROTECTED\".",
|
||||
"The search term to find boards (required).": "El término de búsqueda para encontrar foros (requerido).",
|
||||
"Pagination bookmark from previous response.": "Marcador de paginación de la respuesta anterior.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Buscar términos para títulos de pin, descripciones o etiquetas. También puede buscar usando IDs de pines separados por comas.",
|
||||
"Bookmark token from previous search results for pagination.": "Ficha de marcadores de resultados de búsqueda anteriores para la paginación.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Número máximo de pines a devolver (útil para conjuntos de resultados grandes).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "El nuevo nombre del tablero (máximo 180 caracteres). Dejar en blanco para mantener el nombre actual.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "La nueva descripción del tablero (máximo 500 caracteres). Dejar en blanco para mantener la descripción actual.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Actualizar configuración de privacidad del foro. Dejar vacío para mantener la configuración actual.",
|
||||
"Image URL": "URL de imagen",
|
||||
"Base64 Image": "Imagen Base64",
|
||||
"Video URL": "URL del vídeo",
|
||||
"Public": "Público",
|
||||
"Protected": "Protegido",
|
||||
"Secret": "Secreto",
|
||||
"New Board": "Nuevo foro",
|
||||
"New Follower": "Nuevo Seguidor",
|
||||
"New Pin on Board": "Nuevo Pin en Tablero",
|
||||
"Fires when a new board is created in the account.": "Dispara cuando se crea un nuevo tablero en la cuenta.",
|
||||
"Triggers when a user gains a new follower.": "Dispara cuando un usuario obtiene un nuevo seguidor.",
|
||||
"Fires when a new Pin is added to a specific board.": "Dispara cuando se añade un nuevo Pin a un tablero específico.",
|
||||
"Board Privacy Filter": "Filtro de privacidad del foro",
|
||||
"Page Size": "Tamaño de página",
|
||||
"Pin Types to Watch": "Anclar tipos a ver",
|
||||
"Filter boards by privacy setting (optional).": "Filtrar tableros por configuración de privacidad (opcional).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Número de tableros a buscar por página (1-250, por defecto: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Filtrar por tipos de pin específicos. Dejar en blanco para ver todos los tipos.",
|
||||
"All Boards": "Todos los tableros",
|
||||
"Public Only": "Sólo público",
|
||||
"Protected Only": "Sólo Protegidos",
|
||||
"Secret Only": "Sólo secretos",
|
||||
"Public and Secret": "Público y secreto",
|
||||
"Regular Pins": "Alfileres regulares",
|
||||
"Video Pins": "Pines de vídeo",
|
||||
"Shopping Pins": "Pins de compras",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Alfileres de idea"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Connectez votre compte Pinterest Business",
|
||||
"Create Pin": "Créer une broche",
|
||||
"Create Board": "Créer un tableau",
|
||||
"Delete Pin": "Supprimer la broche",
|
||||
"Find Board by Name": "Trouver un tableau par nom",
|
||||
"Find Pin by Title/Keyword": "Trouver l'épingle par titre/Mot-clé",
|
||||
"Update Board": "Mettre à jour le tableau",
|
||||
"Upload an image or video to create a new Pin on a board.": "Téléchargez une image ou une vidéo pour créer une nouvelle broche sur un tableau.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Créer un nouveau tableau Pinterest pour organiser les Pins.",
|
||||
"Permanently delete a specific Pin.": "Supprimer définitivement une épingle spécifique.",
|
||||
"Search for boards by name using Pinterest's search API.": "Rechercher des tableaux par nom en utilisant l'API de recherche de Pinterest.",
|
||||
"Search for Pins using title, description, or keywords.": "Rechercher des épingles en utilisant le titre, la description ou les mots-clés.",
|
||||
"Update a board's name, description, or privacy settings.": "Mettre à jour le nom, la description ou les paramètres de confidentialité d'un tableau.",
|
||||
"Ad account Id": "Id du compte publicitaire",
|
||||
"Board Id": "Identifiant du tableau",
|
||||
"Board Section Id": "ID de la section du tableau",
|
||||
"Title": "Titre de la feuille de calcul",
|
||||
"Description": "Libellé",
|
||||
"Media Source Type": "Type de Media Source",
|
||||
"Media URL": "URL du média",
|
||||
"Destination Link": "Lien de destination",
|
||||
"Dominant Color": "Couleur dominante",
|
||||
"Alt Text": "Texte Alt",
|
||||
"Parent Pin ID": "ID de Pin parent",
|
||||
"Sponsor ID": "ID du sponsor",
|
||||
"Product Tags": "Balises de produit",
|
||||
"Note": "Note",
|
||||
"Is Removable": "Est amovible",
|
||||
"Board Name": "Nom du tableau",
|
||||
"Privacy": "Confidentialité",
|
||||
"Ads Only Board": "Annonces uniquement sur le tableau",
|
||||
"pin Id": "ID de la broche",
|
||||
"Search Query": "Requête de recherche",
|
||||
"Bookmark": "Marque-page",
|
||||
"Pagination Bookmark": "Marque-page de pagination",
|
||||
"Maximum Results": "Nombre maximum de résultats",
|
||||
"The title of the Pin (max 100 characters).": "Le titre de la broche (max 100 caractères).",
|
||||
"The description of the Pin (max 800 characters).": "La description de la broche (max 800 caractères).",
|
||||
"The type of media source for the Pin.": "Le type de source de média pour l'épingle.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "L'URL de l'image ou de la vidéo à télécharger. Doit être une URL valide.",
|
||||
"The destination URL that the Pin will link to when clicked.": "L'URL de destination vers laquelle l'épingle sera lorsqu'elle sera cliquée.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "La couleur dominante de la broche en tant que code couleur hexadécimal (par exemple, \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Texte alternatif pour l'accessibilité et les lecteurs d'écran (max 500 caractères).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "L'ID de la broche originale si c'est une broche enregistrée/repérée.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "L'ID du compte du sponsor pour le contenu du partenariat payant. Disponible uniquement pour sélectionner les utilisateurs en bêta fermée.",
|
||||
"Select one or more options": "Sélectionnez une ou plusieurs options",
|
||||
"A private note for this Pin that only you can see.": "Une note privée pour cette broche que vous seul pouvez voir.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Réglez sur vrai pour créer une épingle publicitaire qui peut être facilement supprimée.",
|
||||
"The name of the board (max 180 characters).": "Le nom du tableau (max 180 caractères).",
|
||||
"Optional description for your board.": "Description facultative pour votre tableau.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Réglage de la confidentialité de la carte (auto-réglé sur \"PROTECTED\" pour les cartes ad-only).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Créer un tableau réservé aux publicités qui ne peut stocker que les épingles promotionnelles. Remarque : Le nom du tableau deviendra des épingles publicitaires uniquement et la confidentialité sera réglée sur \"PROTECTED\".",
|
||||
"The search term to find boards (required).": "Le terme de recherche pour trouver des tableaux (obligatoire).",
|
||||
"Pagination bookmark from previous response.": "Signet de pagination de la réponse précédente.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Rechercher des termes pour les titres, les descriptions ou les étiquettes. Vous pouvez également effectuer une recherche en utilisant des identifiants d'épingles séparés par des virgules.",
|
||||
"Bookmark token from previous search results for pagination.": "Marquer le jeton des résultats de recherche précédents pour la pagination.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Nombre maximum de pins à retourner (utile pour les grands jeux de résultats).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "Le nouveau nom du tableau (max 180 caractères). Laisser vide pour conserver le nom courant.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "La nouvelle description du tableau (max 500 caractères). Laisser vide pour conserver la description actuelle.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Mettre à jour le paramètre de confidentialité du forum. Laisser vide pour conserver le paramètre actuel.",
|
||||
"Image URL": "URL de l'image",
|
||||
"Base64 Image": "Image Base64",
|
||||
"Video URL": "URL de la vidéo",
|
||||
"Public": "Publique",
|
||||
"Protected": "Protégé",
|
||||
"Secret": "Secrète",
|
||||
"New Board": "Nouveau tableau",
|
||||
"New Follower": "Nouvel abonné",
|
||||
"New Pin on Board": "Nouvelle broche sur la carte",
|
||||
"Fires when a new board is created in the account.": "Tire quand un nouveau tableau est créé dans le compte.",
|
||||
"Triggers when a user gains a new follower.": "Déclenche lorsqu'un utilisateur gagne un nouvel abonné.",
|
||||
"Fires when a new Pin is added to a specific board.": "Tire quand une nouvelle broche est ajoutée à une carte spécifique.",
|
||||
"Board Privacy Filter": "Filtre de confidentialité du tableau",
|
||||
"Page Size": "Nombre d'élément",
|
||||
"Pin Types to Watch": "Épingler les types à surveiller",
|
||||
"Filter boards by privacy setting (optional).": "Filtrer les tableaux par paramètre de confidentialité (facultatif).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Nombre de tableaux à récupérer par page (1-250, par défaut: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Filtrer par types d'épingles spécifiques. Laisser vide pour regarder tous les types.",
|
||||
"All Boards": "Toutes les planches",
|
||||
"Public Only": "Publique uniquement",
|
||||
"Protected Only": "Protégé uniquement",
|
||||
"Secret Only": "Secret uniquement",
|
||||
"Public and Secret": "Public et secret",
|
||||
"Regular Pins": "Épingles régulières",
|
||||
"Video Pins": "Épingles vidéo",
|
||||
"Shopping Pins": "Pins d'achat",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Épingles d'idées"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Pinterest ビジネスアカウントに接続",
|
||||
"Create Pin": "ピンを作成",
|
||||
"Create Board": "ボードを作成",
|
||||
"Delete Pin": "ピンを削除",
|
||||
"Find Board by Name": "名前でボードを検索",
|
||||
"Find Pin by Title/Keyword": "タイトル/キーワードでピンを検索",
|
||||
"Update Board": "ボードを更新",
|
||||
"Upload an image or video to create a new Pin on a board.": "ボードに新しいピンを作成するには、画像またはビデオをアップロードします。",
|
||||
"Create a new Pinterest board for organizing Pins.": "新しい Pinterest ボードを作成してピンを整理します。",
|
||||
"Permanently delete a specific Pin.": "特定のピンを完全に削除します。",
|
||||
"Search for boards by name using Pinterest's search API.": "Pinterestの検索APIを使用してボードを名前で検索します。",
|
||||
"Search for Pins using title, description, or keywords.": "タイトル、説明、キーワードを使用してピンを検索します。",
|
||||
"Update a board's name, description, or privacy settings.": "ボードの名前、説明、またはプライバシー設定を更新します。",
|
||||
"Ad account Id": "広告アカウントID",
|
||||
"Board Id": "ボード ID",
|
||||
"Board Section Id": "ボードセクションID",
|
||||
"Title": "タイトル",
|
||||
"Description": "説明",
|
||||
"Media Source Type": "メディアソースタイプ",
|
||||
"Media URL": "メディア URL",
|
||||
"Destination Link": "リンク先先",
|
||||
"Dominant Color": "支配的な色",
|
||||
"Alt Text": "代替テキスト",
|
||||
"Parent Pin ID": "親ピンID",
|
||||
"Sponsor ID": "スポンサーID",
|
||||
"Product Tags": "商品タグ",
|
||||
"Note": "メモ",
|
||||
"Is Removable": "取り外し可能",
|
||||
"Board Name": "ボード名",
|
||||
"Privacy": "プライバシー",
|
||||
"Ads Only Board": "広告のみ ボード",
|
||||
"pin Id": "ピン ID",
|
||||
"Search Query": "検索クエリ",
|
||||
"Bookmark": "ブックマーク",
|
||||
"Pagination Bookmark": "ページングのブックマーク",
|
||||
"Maximum Results": "最大結果",
|
||||
"The title of the Pin (max 100 characters).": "ピンのタイトル (最大 100 文字)",
|
||||
"The description of the Pin (max 800 characters).": "ピンの説明 (最大 800 文字)。",
|
||||
"The type of media source for the Pin.": "ピンのメディアソースのタイプ。",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "アップロードする画像または動画のURL。有効なURLである必要があります。",
|
||||
"The destination URL that the Pin will link to when clicked.": "ピンがクリックされたときにリンクするリンク先URL。",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "16進カラーコードとしてのピンの支配的な色(例:\"#6E7874\")。",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "アクセシビリティとスクリーンリーダーの代替テキスト(最大 500 文字)。",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "保存済み/反復されたピンの場合、元のピンの ID です。",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "有料パートナーシップコンテンツのスポンサーアカウントID。クローズドベータでのユーザーのみ利用できます。",
|
||||
"Select one or more options": "1つ以上のオプションを選択してください",
|
||||
"A private note for this Pin that only you can see.": "あなただけが見ることができるこのピンのプライベートノート。",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "簡単に削除できる広告のみのピンを作成するには、true に設定します。",
|
||||
"The name of the board (max 180 characters).": "ボードの名前 (最大 180 文字)。",
|
||||
"Optional description for your board.": "あなたのボードの任意の説明。",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "ボードのプライバシー設定 (広告専用ボードの「保護」に自動設定)。",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "プロモーションピンのみを格納できるアドオン専用ボードを作成します。注:ボード名は「アドオン専用ピン」になり、プライバシーは「保護」に設定されます。",
|
||||
"The search term to find boards (required).": "ボードを検索するための検索語(必須)。",
|
||||
"Pagination bookmark from previous response.": "以前の応答からのページネーションブックマーク。",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "ピンのタイトル、説明、タグを検索します。カンマ区切りのピンIDを使用して検索することもできます。",
|
||||
"Bookmark token from previous search results for pagination.": "ページネーション用に以前の検索結果のブックマークトークン。",
|
||||
"Maximum number of pins to return (useful for large result sets).": "リターンする最大ピン数(大きな結果セットに便利)。",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "ボードの新しい名前 (最大 180 文字) 。現在の名前を保持するには空白のままにします。",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "ボードの新しい説明(最大500文字)。現在の説明を維持するには空のままにしてください。",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "ボードのプライバシー設定を更新します。空のままにすると現在の設定を維持します。",
|
||||
"Image URL": "画像URL",
|
||||
"Base64 Image": "Base64 画像",
|
||||
"Video URL": "動画の URL",
|
||||
"Public": "公開",
|
||||
"Protected": "保護",
|
||||
"Secret": "シークレット",
|
||||
"New Board": "新しいボード",
|
||||
"New Follower": "新しいフォロワー",
|
||||
"New Pin on Board": "ボード上の新しいピン",
|
||||
"Fires when a new board is created in the account.": "アカウントに新しいボードが作成されたときに発火します。",
|
||||
"Triggers when a user gains a new follower.": "ユーザーが新しいフォロワーを獲得したときにトリガーします。",
|
||||
"Fires when a new Pin is added to a specific board.": "新しいピンが特定のボードに追加されたときに発生します。",
|
||||
"Board Privacy Filter": "ボードプライバシーフィルタ",
|
||||
"Page Size": "ページサイズ",
|
||||
"Pin Types to Watch": "ウォッチにピンタイプ",
|
||||
"Filter boards by privacy setting (optional).": "プライバシー設定でボードを絞り込みます (オプション)。",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "ページごとにフェッチするボードの数(1-250、デフォルト:25)",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "特定のピンタイプでフィルタします。すべてのタイプを見るには空のままにします。",
|
||||
"All Boards": "すべてのボード",
|
||||
"Public Only": "公開のみ",
|
||||
"Protected Only": "保護されたのみ",
|
||||
"Secret Only": "シークレットのみ",
|
||||
"Public and Secret": "公開と秘密",
|
||||
"Regular Pins": "レギュラーピン",
|
||||
"Video Pins": "ビデオピン",
|
||||
"Shopping Pins": "ショッピングピン",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "アイディアピン"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Verbind uw Pinterest Business Account",
|
||||
"Create Pin": "Pincode maken",
|
||||
"Create Board": "Creëer bord",
|
||||
"Delete Pin": "Verwijder PIN",
|
||||
"Find Board by Name": "Zoek bord op naam",
|
||||
"Find Pin by Title/Keyword": "Zoek PIN op Titel/Sleutelwoord",
|
||||
"Update Board": "Bord bijwerken",
|
||||
"Upload an image or video to create a new Pin on a board.": "Upload een afbeelding of video om een nieuwe pin op een bord te maken.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Maak een nieuw Pinterest board voor het organiseren van Pins.",
|
||||
"Permanently delete a specific Pin.": "Een specifieke pin permanent verwijderen.",
|
||||
"Search for boards by name using Pinterest's search API.": "Zoek boards op naam met behulp van Pinterest's zoekAPI.",
|
||||
"Search for Pins using title, description, or keywords.": "Zoek naar pinnen met titel, beschrijving of trefwoorden.",
|
||||
"Update a board's name, description, or privacy settings.": "Werk de naam van een bord of privacy instellingen bij.",
|
||||
"Ad account Id": "Advertentie account-ID",
|
||||
"Board Id": "Bord ID",
|
||||
"Board Section Id": "Sectie-ID Bord",
|
||||
"Title": "Aanspreektitel",
|
||||
"Description": "Beschrijving",
|
||||
"Media Source Type": "Media Source Type",
|
||||
"Media URL": "Media URL",
|
||||
"Destination Link": "Bestemming Link",
|
||||
"Dominant Color": "Dominante Kleur",
|
||||
"Alt Text": "Alternatieve tekst",
|
||||
"Parent Pin ID": "Bovenliggende pin ID",
|
||||
"Sponsor ID": "Sponsor ID",
|
||||
"Product Tags": "Product tags",
|
||||
"Note": "Notitie",
|
||||
"Is Removable": "Is verwijderbaar",
|
||||
"Board Name": "Naam bord",
|
||||
"Privacy": "Privacy",
|
||||
"Ads Only Board": "Alleen advertenties",
|
||||
"pin Id": "pin ID",
|
||||
"Search Query": "Zoek query",
|
||||
"Bookmark": "Bladwijzer",
|
||||
"Pagination Bookmark": "Paginering Bookmark",
|
||||
"Maximum Results": "Maximaal aantal resultaten",
|
||||
"The title of the Pin (max 100 characters).": "De titel van de pin (max 100 tekens).",
|
||||
"The description of the Pin (max 800 characters).": "De beschrijving van de pin (max 800 tekens).",
|
||||
"The type of media source for the Pin.": "Het mediabron voor de Pin.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "De URL van de afbeelding of video om te uploaden. Moet een geldige URL zijn.",
|
||||
"The destination URL that the Pin will link to when clicked.": "De doel-URL waarnaar de PIN linkt wanneer geklikt wordt.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "De dominante kleur van de pincode als hex kleurcode (bijv. \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Alternatieve tekst voor toegankelijkheid en schermlezers (max 500 tekens).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "Het ID van de originele PIN als dit een opgeslagen/gerepareerde PIN is.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "De sponsor account ID voor betaalde partnerschap inhoud. Alleen beschikbaar voor gebruikers in gesloten beta.",
|
||||
"Select one or more options": "Selecteer een of meer opties",
|
||||
"A private note for this Pin that only you can see.": "Een privénotitie voor deze pin die alleen u kunt zien.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Zet op true om een alleen-kladblok te maken die gemakkelijk kan worden verwijderd.",
|
||||
"The name of the board (max 180 characters).": "De naam van het bord (max 180 tekens).",
|
||||
"Optional description for your board.": "Optionele beschrijving voor jouw bord.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Bord privacy-instelling (automatisch ingesteld op \"PROTECTED\" voor reclameborden).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Creëer een enkel advertentiebord dat alleen promotionele pinnen kan opslaan. Opmerking: Bordentnaam wordt \"Ad-only Pins\" en privacy wordt ingesteld op \"PROTECTED\".",
|
||||
"The search term to find boards (required).": "De zoekterm om boards te vinden (vereist).",
|
||||
"Pagination bookmark from previous response.": "Paginering bladwijzer van het vorige antwoord.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Zoektermen voor pin titels, beschrijvingen of tags. U kunt ook zoeken met behulp van komma-gescheiden pin IDs.",
|
||||
"Bookmark token from previous search results for pagination.": "Bladwijzer token uit vorige zoekresultaten voor paginering.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Maximum aantal te retourneren pinnen (nuttig voor grote resultaatsets).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "De nieuwe naam van het bord (max 180 tekens). Laat leeg om de huidige naam te bewaren.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "De nieuwe beschrijving van het bord (max 500 tekens). Laat leeg om de huidige beschrijving te behouden.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Update board privacy instelling. Laat leeg om de huidige instelling te behouden.",
|
||||
"Image URL": "Afbeelding URL",
|
||||
"Base64 Image": "Base64 afbeelding",
|
||||
"Video URL": "Video URL",
|
||||
"Public": "Openbaar",
|
||||
"Protected": "Beschermd",
|
||||
"Secret": "Geheim",
|
||||
"New Board": "Nieuw bord",
|
||||
"New Follower": "Nieuwe volger",
|
||||
"New Pin on Board": "Nieuwe pin op bord",
|
||||
"Fires when a new board is created in the account.": "Schiet wanneer een nieuw bord wordt aangemaakt in het account.",
|
||||
"Triggers when a user gains a new follower.": "Triggert wanneer een gebruiker een nieuwe volger krijgt.",
|
||||
"Fires when a new Pin is added to a specific board.": "Vuurt wanneer een nieuwe pin is toegevoegd aan een specifiek bord.",
|
||||
"Board Privacy Filter": "Bord privacyfilter",
|
||||
"Page Size": "Paginagrootte",
|
||||
"Pin Types to Watch": "Typ typen om te bekijken",
|
||||
"Filter boards by privacy setting (optional).": "Filter boards op privacy-instelling (optioneel).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Aantal boards dat per pagina moet worden opgehaald (1-250, standaard: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Filter op specifieke pintypes. Laat leeg om alle typen te bekijken.",
|
||||
"All Boards": "Alle boards",
|
||||
"Public Only": "Alleen openbaar",
|
||||
"Protected Only": "Alleen beschermd",
|
||||
"Secret Only": "Alleen geheim",
|
||||
"Public and Secret": "Openbaar en geheim",
|
||||
"Regular Pins": "Normale pinnen",
|
||||
"Video Pins": "Video pinnen",
|
||||
"Shopping Pins": "Winkel pinnen",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Idee pinnen"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Conecte sua conta empresarial do Pinterest",
|
||||
"Create Pin": "Criar PIN",
|
||||
"Create Board": "Criar Board",
|
||||
"Delete Pin": "Excluir Pin",
|
||||
"Find Board by Name": "Encontrar Board por Nome",
|
||||
"Find Pin by Title/Keyword": "Encontre o Pin por Título/Palavra-chave",
|
||||
"Update Board": "Atualizar Board",
|
||||
"Upload an image or video to create a new Pin on a board.": "Enviar uma imagem ou vídeo para criar um novo pin na lousa.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Criar um novo quadro do Pinterest para organizar Pins.",
|
||||
"Permanently delete a specific Pin.": "Exclua permanentemente um pin específico.",
|
||||
"Search for boards by name using Pinterest's search API.": "Busca por boards por nome usando a API de busca do Pinterest.",
|
||||
"Search for Pins using title, description, or keywords.": "Pesquise por Pins usando título, descrição ou palavras-chave.",
|
||||
"Update a board's name, description, or privacy settings.": "Atualizar o nome, descrição ou configurações de privacidade de um fórum.",
|
||||
"Ad account Id": "ID da conta de anúncio",
|
||||
"Board Id": "ID do fórum",
|
||||
"Board Section Id": "ID da seção Board",
|
||||
"Title": "Título",
|
||||
"Description": "Descrição",
|
||||
"Media Source Type": "Tipo de Fonte de Mídia",
|
||||
"Media URL": "URL da Mídia",
|
||||
"Destination Link": "Link de destino",
|
||||
"Dominant Color": "Cor do Dominante",
|
||||
"Alt Text": "Texto Alternativo",
|
||||
"Parent Pin ID": "ID Pin Pai",
|
||||
"Sponsor ID": "ID do Patrocinador",
|
||||
"Product Tags": "Tags de Produto",
|
||||
"Note": "Observação",
|
||||
"Is Removable": "É removível",
|
||||
"Board Name": "Nome do quadro",
|
||||
"Privacy": "Privacidade",
|
||||
"Ads Only Board": "Área de anúncios",
|
||||
"pin Id": "ID do pin",
|
||||
"Search Query": "Consulta de Pesquisa",
|
||||
"Bookmark": "Favorito",
|
||||
"Pagination Bookmark": "Marcador de Paginação",
|
||||
"Maximum Results": "Resultados máximos",
|
||||
"The title of the Pin (max 100 characters).": "O título do Pin (máx. 100 caracteres).",
|
||||
"The description of the Pin (max 800 characters).": "A descrição do Pin (máx. 800 caracteres).",
|
||||
"The type of media source for the Pin.": "O tipo de fonte de mídia para o Pin.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "A URL da imagem ou vídeo para upload. Deve ser uma URL válida.",
|
||||
"The destination URL that the Pin will link to when clicked.": "A URL de destino que o Pin irá vincular quando clicado.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "A cor dominante do Pin como um código de cores hexadecimal (ex: \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Texto alternativo para leitores de tela e acessibilidade (máximo de 500 caracteres).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "O ID do Pin original se isto é um Pin salvo/refixado.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "O ID de conta de patrocinador para conteúdo pago de parceria. Disponível apenas para selecionar usuários em beta fechado.",
|
||||
"Select one or more options": "Selecione uma ou mais opções",
|
||||
"A private note for this Pin that only you can see.": "Uma nota privada para este Pin que só você pode ver.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Defina como verdadeiro para criar um Pin com apenas anúncios que pode ser facilmente removido.",
|
||||
"The name of the board (max 180 characters).": "O nome do board (máximo de 180 caracteres).",
|
||||
"Optional description for your board.": "Descrição opcional para seu fórum.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Configurações de privacidade do fórum (auto-definir como \"PROTECTAD\" para quadros somente anúncios).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Crie um board somente-anúncio que só pode armazenar Pins promocionais. Nota: O nome do Board se tornará \"Pins com apenas publicidade\" e a privacidade será definida como \"PROTECTADA\".",
|
||||
"The search term to find boards (required).": "O termo da pesquisa para encontrar quadros (obrigatório).",
|
||||
"Pagination bookmark from previous response.": "Marcador de paginação da resposta anterior.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Termos de pesquisa para pin títulos, descrições ou tags. Você também pode procurar usando IDs de pin separados por vírgula.",
|
||||
"Bookmark token from previous search results for pagination.": "Token de marcador dos resultados de pesquisa anteriores para paginação.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Número máximo de pinos a retornar (útil para grandes conjuntos de resultados).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "O novo nome do board (máximo de 180 caracteres). Deixe em branco para manter o nome atual.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "A nova descrição do board (máx. 500 caracteres). Deixe em branco para manter a descrição atual.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Atualize a configuração de privacidade do fórum. Deixe em branco para manter a configuração atual.",
|
||||
"Image URL": "URL da imagem",
|
||||
"Base64 Image": "Imagem Base64",
|
||||
"Video URL": "URL do vídeo",
|
||||
"Public": "Público",
|
||||
"Protected": "Protegido",
|
||||
"Secret": "Segredo",
|
||||
"New Board": "Novo Conselho",
|
||||
"New Follower": "Novo seguidor",
|
||||
"New Pin on Board": "Novo Pin no Board",
|
||||
"Fires when a new board is created in the account.": "aciona quando um novo quadro é criado na conta.",
|
||||
"Triggers when a user gains a new follower.": "Dispara quando um usuário ganha um novo seguidor.",
|
||||
"Fires when a new Pin is added to a specific board.": "Lança quando um novo Pin é adicionado a um quadro específico.",
|
||||
"Board Privacy Filter": "Board Filtro de Privacidade",
|
||||
"Page Size": "Tamanho da página",
|
||||
"Pin Types to Watch": "Fixar Tipos para Assistir",
|
||||
"Filter boards by privacy setting (optional).": "Filtrar quadros por configuração de privacidade (opcional).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Número de boards para buscar por página (1-250, padrão: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Filtrar por tipos de pin específicos. Deixe em branco para assistir a todos os tipos.",
|
||||
"All Boards": "Todas as Seções",
|
||||
"Public Only": "Apenas Público",
|
||||
"Protected Only": "Somente Protegido",
|
||||
"Secret Only": "Apenas Segredo",
|
||||
"Public and Secret": "Público e Segredo",
|
||||
"Regular Pins": "Pins regulares",
|
||||
"Video Pins": "Pins de vídeo",
|
||||
"Shopping Pins": "Pins de Compras",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Fixos de Ideia"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Connect your Pinterest Business Account",
|
||||
"Create Pin": "Create Pin",
|
||||
"Create Board": "Create Board",
|
||||
"Delete Pin": "Delete Pin",
|
||||
"Find Board by Name": "Find Board by Name",
|
||||
"Find Pin by Title/Keyword": "Find Pin by Title/Keyword",
|
||||
"Update Board": "Update Board",
|
||||
"Upload an image or video to create a new Pin on a board.": "Upload an image or video to create a new Pin on a board.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Create a new Pinterest board for organizing Pins.",
|
||||
"Permanently delete a specific Pin.": "Permanently delete a specific Pin.",
|
||||
"Search for boards by name using Pinterest's search API.": "Search for boards by name using Pinterest's search API.",
|
||||
"Search for Pins using title, description, or keywords.": "Search for Pins using title, description, or keywords.",
|
||||
"Update a board's name, description, or privacy settings.": "Update a board's name, description, or privacy settings.",
|
||||
"Ad account Id": "Ad account Id",
|
||||
"Board Id": "Board Id",
|
||||
"Board Section Id": "Board Section Id",
|
||||
"Title": "Title",
|
||||
"Description": "Description",
|
||||
"Media Source Type": "Media Source Type",
|
||||
"Media URL": "Media URL",
|
||||
"Destination Link": "Destination Link",
|
||||
"Dominant Color": "Dominant Color",
|
||||
"Alt Text": "Alt Text",
|
||||
"Parent Pin ID": "Parent Pin ID",
|
||||
"Sponsor ID": "Sponsor ID",
|
||||
"Product Tags": "Product Tags",
|
||||
"Note": "Note",
|
||||
"Is Removable": "Is Removable",
|
||||
"Board Name": "Board Name",
|
||||
"Privacy": "Privacy",
|
||||
"Ads Only Board": "Ads Only Board",
|
||||
"pin Id": "pin Id",
|
||||
"Search Query": "Search Query",
|
||||
"Bookmark": "Bookmark",
|
||||
"Pagination Bookmark": "Pagination Bookmark",
|
||||
"Maximum Results": "Maximum Results",
|
||||
"The title of the Pin (max 100 characters).": "The title of the Pin (max 100 characters).",
|
||||
"The description of the Pin (max 800 characters).": "The description of the Pin (max 800 characters).",
|
||||
"The type of media source for the Pin.": "The type of media source for the Pin.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "The URL of the image or video to upload. Must be a valid URL.",
|
||||
"The destination URL that the Pin will link to when clicked.": "The destination URL that the Pin will link to when clicked.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Alternative text for accessibility and screen readers (max 500 characters).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "The ID of the original Pin if this is a saved/repinned Pin.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "The sponsor account ID for paid partnership content. Available only to select users in closed beta.",
|
||||
"Select one or more options": "Select one or more options",
|
||||
"A private note for this Pin that only you can see.": "A private note for this Pin that only you can see.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Set to true to create an ad-only Pin that can be easily removed.",
|
||||
"The name of the board (max 180 characters).": "The name of the board (max 180 characters).",
|
||||
"Optional description for your board.": "Optional description for your board.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".",
|
||||
"The search term to find boards (required).": "The search term to find boards (required).",
|
||||
"Pagination bookmark from previous response.": "Pagination bookmark from previous response.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.",
|
||||
"Bookmark token from previous search results for pagination.": "Bookmark token from previous search results for pagination.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Maximum number of pins to return (useful for large result sets).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "The new name of the board (max 180 characters). Leave empty to keep current name.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "The new description of the board (max 500 characters). Leave empty to keep current description.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Update board privacy setting. Leave empty to keep current setting.",
|
||||
"Image URL": "Image URL",
|
||||
"Base64 Image": "Base64 Image",
|
||||
"Video URL": "Video URL",
|
||||
"Public": "Public",
|
||||
"Protected": "Protected",
|
||||
"Secret": "Secret",
|
||||
"New Board": "New Board",
|
||||
"New Follower": "New Follower",
|
||||
"New Pin on Board": "New Pin on Board",
|
||||
"Fires when a new board is created in the account.": "Fires when a new board is created in the account.",
|
||||
"Triggers when a user gains a new follower.": "Triggers when a user gains a new follower.",
|
||||
"Fires when a new Pin is added to a specific board.": "Fires when a new Pin is added to a specific board.",
|
||||
"Board Privacy Filter": "Board Privacy Filter",
|
||||
"Page Size": "Page Size",
|
||||
"Pin Types to Watch": "Pin Types to Watch",
|
||||
"Filter boards by privacy setting (optional).": "Filter boards by privacy setting (optional).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Number of boards to fetch per page (1-250, default: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Filter by specific pin types. Leave empty to watch all types.",
|
||||
"All Boards": "All Boards",
|
||||
"Public Only": "Public Only",
|
||||
"Protected Only": "Protected Only",
|
||||
"Secret Only": "Secret Only",
|
||||
"Public and Secret": "Public and Secret",
|
||||
"Regular Pins": "Regular Pins",
|
||||
"Video Pins": "Video Pins",
|
||||
"Shopping Pins": "Shopping Pins",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Idea Pins"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Connect your Pinterest Business Account": "Connect your Pinterest Business Account",
|
||||
"Create Pin": "Create Pin",
|
||||
"Create Board": "Create Board",
|
||||
"Delete Pin": "Delete Pin",
|
||||
"Find Board by Name": "Find Board by Name",
|
||||
"Find Pin by Title/Keyword": "Find Pin by Title/Keyword",
|
||||
"Update Board": "Update Board",
|
||||
"Upload an image or video to create a new Pin on a board.": "Upload an image or video to create a new Pin on a board.",
|
||||
"Create a new Pinterest board for organizing Pins.": "Create a new Pinterest board for organizing Pins.",
|
||||
"Permanently delete a specific Pin.": "Permanently delete a specific Pin.",
|
||||
"Search for boards by name using Pinterest's search API.": "Search for boards by name using Pinterest's search API.",
|
||||
"Search for Pins using title, description, or keywords.": "Search for Pins using title, description, or keywords.",
|
||||
"Update a board's name, description, or privacy settings.": "Update a board's name, description, or privacy settings.",
|
||||
"Ad account Id": "Ad account Id",
|
||||
"Board Id": "Board Id",
|
||||
"Board Section Id": "Board Section Id",
|
||||
"Title": "标题",
|
||||
"Description": "描述",
|
||||
"Media Source Type": "Media Source Type",
|
||||
"Media URL": "Media URL",
|
||||
"Destination Link": "Destination Link",
|
||||
"Dominant Color": "Dominant Color",
|
||||
"Alt Text": "Alt Text",
|
||||
"Parent Pin ID": "Parent Pin ID",
|
||||
"Sponsor ID": "Sponsor ID",
|
||||
"Product Tags": "Product Tags",
|
||||
"Note": "说明",
|
||||
"Is Removable": "Is Removable",
|
||||
"Board Name": "Board Name",
|
||||
"Privacy": "Privacy",
|
||||
"Ads Only Board": "Ads Only Board",
|
||||
"pin Id": "pin Id",
|
||||
"Search Query": "Search Query",
|
||||
"Bookmark": "Bookmark",
|
||||
"Pagination Bookmark": "Pagination Bookmark",
|
||||
"Maximum Results": "Maximum Results",
|
||||
"The title of the Pin (max 100 characters).": "The title of the Pin (max 100 characters).",
|
||||
"The description of the Pin (max 800 characters).": "The description of the Pin (max 800 characters).",
|
||||
"The type of media source for the Pin.": "The type of media source for the Pin.",
|
||||
"The URL of the image or video to upload. Must be a valid URL.": "The URL of the image or video to upload. Must be a valid URL.",
|
||||
"The destination URL that the Pin will link to when clicked.": "The destination URL that the Pin will link to when clicked.",
|
||||
"The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").": "The dominant color of the Pin as a hex color code (e.g., \"#6E7874\").",
|
||||
"Alternative text for accessibility and screen readers (max 500 characters).": "Alternative text for accessibility and screen readers (max 500 characters).",
|
||||
"The ID of the original Pin if this is a saved/repinned Pin.": "The ID of the original Pin if this is a saved/repinned Pin.",
|
||||
"The sponsor account ID for paid partnership content. Available only to select users in closed beta.": "The sponsor account ID for paid partnership content. Available only to select users in closed beta.",
|
||||
"Select one or more options": "Select one or more options",
|
||||
"A private note for this Pin that only you can see.": "A private note for this Pin that only you can see.",
|
||||
"Set to true to create an ad-only Pin that can be easily removed.": "Set to true to create an ad-only Pin that can be easily removed.",
|
||||
"The name of the board (max 180 characters).": "The name of the board (max 180 characters).",
|
||||
"Optional description for your board.": "Optional description for your board.",
|
||||
"Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).": "Board privacy setting (auto-set to \"PROTECTED\" for ad-only boards).",
|
||||
"Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".": "Create an ad-only board that can only store promotional Pins. Note: Board name will become \"Ad-only Pins\" and privacy will be set to \"PROTECTED\".",
|
||||
"The search term to find boards (required).": "The search term to find boards (required).",
|
||||
"Pagination bookmark from previous response.": "Pagination bookmark from previous response.",
|
||||
"Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.": "Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.",
|
||||
"Bookmark token from previous search results for pagination.": "Bookmark token from previous search results for pagination.",
|
||||
"Maximum number of pins to return (useful for large result sets).": "Maximum number of pins to return (useful for large result sets).",
|
||||
"The new name of the board (max 180 characters). Leave empty to keep current name.": "The new name of the board (max 180 characters). Leave empty to keep current name.",
|
||||
"The new description of the board (max 500 characters). Leave empty to keep current description.": "The new description of the board (max 500 characters). Leave empty to keep current description.",
|
||||
"Update board privacy setting. Leave empty to keep current setting.": "Update board privacy setting. Leave empty to keep current setting.",
|
||||
"Image URL": "Image URL",
|
||||
"Base64 Image": "Base64 Image",
|
||||
"Video URL": "Video URL",
|
||||
"Public": "Public",
|
||||
"Protected": "Protected",
|
||||
"Secret": "Secret",
|
||||
"New Board": "New Board",
|
||||
"New Follower": "New Follower",
|
||||
"New Pin on Board": "New Pin on Board",
|
||||
"Fires when a new board is created in the account.": "Fires when a new board is created in the account.",
|
||||
"Triggers when a user gains a new follower.": "Triggers when a user gains a new follower.",
|
||||
"Fires when a new Pin is added to a specific board.": "Fires when a new Pin is added to a specific board.",
|
||||
"Board Privacy Filter": "Board Privacy Filter",
|
||||
"Page Size": "Page Size",
|
||||
"Pin Types to Watch": "Pin Types to Watch",
|
||||
"Filter boards by privacy setting (optional).": "Filter boards by privacy setting (optional).",
|
||||
"Number of boards to fetch per page (1-250, default: 25).": "Number of boards to fetch per page (1-250, default: 25).",
|
||||
"Filter by specific pin types. Leave empty to watch all types.": "Filter by specific pin types. Leave empty to watch all types.",
|
||||
"All Boards": "All Boards",
|
||||
"Public Only": "Public Only",
|
||||
"Protected Only": "Protected Only",
|
||||
"Secret Only": "Secret Only",
|
||||
"Public and Secret": "Public and Secret",
|
||||
"Regular Pins": "Regular Pins",
|
||||
"Video Pins": "Video Pins",
|
||||
"Shopping Pins": "Shopping Pins",
|
||||
"Carousel Pins": "Carousel Pins",
|
||||
"Idea Pins": "Idea Pins"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createPiece } from '@activepieces/pieces-framework';
|
||||
import { pinterestAuth } from './lib/common/auth';
|
||||
import { createPin } from './lib/actions/create-pin';
|
||||
import { createBoard } from './lib/actions/create-board';
|
||||
import { deletePin } from './lib/actions/delete-pin';
|
||||
import { findBoardByName } from './lib/actions/find-board-by-name';
|
||||
import { findPin } from './lib/actions/find-pin';
|
||||
import { updateBoard } from './lib/actions/update-board';
|
||||
import { newBoard } from './lib/triggers/new-board';
|
||||
import { newFollower } from './lib/triggers/new-follower';
|
||||
import { newPinOnBoard } from './lib/triggers/new-pin-on-board';
|
||||
|
||||
export const pinterest = createPiece({
|
||||
displayName: 'Pinterest',
|
||||
auth: pinterestAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/pinterest.png',
|
||||
authors: ['Sanket6652'],
|
||||
actions: [
|
||||
createPin,
|
||||
createBoard,
|
||||
deletePin,
|
||||
findBoardByName,
|
||||
findPin,
|
||||
updateBoard,
|
||||
],
|
||||
triggers: [newBoard, newFollower, newPinOnBoard],
|
||||
});
|
||||
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { adAccountIdDropdown } from '../common/props';
|
||||
|
||||
export const createBoard = createAction({
|
||||
auth: pinterestAuth,
|
||||
name: 'createBoard',
|
||||
displayName: 'Create Board',
|
||||
description: 'Create a new Pinterest board for organizing Pins.',
|
||||
props: {
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
name: Property.ShortText({
|
||||
displayName: 'Board Name',
|
||||
required: true,
|
||||
description: 'The name of the board (max 180 characters).',
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
required: false,
|
||||
description: 'Optional description for your board.',
|
||||
}),
|
||||
privacy: Property.StaticDropdown({
|
||||
displayName: 'Privacy',
|
||||
required: false,
|
||||
defaultValue: 'PUBLIC',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Public', value: 'PUBLIC' },
|
||||
{ label: 'Protected', value: 'PROTECTED' },
|
||||
{ label: 'Secret', value: 'SECRET' },
|
||||
],
|
||||
},
|
||||
description:
|
||||
'Board privacy setting (auto-set to "PROTECTED" for ad-only boards).',
|
||||
}),
|
||||
is_ads_only: Property.Checkbox({
|
||||
displayName: 'Ads Only Board',
|
||||
description:
|
||||
'Create an ad-only board that can only store promotional Pins. Note: Board name will become "Ad-only Pins" and privacy will be set to "PROTECTED".',
|
||||
defaultValue: false,
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const { ad_account_id, name, description, privacy, is_ads_only } =
|
||||
propsValue;
|
||||
// Validation
|
||||
if (name && name.length > 180) {
|
||||
throw new Error('Board name must be 180 characters or less');
|
||||
}
|
||||
|
||||
if (description && description.length > 500) {
|
||||
throw new Error('Board description must be 500 characters or less');
|
||||
}
|
||||
const body: any = {
|
||||
name,
|
||||
is_ads_only,
|
||||
};
|
||||
if (description) body.description = description;
|
||||
if (privacy) body.privacy = privacy;
|
||||
|
||||
let path = '/boards';
|
||||
if (ad_account_id) {
|
||||
path = `/boards?ad_account_id=${encodeURIComponent(ad_account_id)}`;
|
||||
}
|
||||
|
||||
return await makeRequest(
|
||||
getAccessTokenOrThrow(auth),
|
||||
HttpMethod.POST,
|
||||
path,
|
||||
body
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,198 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import {
|
||||
adAccountIdDropdown,
|
||||
boardIdDropdown,
|
||||
boardSectionIdDropdown,
|
||||
pinIdMultiSelectDropdown,
|
||||
} from '../common/props';
|
||||
|
||||
export const createPin = createAction({
|
||||
auth: pinterestAuth,
|
||||
name: 'createPin',
|
||||
displayName: 'Create Pin',
|
||||
description: 'Upload an image or video to create a new Pin on a board.',
|
||||
props: {
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
board_id: boardIdDropdown,
|
||||
board_section_id: boardSectionIdDropdown,
|
||||
title: Property.ShortText({
|
||||
displayName: 'Title',
|
||||
required: true,
|
||||
description: 'The title of the Pin (max 100 characters).',
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
required: false,
|
||||
description: 'The description of the Pin (max 800 characters).',
|
||||
}),
|
||||
media_source_type: Property.StaticDropdown({
|
||||
displayName: 'Media Source Type',
|
||||
required: true,
|
||||
description: 'The type of media source for the Pin.',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Image URL', value: 'image_url' },
|
||||
{ label: 'Base64 Image', value: 'image_base64' },
|
||||
{ label: 'Video URL', value: 'video_url' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
media_url: Property.ShortText({
|
||||
displayName: 'Media URL',
|
||||
required: true,
|
||||
description:
|
||||
'The URL of the image or video to upload. Must be a valid URL.',
|
||||
}),
|
||||
link: Property.ShortText({
|
||||
displayName: 'Destination Link',
|
||||
required: false,
|
||||
description:
|
||||
'The destination URL that the Pin will link to when clicked.',
|
||||
}),
|
||||
dominant_color: Property.ShortText({
|
||||
displayName: 'Dominant Color',
|
||||
description:
|
||||
'The dominant color of the Pin as a hex color code (e.g., "#6E7874").',
|
||||
required: false,
|
||||
}),
|
||||
alt_text: Property.ShortText({
|
||||
displayName: 'Alt Text',
|
||||
description:
|
||||
'Alternative text for accessibility and screen readers (max 500 characters).',
|
||||
required: false,
|
||||
}),
|
||||
parent_pin_id: Property.ShortText({
|
||||
displayName: 'Parent Pin ID',
|
||||
description:
|
||||
'The ID of the original Pin if this is a saved/repinned Pin.',
|
||||
required: false,
|
||||
}),
|
||||
sponsor_id: Property.ShortText({
|
||||
displayName: 'Sponsor ID',
|
||||
description:
|
||||
'The sponsor account ID for paid partnership content. Available only to select users in closed beta.',
|
||||
required: false,
|
||||
}),
|
||||
product_tags: pinIdMultiSelectDropdown,
|
||||
note: Property.ShortText({
|
||||
displayName: 'Note',
|
||||
description: 'A private note for this Pin that only you can see.',
|
||||
required: false,
|
||||
}),
|
||||
is_removable: Property.Checkbox({
|
||||
displayName: 'Is Removable',
|
||||
description:
|
||||
'Set to true to create an ad-only Pin that can be easily removed.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const {
|
||||
board_id,
|
||||
board_section_id,
|
||||
title,
|
||||
description,
|
||||
media_source_type,
|
||||
media_url,
|
||||
link,
|
||||
dominant_color,
|
||||
alt_text,
|
||||
parent_pin_id,
|
||||
is_removable,
|
||||
product_tags,
|
||||
ad_account_id,
|
||||
note,
|
||||
sponsor_id,
|
||||
} = propsValue;
|
||||
|
||||
// Validation
|
||||
if (title && title.length > 100) {
|
||||
throw new Error('Title must be 100 characters or less');
|
||||
}
|
||||
|
||||
if (description && description.length > 800) {
|
||||
throw new Error('Description must be 800 characters or less');
|
||||
}
|
||||
|
||||
if (alt_text && alt_text.length > 500) {
|
||||
throw new Error('Alt text must be 500 characters or less');
|
||||
}
|
||||
|
||||
// URL validation for media_url
|
||||
try {
|
||||
new URL(media_url);
|
||||
} catch {
|
||||
throw new Error('Please enter a valid URL for Image/Video URL');
|
||||
}
|
||||
|
||||
// URL validation for link (if provided)
|
||||
if (link) {
|
||||
try {
|
||||
new URL(link);
|
||||
} catch {
|
||||
throw new Error('Please enter a valid URL for Destination Link');
|
||||
}
|
||||
}
|
||||
|
||||
// Hex color validation for dominant_color (if provided)
|
||||
if (dominant_color) {
|
||||
const hexColorRegex = /^#[0-9A-Fa-f]{6}$/;
|
||||
if (!hexColorRegex.test(dominant_color)) {
|
||||
throw new Error(
|
||||
'Pin Color must be a valid hex color format (e.g., #6E7874)'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Build request body according to Pinterest API spec
|
||||
const body: any = {
|
||||
board_id,
|
||||
title,
|
||||
media_source: {
|
||||
source_type: media_source_type,
|
||||
url: media_url,
|
||||
},
|
||||
};
|
||||
|
||||
// Add optional fields only if they have values
|
||||
if (board_section_id) body.board_section_id = board_section_id;
|
||||
if (description) body.description = description;
|
||||
if (link) body.link = link;
|
||||
if (dominant_color) body.dominant_color = dominant_color;
|
||||
if (alt_text) body.alt_text = alt_text;
|
||||
if (parent_pin_id) body.parent_pin_id = parent_pin_id;
|
||||
if (note) body.note = note;
|
||||
if (sponsor_id) body.sponsor_id = sponsor_id;
|
||||
if (typeof is_removable === 'boolean') body.is_removable = is_removable;
|
||||
|
||||
// Handle product_tags array
|
||||
if (
|
||||
product_tags &&
|
||||
Array.isArray(product_tags) &&
|
||||
product_tags.length > 0
|
||||
) {
|
||||
body.product_tags = product_tags;
|
||||
}
|
||||
|
||||
// Build API path
|
||||
let path = '/pins';
|
||||
if (ad_account_id) {
|
||||
path = `/pins?ad_account_id=${encodeURIComponent(ad_account_id)}`;
|
||||
}
|
||||
|
||||
return await makeRequest(
|
||||
getAccessTokenOrThrow(auth),
|
||||
HttpMethod.POST,
|
||||
path,
|
||||
body
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { adAccountIdDropdown, pinIdDropdown } from '../common/props';
|
||||
|
||||
export const deletePin = createAction({
|
||||
auth: pinterestAuth,
|
||||
name: 'deletePin',
|
||||
displayName: 'Delete Pin',
|
||||
description: 'Permanently delete a specific Pin.',
|
||||
props: {
|
||||
pin_id: pinIdDropdown,
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const { pin_id, ad_account_id } = propsValue;
|
||||
|
||||
let path = `/pins/${pin_id}`;
|
||||
if (ad_account_id) {
|
||||
path = `/pins/${pin_id}?ad_account_id=${ad_account_id}`;
|
||||
}
|
||||
|
||||
const response = await makeRequest(
|
||||
getAccessTokenOrThrow(auth),
|
||||
HttpMethod.DELETE,
|
||||
path
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Pin ${pin_id} has been successfully deleted.`,
|
||||
pin_id: pin_id,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { adAccountIdDropdown } from '../common/props';
|
||||
|
||||
export const findBoardByName = createAction({
|
||||
auth: pinterestAuth,
|
||||
name: 'findBoardByName',
|
||||
displayName: 'Find Board by Name',
|
||||
description: "Search for boards by name using Pinterest's search API.",
|
||||
props: {
|
||||
query: Property.ShortText({
|
||||
displayName: 'Search Query',
|
||||
required: true,
|
||||
description: 'The search term to find boards (required).',
|
||||
}),
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
bookmark: Property.ShortText({
|
||||
displayName: 'Bookmark',
|
||||
required: false,
|
||||
description: 'Pagination bookmark from previous response.',
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const { query, ad_account_id, bookmark } = propsValue;
|
||||
|
||||
// Build query parameters
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append('query', query);
|
||||
|
||||
if (ad_account_id) {
|
||||
searchParams.append('ad_account_id', ad_account_id);
|
||||
}
|
||||
|
||||
if (bookmark) {
|
||||
searchParams.append('bookmark', bookmark);
|
||||
}
|
||||
|
||||
const path = `/search/boards/?${searchParams.toString()}`;
|
||||
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
getAccessTokenOrThrow(auth),
|
||||
HttpMethod.GET,
|
||||
path
|
||||
);
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to search boards: ${
|
||||
error instanceof Error ? error.message : 'Unknown error'
|
||||
}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { adAccountIdDropdown } from '../common/props';
|
||||
|
||||
export const findPin = createAction({
|
||||
auth: pinterestAuth,
|
||||
name: 'findPin',
|
||||
displayName: 'Find Pin by Title/Keyword',
|
||||
description: 'Search for Pins using title, description, or keywords.',
|
||||
props: {
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
query: Property.ShortText({
|
||||
displayName: 'Search Query',
|
||||
required: true,
|
||||
description:
|
||||
'Search terms for pin titles, descriptions, or tags. You can also search using comma-separated pin IDs.',
|
||||
}),
|
||||
bookmark: Property.ShortText({
|
||||
displayName: 'Pagination Bookmark',
|
||||
required: false,
|
||||
description:
|
||||
'Bookmark token from previous search results for pagination.',
|
||||
}),
|
||||
max_results: Property.Number({
|
||||
displayName: 'Maximum Results',
|
||||
required: false,
|
||||
description:
|
||||
'Maximum number of pins to return (useful for large result sets).',
|
||||
defaultValue: 25,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const { query, bookmark, ad_account_id, max_results } = propsValue;
|
||||
|
||||
// Build query parameters
|
||||
const params = new URLSearchParams();
|
||||
params.append('query', query);
|
||||
|
||||
if (bookmark) {
|
||||
params.append('bookmark', bookmark);
|
||||
}
|
||||
|
||||
if (ad_account_id) {
|
||||
params.append('ad_account_id', ad_account_id);
|
||||
}
|
||||
|
||||
const path = `/search/pins?${params.toString()}`;
|
||||
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
getAccessTokenOrThrow(auth),
|
||||
HttpMethod.GET,
|
||||
path
|
||||
);
|
||||
|
||||
// Apply max_results limit if specified
|
||||
let items = response.items || [];
|
||||
if (max_results && items.length > max_results) {
|
||||
items = items.slice(0, max_results);
|
||||
}
|
||||
|
||||
return {
|
||||
items,
|
||||
bookmark: response.bookmark,
|
||||
total_results: items.length,
|
||||
query_used: query,
|
||||
has_more: !!response.bookmark,
|
||||
};
|
||||
} catch (error: any) {
|
||||
if (error.response?.status === 404) {
|
||||
throw new Error('No pins found matching your search criteria.');
|
||||
}
|
||||
throw new Error(
|
||||
`Failed to search pins: ${error.message || 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { adAccountIdDropdown, boardIdDropdown } from '../common/props';
|
||||
|
||||
export const updateBoard = createAction({
|
||||
auth: pinterestAuth,
|
||||
name: 'updateBoard',
|
||||
displayName: 'Update Board',
|
||||
description: "Update a board's name, description, or privacy settings.",
|
||||
props: {
|
||||
board_id: boardIdDropdown,
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
name: Property.ShortText({
|
||||
displayName: 'Board Name',
|
||||
required: false,
|
||||
description:
|
||||
'The new name of the board (max 180 characters). Leave empty to keep current name.',
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
required: false,
|
||||
description:
|
||||
'The new description of the board (max 500 characters). Leave empty to keep current description.',
|
||||
}),
|
||||
privacy: Property.StaticDropdown({
|
||||
displayName: 'Privacy',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Public', value: 'PUBLIC' },
|
||||
{ label: 'Protected', value: 'PROTECTED' },
|
||||
{ label: 'Secret', value: 'SECRET' },
|
||||
],
|
||||
},
|
||||
description:
|
||||
'Update board privacy setting. Leave empty to keep current setting.',
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const { board_id, name, description, privacy, ad_account_id } = propsValue;
|
||||
|
||||
// Validation - at least one field must be provided for update
|
||||
if (!name && description === undefined && !privacy) {
|
||||
throw new Error(
|
||||
'At least one field (name, description, or privacy) must be provided to update the board.'
|
||||
);
|
||||
}
|
||||
|
||||
// Validation for field lengths
|
||||
if (name && name.length > 180) {
|
||||
throw new Error('Board name must be 180 characters or less');
|
||||
}
|
||||
|
||||
if (description && description.length > 500) {
|
||||
throw new Error('Board description must be 500 characters or less');
|
||||
}
|
||||
|
||||
// Build request body with only the fields being updated
|
||||
const body: any = {};
|
||||
if (name && name.trim()) {
|
||||
body.name = name.trim();
|
||||
}
|
||||
if (description !== undefined) {
|
||||
body.description = description;
|
||||
}
|
||||
if (privacy) {
|
||||
body.privacy = privacy;
|
||||
}
|
||||
|
||||
// Build path with query parameter if ad_account_id is provided
|
||||
let path = `/boards/${board_id}`;
|
||||
if (ad_account_id) {
|
||||
path = `/boards/${board_id}?ad_account_id=${encodeURIComponent(
|
||||
ad_account_id
|
||||
)}`;
|
||||
}
|
||||
|
||||
try {
|
||||
return await makeRequest(
|
||||
getAccessTokenOrThrow(auth),
|
||||
HttpMethod.PATCH,
|
||||
path,
|
||||
body
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to update board: ${
|
||||
error instanceof Error ? error.message : 'Unknown error'
|
||||
}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import {
|
||||
PieceAuth,
|
||||
OAuth2AuthorizationMethod,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
export const pinterestAuth = PieceAuth.OAuth2({
|
||||
description: 'Connect your Pinterest Business Account',
|
||||
authUrl: 'https://www.pinterest.com/oauth/',
|
||||
tokenUrl: 'https://api.pinterest.com/v5/oauth/token',
|
||||
required: true,
|
||||
scope: [
|
||||
'ads:read',
|
||||
'boards:read',
|
||||
'boards:write',
|
||||
'boards:read_secret',
|
||||
'pins:read',
|
||||
'pins:write',
|
||||
'pins:read_secret',
|
||||
'user_accounts:read',
|
||||
],
|
||||
authorizationMethod: OAuth2AuthorizationMethod.HEADER,
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
|
||||
export const BASE_URL = 'https://api.pinterest.com/v5';
|
||||
|
||||
export async function makeRequest(
|
||||
apiKey: string,
|
||||
method: HttpMethod,
|
||||
path: string,
|
||||
body?: unknown
|
||||
) {
|
||||
try {
|
||||
const response = await httpClient.sendRequest({
|
||||
method,
|
||||
url: `${BASE_URL}${path}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body,
|
||||
});
|
||||
|
||||
return response.body;
|
||||
} catch (error: any) {
|
||||
// Handle Pinterest API specific error codes
|
||||
if (error.response?.status) {
|
||||
const status = error.response.status;
|
||||
const errorData = error.response.body;
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
throw new Error(
|
||||
`Bad Request: ${
|
||||
errorData?.message ||
|
||||
'Invalid request parameters. Please check your input and try again.'
|
||||
}`
|
||||
);
|
||||
|
||||
case 401:
|
||||
throw new Error(
|
||||
'Authentication Failed: Your Pinterest access token is invalid or expired. Please reconnect your Pinterest account.'
|
||||
);
|
||||
|
||||
case 403:
|
||||
throw new Error(
|
||||
"Access Denied: You don't have permission to access this resource. Please check your Pinterest account permissions."
|
||||
);
|
||||
|
||||
case 404:
|
||||
throw new Error(
|
||||
'Resource Not Found: The requested Pinterest resource (board, pin, etc.) could not be found. Please verify the resource exists.'
|
||||
);
|
||||
|
||||
case 429:
|
||||
throw new Error(
|
||||
"Rate Limit Exceeded: You've exceeded Pinterest's API rate limits. Please wait a moment and try again."
|
||||
);
|
||||
|
||||
case 500:
|
||||
throw new Error(
|
||||
"Pinterest Server Error: Pinterest's servers are experiencing issues. Please try again later."
|
||||
);
|
||||
|
||||
case 502:
|
||||
throw new Error(
|
||||
"Bad Gateway: Pinterest's servers are temporarily unavailable. Please try again later."
|
||||
);
|
||||
|
||||
case 503:
|
||||
throw new Error(
|
||||
"Service Unavailable: Pinterest's API service is temporarily down. Please try again later."
|
||||
);
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
`Pinterest API Error (${status}): ${
|
||||
errorData?.message ||
|
||||
'An unexpected error occurred while communicating with Pinterest.'
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle network or other errors
|
||||
if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {
|
||||
throw new Error(
|
||||
'Network Error: Unable to connect to Pinterest API. Please check your internet connection and try again.'
|
||||
);
|
||||
}
|
||||
|
||||
if (error.code === 'ETIMEDOUT') {
|
||||
throw new Error(
|
||||
'Request Timeout: The request to Pinterest API timed out. Please try again.'
|
||||
);
|
||||
}
|
||||
|
||||
// Generic error fallback
|
||||
throw new Error(
|
||||
`Unexpected Error: ${
|
||||
error.message ||
|
||||
'An unexpected error occurred while processing your request.'
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
import {
|
||||
DropdownOption,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from '.';
|
||||
import { HttpMethod, getAccessTokenOrThrow } from '@activepieces/pieces-common';
|
||||
import { pinterestAuth } from './auth';
|
||||
|
||||
export const boardIdDropdown = Property.Dropdown({
|
||||
auth: pinterestAuth,
|
||||
displayName: 'Board Id',
|
||||
required: true,
|
||||
refreshers: ['ad_account_id'],
|
||||
options: async ({ auth, ad_account_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const url = new URL('/boards', 'https://api.pinterest.com/v5');
|
||||
if (ad_account_id) {
|
||||
url.searchParams.append('ad_account_id', ad_account_id as string);
|
||||
}
|
||||
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const boards = await makeRequest(
|
||||
accessToken,
|
||||
HttpMethod.GET,
|
||||
url.pathname + url.search
|
||||
);
|
||||
|
||||
const options: DropdownOption<string>[] = boards.items.map(
|
||||
(board: any) => ({
|
||||
label: board.name,
|
||||
value: board.id,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Error loading boards. Please try again.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const pinIdDropdown = Property.Dropdown({
|
||||
auth: pinterestAuth,
|
||||
displayName: 'pin Id',
|
||||
required: true,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const pins = await makeRequest(accessToken, HttpMethod.GET, '/pins');
|
||||
|
||||
const options: DropdownOption<string>[] = pins.items.map((pin: any) => ({
|
||||
label: pin.title,
|
||||
value: pin.id,
|
||||
}));
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Error loading pins. Please try again.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const adAccountIdDropdown = Property.Dropdown({
|
||||
auth: pinterestAuth,
|
||||
displayName: 'Ad account Id',
|
||||
required: false,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const adAccounts = await makeRequest(
|
||||
accessToken,
|
||||
HttpMethod.GET,
|
||||
'/ad_accounts'
|
||||
);
|
||||
|
||||
const options: DropdownOption<string>[] = adAccounts.items.map(
|
||||
(account: any) => ({
|
||||
label: account.name,
|
||||
value: account.id,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Error loading ad accounts. Please try again.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const boardSectionIdDropdown = Property.Dropdown({
|
||||
auth: pinterestAuth,
|
||||
displayName: 'Board Section Id',
|
||||
required: false,
|
||||
refreshers: ['auth', 'board_id'],
|
||||
options: async ({ auth, board_id }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
if (!board_id) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a board first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const boardsections = await makeRequest(
|
||||
accessToken,
|
||||
HttpMethod.GET,
|
||||
`/boards/${board_id}/sections`
|
||||
);
|
||||
|
||||
const options: DropdownOption<string>[] = boardsections.items.map(
|
||||
(section: any) => ({
|
||||
label: section.name,
|
||||
value: section.id,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Error loading board sections. Please try again.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const pinIdMultiSelectDropdown = Property.MultiSelectDropdown({
|
||||
auth: pinterestAuth,
|
||||
displayName: 'Product Tags',
|
||||
description: 'Select one or more options',
|
||||
required: false,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
|
||||
const pins = await makeRequest(accessToken, HttpMethod.GET, '/pins');
|
||||
|
||||
const options: DropdownOption<string>[] = pins.items.map((pin: any) => ({
|
||||
label: pin.title,
|
||||
value: pin.id,
|
||||
}));
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Error loading pins. Please try again.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,165 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
HttpMethod,
|
||||
getAccessTokenOrThrow,
|
||||
} from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { adAccountIdDropdown } from '../common/props';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof pinterestAuth>,
|
||||
Record<string, any>
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, propsValue, lastFetchEpochMS }) => {
|
||||
const { ad_account_id, privacy_filter, page_size } = propsValue;
|
||||
let bookmark: string | undefined = undefined;
|
||||
let boards: any[] = [];
|
||||
let pageCount = 0;
|
||||
const maxPages = 10; // Limit to prevent excessive API calls
|
||||
|
||||
do {
|
||||
pageCount++;
|
||||
|
||||
// Build query parameters
|
||||
const searchParams = new URLSearchParams();
|
||||
|
||||
// Add page_size parameter
|
||||
searchParams.append('page_size', (page_size || 25).toString());
|
||||
|
||||
if (bookmark) {
|
||||
searchParams.append('bookmark', bookmark);
|
||||
}
|
||||
if (ad_account_id) {
|
||||
searchParams.append('ad_account_id', ad_account_id);
|
||||
}
|
||||
if (privacy_filter && privacy_filter !== 'ALL') {
|
||||
searchParams.append('privacy', privacy_filter);
|
||||
}
|
||||
|
||||
const queryString = searchParams.toString();
|
||||
const path = `/boards${queryString ? `?${queryString}` : ''}`;
|
||||
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
getAccessTokenOrThrow(auth as OAuth2PropertyValue),
|
||||
HttpMethod.GET,
|
||||
path
|
||||
);
|
||||
|
||||
const items = response.items || [];
|
||||
boards = boards.concat(items);
|
||||
bookmark = response.bookmark;
|
||||
|
||||
// Break early if we've found items older than last fetch
|
||||
if (lastFetchEpochMS && items.length > 0) {
|
||||
const hasNew = items.some(
|
||||
(item: any) => dayjs(item.created_at).valueOf() > lastFetchEpochMS
|
||||
);
|
||||
if (!hasNew) break;
|
||||
}
|
||||
|
||||
// Rate limiting awareness
|
||||
if (bookmark && pageCount < maxPages) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching boards:', error);
|
||||
break;
|
||||
}
|
||||
} while (bookmark && pageCount < maxPages);
|
||||
|
||||
// Filter by timestamp if this isn't the first run
|
||||
if (lastFetchEpochMS) {
|
||||
boards = boards.filter(
|
||||
(item: any) => dayjs(item.created_at).valueOf() > lastFetchEpochMS
|
||||
);
|
||||
}
|
||||
|
||||
return boards.map((item) => ({
|
||||
epochMilliSeconds: dayjs(item.created_at).valueOf(),
|
||||
data: item,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newBoard = createTrigger({
|
||||
auth: pinterestAuth,
|
||||
name: 'newBoard',
|
||||
displayName: 'New Board',
|
||||
description: 'Fires when a new board is created in the account.',
|
||||
props: {
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
privacy_filter: Property.StaticDropdown({
|
||||
displayName: 'Board Privacy Filter',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'All Boards', value: 'ALL' },
|
||||
{ label: 'Public Only', value: 'PUBLIC' },
|
||||
{ label: 'Protected Only', value: 'PROTECTED' },
|
||||
{ label: 'Secret Only', value: 'SECRET' },
|
||||
{ label: 'Public and Secret', value: 'PUBLIC_AND_SECRET' },
|
||||
],
|
||||
},
|
||||
description: 'Filter boards by privacy setting (optional).',
|
||||
}),
|
||||
page_size: Property.Number({
|
||||
displayName: 'Page Size',
|
||||
required: false,
|
||||
description: 'Number of boards to fetch per page (1-250, default: 25).',
|
||||
}),
|
||||
},
|
||||
sampleData: {
|
||||
id: '549755885175',
|
||||
created_at: '2020-01-01T20:10:40-00:00',
|
||||
board_pins_modified_at: '2020-01-01T20:10:40-00:00',
|
||||
name: 'Summer Recipes',
|
||||
description: 'My favorite summer recipes',
|
||||
collaborator_count: 17,
|
||||
pin_count: 5,
|
||||
follower_count: 13,
|
||||
media: {
|
||||
image_cover_url:
|
||||
'https://i.pinimg.com/400x300/fd/cd/d5/fdcdd5a6d8a80824add0d054125cd957.jpg',
|
||||
pin_thumbnail_urls: [
|
||||
'https://i.pinimg.com/150x150/b4/57/10/b45710f1ede96af55230f4b43935c4af.jpg',
|
||||
'https://i.pinimg.com/150x150/dd/ff/46/ddff4616e39c1935cd05738794fa860e.jpg',
|
||||
'https://i.pinimg.com/150x150/84/ac/59/84ac59b670ccb5b903dace480a98930c.jpg',
|
||||
'https://i.pinimg.com/150x150/4c/54/6f/4c546f521be85e30838fb742bfff6936.jpg',
|
||||
],
|
||||
},
|
||||
owner: {
|
||||
username: 'sample_username',
|
||||
},
|
||||
privacy: 'PUBLIC',
|
||||
is_ads_only: false,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onEnable(polling, { store, auth, propsValue });
|
||||
},
|
||||
async onDisable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onDisable(polling, { store, auth, propsValue });
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
PiecePropValueSchema,
|
||||
OAuth2PropertyValue,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
HttpMethod,
|
||||
getAccessTokenOrThrow,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof pinterestAuth>,
|
||||
Record<string, any>
|
||||
> = {
|
||||
strategy: DedupeStrategy.LAST_ITEM,
|
||||
items: async ({ auth }) => {
|
||||
let bookmark: string | undefined = undefined;
|
||||
let followers: any[] = [];
|
||||
let pageCount = 0;
|
||||
const maxPages = 20; // Limit to prevent excessive API calls
|
||||
|
||||
do {
|
||||
pageCount++;
|
||||
|
||||
// Build query parameters
|
||||
const searchParams = new URLSearchParams();
|
||||
if (bookmark) {
|
||||
searchParams.append('bookmark', bookmark);
|
||||
}
|
||||
|
||||
const queryString = searchParams.toString();
|
||||
const path = `/user_account/followers${
|
||||
queryString ? `?${queryString}` : ''
|
||||
}`;
|
||||
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
getAccessTokenOrThrow(auth as OAuth2PropertyValue),
|
||||
HttpMethod.GET,
|
||||
path
|
||||
);
|
||||
|
||||
const items = response.items || [];
|
||||
followers = followers.concat(items);
|
||||
bookmark = response.bookmark;
|
||||
|
||||
// Rate limiting awareness - add delay between requests
|
||||
if (bookmark && pageCount < maxPages) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching followers:', error);
|
||||
break;
|
||||
}
|
||||
} while (bookmark && pageCount < maxPages);
|
||||
|
||||
// Return items with username as identifier
|
||||
return followers.map((item) => ({
|
||||
id: item.username,
|
||||
data: item,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newFollower = createTrigger({
|
||||
auth: pinterestAuth,
|
||||
name: 'newFollower',
|
||||
displayName: 'New Follower',
|
||||
description: 'Triggers when a user gains a new follower.',
|
||||
props: {},
|
||||
sampleData: {
|
||||
username: 'sample_username',
|
||||
type: 'user',
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onEnable(polling, { store, auth, propsValue });
|
||||
},
|
||||
async onDisable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onDisable(polling, { store, auth, propsValue });
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,223 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
OAuth2PropertyValue,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
HttpMethod,
|
||||
getAccessTokenOrThrow,
|
||||
} from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
import { makeRequest } from '../common';
|
||||
import { pinterestAuth } from '../common/auth';
|
||||
import { adAccountIdDropdown, boardIdDropdown } from '../common/props';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof pinterestAuth>,
|
||||
Record<string, any>
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ propsValue, auth, lastFetchEpochMS }) => {
|
||||
const { board_id, ad_account_id, creative_types } = propsValue;
|
||||
let bookmark: string | undefined = undefined;
|
||||
let pins: any[] = [];
|
||||
let pageCount = 0;
|
||||
const maxPages = 10; // Limit to prevent excessive API calls
|
||||
const initialPageSize = 25; // Smaller initial page size for faster response
|
||||
|
||||
do {
|
||||
pageCount++;
|
||||
// Build query parameters
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append('page_size', initialPageSize.toString());
|
||||
if (bookmark) {
|
||||
searchParams.append('bookmark', bookmark);
|
||||
}
|
||||
|
||||
if (ad_account_id) {
|
||||
searchParams.append('ad_account_id', ad_account_id);
|
||||
}
|
||||
|
||||
// Add creative_types filter if specified
|
||||
if (creative_types && creative_types.length > 0) {
|
||||
creative_types.forEach((type: string) => {
|
||||
searchParams.append('creative_types', type);
|
||||
});
|
||||
}
|
||||
|
||||
const queryString = searchParams.toString();
|
||||
const path = `/boards/${board_id}/pins${
|
||||
queryString ? `?${queryString}` : ''
|
||||
}`;
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
getAccessTokenOrThrow(auth as OAuth2PropertyValue),
|
||||
HttpMethod.GET,
|
||||
path
|
||||
);
|
||||
const items = response.items || [];
|
||||
bookmark = response.bookmark;
|
||||
|
||||
// If this is not the first run, filter items by timestamp immediately
|
||||
if (lastFetchEpochMS) {
|
||||
const newItems = items.filter(
|
||||
(item: any) => dayjs(item.created_at).valueOf() > lastFetchEpochMS
|
||||
);
|
||||
|
||||
pins = pins.concat(newItems);
|
||||
|
||||
// Break early if no new items found in this page
|
||||
if (newItems.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Break early if we found items older than last fetch
|
||||
const hasOldItems = items.some(
|
||||
(item: any) => dayjs(item.created_at).valueOf() <= lastFetchEpochMS
|
||||
);
|
||||
if (hasOldItems) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Rate limiting awareness - add delay between requests
|
||||
if (bookmark && pageCount < maxPages) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100)); // 100ms delay
|
||||
}
|
||||
} else {
|
||||
// First run - collect all items
|
||||
pins = pins.concat(items);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error fetching pins for board ${board_id}:`, error);
|
||||
break; // Stop pagination on error
|
||||
}
|
||||
} while (bookmark);
|
||||
|
||||
// Sort by creation date (newest first) for consistent ordering
|
||||
pins.sort(
|
||||
(a, b) => dayjs(b.created_at).valueOf() - dayjs(a.created_at).valueOf()
|
||||
);
|
||||
|
||||
return pins.map((item) => ({
|
||||
epochMilliSeconds: dayjs(item.created_at).valueOf(),
|
||||
data: item,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newPinOnBoard = createTrigger({
|
||||
auth: pinterestAuth,
|
||||
name: 'newPinOnBoard',
|
||||
displayName: 'New Pin on Board',
|
||||
description: 'Fires when a new Pin is added to a specific board.',
|
||||
props: {
|
||||
board_id: boardIdDropdown,
|
||||
ad_account_id: adAccountIdDropdown,
|
||||
creative_types: Property.StaticMultiSelectDropdown({
|
||||
displayName: 'Pin Types to Watch',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Regular Pins', value: 'REGULAR' },
|
||||
{ label: 'Video Pins', value: 'VIDEO' },
|
||||
{ label: 'Shopping Pins', value: 'SHOPPING' },
|
||||
{ label: 'Carousel Pins', value: 'CAROUSEL' },
|
||||
{ label: 'Idea Pins', value: 'IDEA' },
|
||||
],
|
||||
},
|
||||
description:
|
||||
'Filter by specific pin types. Leave empty to watch all types.',
|
||||
}),
|
||||
},
|
||||
sampleData: {
|
||||
items: [
|
||||
{
|
||||
id: '813744226420795884',
|
||||
created_at: '2020-01-01T20:10:40-00:00',
|
||||
link: 'https://www.pinterest.com/',
|
||||
title: 'string',
|
||||
description: 'string',
|
||||
dominant_color: '#6E7874',
|
||||
alt_text: 'string',
|
||||
creative_type: 'REGULAR',
|
||||
board_id: 'string',
|
||||
board_section_id: 'string',
|
||||
board_owner: {
|
||||
username: 'string',
|
||||
},
|
||||
is_owner: 'false',
|
||||
media: {
|
||||
media_type: 'string',
|
||||
images: {
|
||||
'150x150': {
|
||||
width: 150,
|
||||
height: 150,
|
||||
url: 'https://i.pinimg.com/150x150/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
|
||||
},
|
||||
'400x300': {
|
||||
width: 400,
|
||||
height: 300,
|
||||
url: 'https://i.pinimg.com/400x300/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
|
||||
},
|
||||
'600x': {
|
||||
width: 600,
|
||||
height: 600,
|
||||
url: 'https://i.pinimg.com/600x/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
|
||||
},
|
||||
'1200x': {
|
||||
width: 1200,
|
||||
height: 1200,
|
||||
url: 'https://i.pinimg.com/1200x/0d/f6/f1/0df6f1f0bfe7aaca849c1bbc3607a34b.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
parent_pin_id: 'string',
|
||||
is_standard: 'false',
|
||||
has_been_promoted: 'false',
|
||||
product_tags: [
|
||||
{
|
||||
pin_id: '903972677830',
|
||||
},
|
||||
],
|
||||
note: 'string',
|
||||
pin_metrics: {
|
||||
'90d': {
|
||||
pin_click: 7,
|
||||
impression: 2,
|
||||
clickthrough: 3,
|
||||
},
|
||||
lifetime_metrics: {
|
||||
pin_click: 7,
|
||||
impression: 2,
|
||||
clickthrough: 3,
|
||||
reaction: 10,
|
||||
comment: 2,
|
||||
},
|
||||
},
|
||||
is_removable: true,
|
||||
},
|
||||
],
|
||||
bookmark: 'string',
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onEnable(polling, { store, auth, propsValue });
|
||||
},
|
||||
async onDisable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onDisable(polling, { store, auth, propsValue });
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user