How to Write a Code to Push a Post and its Associated Comments to a Target Wordpress Site Using the Wordpress REST API?

This topic was automatically generated from Slack. You can find the original thread here.

Good morning. Hope all is well.

Recently, I figured out how to use the Wordpress REST API to pull a post from one site. The name of my step is called code_pull. Here is the code:

import { axios } from "@pipedream/platform";

export default {
  props: {
    sourceSiteUrl: {
      type: "string",
      label: "Source Site URL",
      description: "The URL of the Wordpress site you want to pull posts from",
    },
    sourceSiteUsername: {
      type: "string",
      label: "Source Site Username",
      description: "The username for the source Wordpress site",
    },
    sourceSitePassword: {
      type: "string",
      label: "Source Site Password",
      description: "The password for the source Wordpress site",
    },
    postId: {
      type: "integer",
      label: "Post ID",
      description: "The ID of the post you want to pull from the source site",
    },
  },
  async run({ $ }) {
    const postResponse = await axios($, {
      method: "GET",
      url: `${this.sourceSiteUrl}/wp-json/wp/v2/posts/${this.postId}?context=edit`,
      auth: {
        username: this.sourceSiteUsername,
        password: this.sourceSitePassword,
      },
    });

    const commentsResponse = await axios($, {
      method: "GET",
      url: `${this.sourceSiteUrl}/wp-json/wp/v2/comments`,
      params: {
        post: this.postId,
      },
      auth: {
        username: this.sourceSiteUsername,
        password: this.sourceSitePassword,
      },
    });

    return {
      post: postResponse,
      comments: commentsResponse,
    };
  },
};

Are you can see it was modified to fetch the post data with the raw post_content field and the associated comments.

I would like you to write me a code that will request the target site URL, target site Username and target site Password.

The goal is to push the object into the other Wordpress using the raw post_content that contains the associated comments.

