diff --git a/packages/backend/src/apps/wordpress/assets/favicon.svg b/packages/backend/src/apps/wordpress/assets/favicon.svg
new file mode 100644
index 00000000..39be6e12
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/assets/favicon.svg
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/packages/backend/src/apps/wordpress/auth/generate-auth-url.ts b/packages/backend/src/apps/wordpress/auth/generate-auth-url.ts
new file mode 100644
index 00000000..ef4e0b84
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/auth/generate-auth-url.ts
@@ -0,0 +1,24 @@
+import { URL, URLSearchParams } from 'node:url';
+import { IGlobalVariable } from '@automatisch/types';
+
+import appConfig from '../../../config/app';
+import getInstanceUrl from '../common/get-instance-url';
+
+export default async function generateAuthUrl($: IGlobalVariable) {
+ const successUrl = new URL(
+ '/app/wordpress/connections/add',
+ appConfig.webAppUrl
+ ).toString();
+ const baseUrl = getInstanceUrl($);
+
+ const searchParams = new URLSearchParams({
+ app_name: 'automatisch',
+ success_url: successUrl,
+ });
+
+ const url = new URL(`/wp-admin/authorize-application.php?${searchParams}`, baseUrl).toString();
+
+ await $.auth.set({
+ url,
+ });
+}
diff --git a/packages/backend/src/apps/wordpress/auth/index.ts b/packages/backend/src/apps/wordpress/auth/index.ts
new file mode 100644
index 00000000..e4883f11
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/auth/index.ts
@@ -0,0 +1,24 @@
+import generateAuthUrl from './generate-auth-url';
+import isStillVerified from './is-still-verified';
+import verifyCredentials from './verify-credentials';
+
+export default {
+ fields: [
+ {
+ key: 'instanceUrl',
+ label: 'WordPress instance URL',
+ type: 'string' as const,
+ required: false,
+ readOnly: false,
+ value: null,
+ placeholder: null,
+ description: 'Your WordPress instance URL.',
+ docUrl: 'https://automatisch.io/docs/wordpress#instance-url',
+ clickToCopy: true,
+ },
+ ],
+
+ generateAuthUrl,
+ isStillVerified,
+ verifyCredentials,
+};
diff --git a/packages/backend/src/apps/wordpress/auth/is-still-verified.ts b/packages/backend/src/apps/wordpress/auth/is-still-verified.ts
new file mode 100644
index 00000000..9cc179ed
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/auth/is-still-verified.ts
@@ -0,0 +1,9 @@
+import { IGlobalVariable } from '@automatisch/types';
+
+const isStillVerified = async ($: IGlobalVariable) => {
+ await $.http.get('?rest_route=/wp/v2/settings');
+
+ return true;
+};
+
+export default isStillVerified;
diff --git a/packages/backend/src/apps/wordpress/auth/verify-credentials.ts b/packages/backend/src/apps/wordpress/auth/verify-credentials.ts
new file mode 100644
index 00000000..0c9f4f73
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/auth/verify-credentials.ts
@@ -0,0 +1,24 @@
+import { IGlobalVariable } from '@automatisch/types';
+
+const verifyCredentials = async ($: IGlobalVariable) => {
+ const instanceUrl = $.auth.data.instanceUrl as string;
+ const password = $.auth.data.password as string;
+ const siteUrl = $.auth.data.site_url as string;
+ const url = $.auth.data.url as string;
+ const userLogin = $.auth.data.user_login as string;
+
+ if (!password) {
+ throw new Error('Failed while authorizing!');
+ }
+
+ await $.auth.set({
+ screenName: `${userLogin} @ ${siteUrl}`,
+ instanceUrl,
+ password,
+ siteUrl,
+ url,
+ userLogin,
+ });
+};
+
+export default verifyCredentials;
diff --git a/packages/backend/src/apps/wordpress/common/add-auth-header.ts b/packages/backend/src/apps/wordpress/common/add-auth-header.ts
new file mode 100644
index 00000000..af5f1237
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/common/add-auth-header.ts
@@ -0,0 +1,17 @@
+import { TBeforeRequest } from '@automatisch/types';
+
+const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
+ const userLogin = $.auth.data.userLogin as string;
+ const password = $.auth.data.password as string;
+
+ if (userLogin && password) {
+ requestConfig.auth = {
+ username: userLogin,
+ password,
+ };
+ }
+
+ return requestConfig;
+};
+
+export default addAuthHeader;
diff --git a/packages/backend/src/apps/wordpress/common/get-instance-url.ts b/packages/backend/src/apps/wordpress/common/get-instance-url.ts
new file mode 100644
index 00000000..72b9bc73
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/common/get-instance-url.ts
@@ -0,0 +1,7 @@
+import { IGlobalVariable } from '@automatisch/types';
+
+const getInstanceUrl = ($: IGlobalVariable): string => {
+ return $.auth.data.instanceUrl as string;
+};
+
+export default getInstanceUrl;
diff --git a/packages/backend/src/apps/wordpress/common/set-base-url.ts b/packages/backend/src/apps/wordpress/common/set-base-url.ts
new file mode 100644
index 00000000..f02c49e9
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/common/set-base-url.ts
@@ -0,0 +1,12 @@
+import { TBeforeRequest } from '@automatisch/types';
+
+const setBaseUrl: TBeforeRequest = ($, requestConfig) => {
+ const instanceUrl = $.auth.data.instanceUrl as string;
+ if (instanceUrl) {
+ requestConfig.baseURL = instanceUrl;
+ }
+
+ return requestConfig;
+};
+
+export default setBaseUrl;
diff --git a/packages/backend/src/apps/wordpress/dynamic-data/index.ts b/packages/backend/src/apps/wordpress/dynamic-data/index.ts
new file mode 100644
index 00000000..640a00f3
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/dynamic-data/index.ts
@@ -0,0 +1,3 @@
+import listStatuses from './list-statuses';
+
+export default [listStatuses];
diff --git a/packages/backend/src/apps/wordpress/dynamic-data/list-statuses/index.ts b/packages/backend/src/apps/wordpress/dynamic-data/list-statuses/index.ts
new file mode 100644
index 00000000..0a6af758
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/dynamic-data/list-statuses/index.ts
@@ -0,0 +1,37 @@
+import { IGlobalVariable, IJSONObject } from '@automatisch/types';
+
+type Status = {
+ slug: string;
+ name: string;
+}
+type Statuses = Record;
+
+export default {
+ name: 'List statuses',
+ key: 'listStatuses',
+
+ async run($: IGlobalVariable) {
+ const statuses: {
+ data: IJSONObject[];
+ } = {
+ data: [],
+ };
+
+ const { data } = await $.http.get('?rest_route=/wp/v2/statuses');
+
+ if (!data) return statuses;
+
+ const values = Object.values(data);
+
+ if (!values?.length) return statuses;
+
+ for (const status of values) {
+ statuses.data.push({
+ value: status.slug,
+ name: status.name,
+ })
+ }
+
+ return statuses;
+ },
+};
diff --git a/packages/backend/src/apps/wordpress/index.d.ts b/packages/backend/src/apps/wordpress/index.d.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/backend/src/apps/wordpress/index.ts b/packages/backend/src/apps/wordpress/index.ts
new file mode 100644
index 00000000..521f7e93
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/index.ts
@@ -0,0 +1,21 @@
+import defineApp from '../../helpers/define-app';
+import addAuthHeader from './common/add-auth-header';
+import setBaseUrl from './common/set-base-url';
+import auth from './auth';
+import triggers from './triggers';
+import dynamicData from './dynamic-data';
+
+export default defineApp({
+ name: 'WordPress',
+ key: 'wordpress',
+ iconUrl: '{BASE_URL}/apps/wordpress/assets/favicon.svg',
+ authDocUrl: 'https://automatisch.io/docs/apps/wordpress/connection',
+ supportsConnections: true,
+ baseUrl: 'https://wordpress.com',
+ apiBaseUrl: '',
+ primaryColor: '464342',
+ beforeRequest: [setBaseUrl, addAuthHeader],
+ auth,
+ triggers,
+ dynamicData,
+});
diff --git a/packages/backend/src/apps/wordpress/triggers/index.ts b/packages/backend/src/apps/wordpress/triggers/index.ts
new file mode 100644
index 00000000..7d0bbda4
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/triggers/index.ts
@@ -0,0 +1,3 @@
+import newPost from './new-post';
+
+export default [newPost];
diff --git a/packages/backend/src/apps/wordpress/triggers/new-post/index.ts b/packages/backend/src/apps/wordpress/triggers/new-post/index.ts
new file mode 100644
index 00000000..5d481980
--- /dev/null
+++ b/packages/backend/src/apps/wordpress/triggers/new-post/index.ts
@@ -0,0 +1,60 @@
+import defineTrigger from '../../../../helpers/define-trigger';
+
+export default defineTrigger({
+ name: 'New post',
+ key: 'newPost',
+ description: 'Triggers when a new post is created.',
+ arguments: [
+ {
+ label: 'Status',
+ key: 'status',
+ type: 'dropdown' as const,
+ required: true,
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listStatuses',
+ },
+ ],
+ },
+ },
+ ],
+
+ async run($) {
+ const params = {
+ per_page: 100,
+ page: 1,
+ order: 'desc',
+ orderby: 'date',
+ status: $.step.parameters.status || '',
+ };
+
+ let totalPages = 1;
+ do {
+ const {
+ data,
+ headers
+ } = await $.http.get('?rest_route=/wp/v2/posts', { params });
+
+ params.page = params.page + 1;
+ totalPages = Number(headers['x-wp-totalpages']);
+
+ if (data.length) {
+ for (const post of data) {
+ const dataItem = {
+ raw: post,
+ meta: {
+ internalId: post.id.toString(),
+ },
+ };
+
+ $.pushTriggerItem(dataItem);
+ }
+ }
+ } while (params.page <= totalPages);
+ },
+});
diff --git a/packages/docs/pages/.vitepress/config.js b/packages/docs/pages/.vitepress/config.js
index 7ba17216..20d0b618 100644
--- a/packages/docs/pages/.vitepress/config.js
+++ b/packages/docs/pages/.vitepress/config.js
@@ -337,6 +337,15 @@ export default defineConfig({
{ text: 'Connection', link: '/apps/webhooks/connection' },
],
},
+ {
+ text: 'WordPress',
+ collapsible: true,
+ collapsed: true,
+ items: [
+ { text: 'Triggers', link: '/apps/wordpress/triggers' },
+ { text: 'Connection', link: '/apps/wordpress/connection' },
+ ],
+ },
],
'/': [
{
diff --git a/packages/docs/pages/apps/wordpress/connection.md b/packages/docs/pages/apps/wordpress/connection.md
new file mode 100644
index 00000000..9cce51bb
--- /dev/null
+++ b/packages/docs/pages/apps/wordpress/connection.md
@@ -0,0 +1,9 @@
+# WordPress
+
+:::info
+This page explains the steps you need to follow to set up the WordPress connection in Automatisch. If any of the steps are outdated, please let us know!
+:::
+
+1. Add your WordPress public URL (without any path in the address) in the **WordPress instance URL** field on Automatisch.
+1. Click **Submit** button on Automatisch.
+1. Congrats! Start using your new WordPress connection within the flows.
diff --git a/packages/docs/pages/apps/wordpress/triggers.md b/packages/docs/pages/apps/wordpress/triggers.md
new file mode 100644
index 00000000..a41d54d7
--- /dev/null
+++ b/packages/docs/pages/apps/wordpress/triggers.md
@@ -0,0 +1,12 @@
+---
+favicon: /favicons/wordpress.svg
+items:
+ - name: New post
+ desc: Triggers when a new post is created.
+---
+
+
+
+
diff --git a/packages/docs/pages/guide/available-apps.md b/packages/docs/pages/guide/available-apps.md
index f4568916..35f6e678 100644
--- a/packages/docs/pages/guide/available-apps.md
+++ b/packages/docs/pages/guide/available-apps.md
@@ -35,3 +35,4 @@ Following integrations are currently supported by Automatisch.
- [Twitter](/apps/twitter/triggers)
- [Typeform](/apps/typeform/triggers)
- [Webhooks](/apps/webhooks/triggers)
+- [WordPress](/apps/wordpress/triggers)
diff --git a/packages/docs/pages/public/favicons/wordpress.svg b/packages/docs/pages/public/favicons/wordpress.svg
new file mode 100644
index 00000000..39be6e12
--- /dev/null
+++ b/packages/docs/pages/public/favicons/wordpress.svg
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file