Sure, I can help you with that. Here’s a Pipedream component that takes the target site URL, username, and password as inputs, and pushes the post and associated comments to the target Wordpress site. This code assumes that the post and comments data are available from the previous step code_pull. import { axios } from "@pipedream/platform"; export default defineComponent({ props: { targetSiteUrl: { type: "string", label: "Target Site URL", description: "The URL of the Wordpress site you want to push posts to", }, targetSiteUsername: { type: "string", label: "Target Site Username", description: "The username for the target Wordpress site", }, targetSitePassword: { type: "string", label: "Target Site Password", description: "The password for the target Wordpress site", }, }, async run({ steps, $ }) { const post = [steps.code_pull.post](http://steps.code_pull.post); const comments = steps.code_pull.comments; // Push the post to the target site const postResponse = await axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`, auth: { username: this.targetSiteUsername, password: this.targetSitePassword, }, data: post, }); // Push the comments to the target site const commentsResponses = await Promise.all( comments.map((comment) => axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`, auth: { username: this.targetSiteUsername, password: this.targetSitePassword, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, }); This code will make a POST request to the target Wordpress site for each comment associated with the post. The responses from these requests are returned in an array. Please replace code_pull with the actual name of your previous step if it’s different.

I need to make a change to this code. I need to authentic when I use POST and I have an API Password.

import { axios } from "@pipedream/platform";

export default defineComponent({
  props: {
    targetSiteUrl: {
      type: "string",
      label: "Target Site URL",
      description: "The URL of the Wordpress site you want to push posts to",
    },
    targetSiteUsername: {
      type: "string",
      label: "Target Site Username",
      description: "The username for the target Wordpress site",
    },
    targetSitePassword: {
      type: "string",
      label: "Target Site Password",
      description: "The password for the target Wordpress site",
    },
  },
  async run({ steps, $ }) {
    const post = [steps.code_pull.post](http://steps.code_pull.post);
    const comments = steps.code_pull.comments;

    // Push the post to the target site
    const postResponse = await axios($, {
      method: "POST",
      url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`,
      auth: {
        username: this.targetSiteUsername,
        password: this.targetSitePassword,
      },
      data: post,
    });

    // Push the comments to the target site
    const commentsResponses = await Promise.all(
      comments.map((comment) =>
        axios($, {
          method: "POST",
          url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`,
          auth: {
            username: this.targetSiteUsername,
            password: this.targetSitePassword,
          },
          data: comment,
        })
      )
    );

    return {
      postResponse,
      commentsResponses,
    };
  },
});

Sure, if you need to authenticate using an API password, you can modify the auth object in your axios request. Here’s how you can modify your code: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { targetSiteUrl: { type: "string", label: "Target Site URL", description: "The URL of the Wordpress site you want to push posts to", }, targetSiteUsername: { type: "string", label: "Target Site Username", description: "The username for the target Wordpress site", }, apiPassword: { type: "string", label: "API Password", description: "The API password for the target Wordpress site", }, }, async run({ steps, $ }) { const post = [steps.code_pull.post](http://steps.code_pull.post); const comments = steps.code_pull.comments; // Push the post to the target site const postResponse = await axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`, headers: { 'Authorization': `Basic ${Buffer.from(`${this.targetSiteUsername}:${this.apiPassword}`).toString('base64')}`, }, data: post, }); // Push the comments to the target site const commentsResponses = await Promise.all( comments.map((comment) => axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`, headers: { 'Authorization': `Basic ${Buffer.from(`${this.targetSiteUsername}:${this.apiPassword}`).toString('base64')}`, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, }); In this code, I’ve replaced targetSitePassword with apiPassword and used it to create a Basic Authentication header. This header is created by base64 encoding the username and password separated by a colon. Please replace code_pull with the actual name of your previous step if it’s different.

I am having a problem. You wrote me TWO codes. One code allows me to access my Wordpress PEST API via POST, the other one doesn’t. Can you compare the two codes and fix them.

THIS CODE DOES NOT WORK:

import { axios } from "@pipedream/platform";

export default defineComponent({
  props: {
    targetSiteUrl: {
      type: "string",
      label: "Target Site URL",
      description: "The URL of the Wordpress site you want to push posts to",
    },
    targetSiteUsername: {
      type: "string",
      label: "Target Site Username",
      description: "The username for the target Wordpress site",
    },
    targetSitePassword: {
      type: "string",
      label: "Target Site Password",
      description: "The password for the target Wordpress site",
    },
  },
  async run({ steps, $ }) {
    const post = [steps.code_pull.post](http://steps.code_pull.post);
    const comments = steps.code_pull.comments;

    // Push the post to the target site
    const postResponse = await axios($, {
      method: "POST",
      url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`,
      auth: {
        username: this.targetSiteUsername,
        password: this.targetSitePassword,
      },
      data: post,
    });

    // Push the comments to the target site
    const commentsResponses = await Promise.all(
      comments.map((comment) =>
        axios($, {
          method: "POST",
          url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`,
          auth: {
            username: this.targetSiteUsername,
            password: this.targetSitePassword,
          },
          data: comment,
        })
      )
    );

    return {
      postResponse,
      commentsResponses,
    };
  },
});

This code does work:

import { axios } from "@pipedream/platform";

export default defineComponent({
  props: {
    targetUrl: {
      type: "string",
      label: "Target URL",
      description: "The URL of your WordPress REST API endpoint",
    },
    username: {
      type: "string",
      label: "Username",
      description: "The username for your WordPress site",
    },
    password: {
      type: "string",
      label: "Password",
      description: "The password for your WordPress site",
    },
  },
  async run({ $ }) {
    const auth = {
      username: this.username,
      password: this.password,
    };

    const response = await axios($, {
      method: "POST",
      url: this.targetUrl,
      auth: auth,
    });

    return response;
  },
});

Essentially, I created a step called code_pull, which is an object which just pull data from one Wordpress Site and now I want to push that data into another Wordpress Site.

I see that you’re trying to push data from one WordPress site to another using Pipedream. Let’s compare the two pieces of code you’ve provided to identify the issue. The first piece of code that doesn’t work seems to have an issue with how you’re trying to access the data from the code_pull step. This line seems to be incorrect: const post = [steps.code_pull.post](http://steps.code_pull.post); It appears you’re trying to use some sort of link markdown syntax, which is not valid in JavaScript. Instead, you should be accessing the data from the code_pull step like this: const post = [steps.code_pull.post](http://steps.code_pull.post); The same correction should be applied to the comments line: const comments = steps.code_pull.comments; Here’s the corrected version of your first code: ``` import { axios } from “@pipedream/platform”; export default defineComponent({ props: { targetSiteUrl: { type: “string”, label: “Target Site URL”, description: “The URL of the Wordpress site you want to push posts to”, }, targetSiteUsername: { type: “string”, label: “Target Site Username”, description: “The username for the target Wordpress site”, }, targetSitePassword: { type: “string”, label: “Target Site Password”, description: “The password for the target Wordpress site”, }, }, async run({ steps, $ }) { const post = steps.code_pull.post; const comments = steps.code_pull.comments; // Push the post to the target site const postResponse = await axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/posts, auth: { username: this.targetSiteUsername, password: this.targetSitePassword, }, data: post, }); // Push the comments to the target site const commentsResponses = await Promise.all( comments.map((comment) => axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/comments, auth: { username: this.targetSiteUsername, password: this.targetSitePassword, }, data: comment, }) ) );

It seems the code was cut off.

I apologize for the confusion earlier. It seems there was an issue with the formatting of the code. Here’s the corrected version of your first code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { targetSiteUrl: { type: “string”, label: “Target Site URL”, description: “The URL of the Wordpress site you want to push posts to”, }, targetSiteUsername: { type: “string”, label: “Target Site Username”, description: “The username for the target Wordpress site”, }, targetSitePassword: { type: “string”, label: “Target Site Password”, description: “The password for the target Wordpress site”, }, }, async run({ steps, $ }) { const post = steps.code_pull.post; const comments = steps.code_pull.comments; // Push the post to the target site const postResponse = await axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/posts, auth: { username: this.targetSiteUsername, password: this.targetSitePassword, }, data: post, }); // Push the comments to the target site const commentsResponses = await Promise.all( comments.map((comment) => axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/comments, auth: { username: this.targetSiteUsername, password: this.targetSitePassword, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, });

I am getting the following error:

I’m sorry, but I can’t see the error you’re referring to. Could you please provide more details or describe the error you’re encountering? This will help me assist you better.

I am getting the following error:

Error - Request failed with status code 401
{"status":"error","error":"MISSING_AUTHORIZATION_HEADER","code":"401","error_description":"Authorization header not received. Either authorization header was not sent or it was removed by your server due to security reasons."}

This is the code:

import { axios } from "@pipedream/platform";

export default defineComponent({
  props: {
    targetSiteUrl: {
      type: "string",
      label: "Target Site URL",
      description: "The URL of the Wordpress site you want to push posts to",
    },
    targetSiteUsername: {
      type: "string",
      label: "Target Site Username",
      description: "The username for the target Wordpress site",
    },
    targetSitePassword: {
      type: "string",
      label: "Target Site Password",
      description: "The password for the target Wordpress site",
    },
  },
  async run({ steps, $ }) {
    const post = [steps.code_pull.post](http://steps.code_pull.post);
    const comments = steps.code_pull.comments;

    // Push the post to the target site
    const postResponse = await axios($, {
      method: "POST",
      url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`,
      auth: {
        username: this.targetSiteUsername,
        password: this.targetSitePassword,
      },
      data: post,
    });

    // Push the comments to the target site
    const commentsResponses = await Promise.all(
      comments.map((comment) =>
        axios($, {
          method: "POST",
          url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`,
          auth: {
            username: this.targetSiteUsername,
            password: this.targetSitePassword,
          },
          data: comment,
        })
      )
    );

    return {
      postResponse,
      commentsResponses,
    };
  },
});

I know for certain that my targetSiteUsername and targetSitePassword works for posting.

I’m sorry to hear that you’re having trouble with authorization. The error message indicates that the server did not receive an Authorization header, which is needed for the server to authenticate your request. In your code, you’re using the auth option in the axios configuration to provide your username and password. This should automatically create a Basic Auth header. However, it seems like the server is not receiving it. One possible issue could be that the server does not support Basic Auth or expects a different authentication method. You might need to use a Bearer token or a custom Authorization header. If you’re sure that the server supports Basic Auth, you could try manually creating the Authorization header. Here’s how you can do it: ```
import { axios } from “@pipedream/platform”; import { Buffer } from ‘buffer’; export default defineComponent({ props: { // … your props here … }, async run({ steps, $ }) { const auth = Buffer.from(${this.targetSiteUsername}:${this.targetSitePassword}).toString(‘base64’); // Push the post to the target site const postResponse = await axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/posts, headers: { Authorization: Basic ${auth}, }, data: post, }); // Push the comments to the target site const commentsResponses = await Promise.all( comments.map((comment) => axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/comments, headers: { Authorization: Basic ${auth}, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, });

I think the code you provided will work.

It gave an error:

ReferenceError
post is not defined

Here is the code:

import { axios } from "@pipedream/platform";
import { Buffer } from 'buffer';

export default defineComponent({
  props: {
    targetSiteUrl: {
      type: "string",
      label: "Target Site URL",
      description: "The URL of the Wordpress site you want to push posts to",
    },
    targetSiteUsername: {
      type: "string",
      label: "Target Site Username",
      description: "The username for the target Wordpress site",
    },
    targetSitePassword: {
      type: "string",
      label: "Target Site Password",
      description: "The password for the target Wordpress site",
    },
  },
  async run({ steps, $ }) {
    const auth = Buffer.from(`${this.targetSiteUsername}:${this.targetSitePassword}`).toString('base64');

    // Push the post to the target site
    const postResponse = await axios($, {
      method: "POST",
      url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`,
      headers: {
        Authorization: `Basic ${auth}`,
      },
      data: post,
    });

    // Push the comments to the target site
    const commentsResponses = await Promise.all(
      comments.map((comment) =>
        axios($, {
          method: "POST",
          url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`,
          headers: {
            Authorization: `Basic ${auth}`,
          },
          data: comment,
        })
      )
    );

    return {
      postResponse,
      commentsResponses,
    };
  },
});

I see that you’re getting a ReferenceError because post and comments are not defined. These variables seem to represent the post data and comments data that you want to send to the target site. You should add these as props to your component so that you can pass them in when you run the component. Here’s how you can do it: import { axios } from "@pipedream/platform"; import { Buffer } from 'buffer'; export default defineComponent({ props: { targetSiteUrl: { type: "string", label: "Target Site URL", description: "The URL of the Wordpress site you want to push posts to", }, targetSiteUsername: { type: "string", label: "Target Site Username", description: "The username for the target Wordpress site", }, targetSitePassword: { type: "string", label: "Target Site Password", description: "The password for the target Wordpress site", }, post: { type: "object", label: "Post Data", description: "The data for the post you want to push to the target site", }, comments: { type: "object[]", label: "Comments Data", description: "The data for the comments you want to push to the target site", }, }, async run({ steps, $ }) { const auth = Buffer.from(`${this.targetSiteUsername}:${this.targetSitePassword}`).toString('base64'); // Push the post to the target site const postResponse = await axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`, headers: { Authorization: `Basic ${auth}`, }, data: [this.post](http://this.post), }); // Push the comments to the target site const commentsResponses = await Promise.all( this.comments.map((comment) => axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`, headers: { Authorization: `Basic ${auth}`, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, }); This code adds post and comments as props to your component. You can now

Two things.

  1. The message was cut off.
  2. The following message came up.
Code Error
unsupported array element type for prop comments: object

I apologize for the confusion earlier. The error message you’re seeing is due to the fact that Pipedream currently does not support array of objects as a prop type. To work around this, you can change the type of comments prop to string[] and then parse each string as a JSON object in your code. Here’s how you can modify your code: ``` import { axios } from “@pipedream/platform”; import { Buffer } from ‘buffer’; export default defineComponent({ props: { targetSiteUrl: { type: “string”, label: “Target Site URL”, description: “The URL of the Wordpress site you want to push posts to”, }, targetSiteUsername: { type: “string”, label: “Target Site Username”, description: “The username for the target Wordpress site”, }, targetSitePassword: { type: “string”, label: “Target Site Password”, description: “The password for the target Wordpress site”, }, post: { type: “object”, label: “Post Data”, description: “The data for the post you want to push to the target site”, }, comments: { type: “string[]”, label: “Comments Data”, description: “The data for the comments you want to push to the target site”, }, }, async run({ steps, $ }) { const auth = Buffer.from(${this.targetSiteUsername}:${this.targetSitePassword}).toString(‘base64’); // Push the post to the target site const postResponse = await axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/posts, headers: { Authorization: Basic ${auth}, }, data: this.post, }); // Parse comments from JSON const commentsData = this.comments.map(comment => JSON.parse(comment)); // Push the comments to the target site const commentsResponses = await Promise.all( commentsData.map((comment) => axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/comments, headers: { Authorization: Basic ${auth}, }, data: comment, }) ) ); return { postResponse, commentsResponses, };

The code you suggested was cutoff.

I apologize for the previous incomplete response. Here’s the complete code: ```
import { axios } from “@pipedream/platform”; export default defineComponent({ props: { targetSiteUrl: { type: “string”, label: “Target Site URL”, description: “The URL of the Wordpress site you want to push posts to”, }, targetSiteUsername: { type: “string”, label: “Target Site Username”, description: “The username for the target Wordpress site”, }, targetSitePassword: { type: “string”, label: “Target Site Password”, description: “The password for the target Wordpress site”, }, post: { type: “object”, label: “Post Data”, description: “The data for the post you want to push to the target site”, }, comments: { type: “string[]”, label: “Comments Data”, description: “The data for the comments you want to push to the target site”, }, }, async run({ steps, $ }) { const auth = Buffer.from(${this.targetSiteUsername}:${this.targetSitePassword}).toString(‘base64’); // Push the post to the target site const postResponse = await axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/posts, headers: { Authorization: Basic ${auth}, }, data: this.post, }); // Parse comments from JSON const commentsData = this.comments.map(comment => JSON.parse(comment)); // Push the comments to the target site const commentsResponses = await Promise.all( commentsData.map((comment) => axios($, { method: “POST”, url: ${this.targetSiteUrl}/wp-json/wp/v2/comments, headers: { Authorization: Basic ${auth}, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, });

I received the following error:

Error - Request failed with status code 401
{"status":"error","error":"MISSING_AUTHORIZATION_HEADER","code":"401","error_description":"Authorization header not received. Either authorization header was not sent or it was removed by your server due to security reasons."}
DETAILS


steps.code_push{1}
debug{5}
status:
401
statusText:
Unauthorized
headers{15}config{12}data{4}

I’m sorry for the inconvenience. The error message indicates that the Authorization header is missing from your request. This is likely because the username or password for the target Wordpress site is incorrect or not being included correctly in the request. Here’s how you can modify the code to ensure that the Authorization header is being set correctly: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { targetSiteUrl: { type: "string", label: "Target Site URL", description: "The URL of the Wordpress site you want to push posts to", }, targetSiteUsername: { type: "string", label: "Target Site Username", description: "The username for the target Wordpress site", }, targetSitePassword: { type: "string", label: "Target Site Password", description: "The password for the target Wordpress site", }, post: { type: "object", label: "Post Data", description: "The data for the post you want to push to the target site", }, comments: { type: "string[]", label: "Comments Data", description: "The data for the comments you want to push to the target site", }, }, async run({ steps, $ }) { const auth = `Basic ${Buffer.from(`${this.targetSiteUsername}:${this.targetSitePassword}`).toString('base64')}`; // Push the post to the target site const postResponse = await axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/posts`, headers: { Authorization: auth, }, data: [this.post](http://this.post), }); // Parse comments from JSON const commentsData = this.comments.map(comment => JSON.parse(comment)); // Push the comments to the target site const commentsResponses = await Promise.all( commentsData.map((comment) => axios($, { method: "POST", url: `${this.targetSiteUrl}/wp-json/wp/v2/comments`, headers: { Authorization: auth, }, data: comment, }) ) ); return { postResponse, commentsResponses, }; }, }); Please ensure that the targetSiteUsername and targetSitePassword props are set