Action

Post to Pika as draft

Posted by bjhess, Last update 25 days ago

UPDATES

25 days ago

  • Avoid duplicate success notifications
  • Refine success notification wording
show all updates...

25 days ago

  • Avoid duplicate success notifications
  • Refine success notification wording

26 days ago

Open Pika Location after successfully saving the draft.

Post the current draft to Pika as a draft using Pika’s Micropub API.

This action provides a quick way to write in Drafts and send posts to your Pika site for later editing and publishing.

Setup

  1. Create an App Token in Pika: Settings → App Tokens
  2. Run this action in Drafts.
  3. When prompted, paste your Pika app token.

Posts are sent to the Pika Micropub endpoint:

https://pika.page/micropub

How it Works

  • The post is always saved as a draft in Pika.
  • If the first line of the draft is a Markdown heading (for example # Title), it becomes the post title.
  • The rest of the draft becomes the post content.
  • Drafts tags are sent to Pika as post tags.
  • Content is sent as Markdown.
  • Pika requires posts to include body content. If the draft only contains a title, the action will display an error.

For the latest documentation about Pika’s integration with Drafts, visit:

https://pika.page/manual/micropub#drafts

Steps

  • script

    // Post to Pika as draft
    //
    // Behavior:
    // - Hardcoded endpoint: https://pika.page/micropub
    // - If first line is a heading (#, ##, ###, etc.), use it as title
    // - Otherwise, send the entire draft as body content
    // - Sends Drafts tags as Micropub categories
    // - Always posts as a draft
    
    const ENDPOINT = "https://pika.page/micropub";
    
    function run() {
      // ----- Credential -----
      let credential = Credential.create(
        "Pika App Token",
        "Enter your Pika app token from Pika → Settings → App tokens."
      );
    
      credential.addPasswordField("token", "Pika App Token");
    
      if (!credential.authorize()) {
        context.cancel("Authorization canceled.");
        return;
      }
    
      const token = credential.getValue("token");
      if (!token) {
        context.fail("Missing Pika app token.");
        return;
      }
    
      // ----- Parse draft into title + body -----
      const raw = draft.content || "";
      const lines = raw.split(/\r?\n/);
    
      let title = null;
      let bodyLines = lines.slice();
    
      if (lines.length > 0) {
        const firstLine = lines[0];
        const headingMatch = firstLine.match(/^#{1,6}\s+(.+?)\s*#*\s*$/);
    
        if (headingMatch) {
          title = headingMatch[1].trim();
          bodyLines = lines.slice(1);
    
          // Remove leading blank lines after heading
          while (bodyLines.length > 0 && bodyLines[0].trim() === "") {
            bodyLines.shift();
          }
        }
      }
    
      const body = bodyLines.join("\n").trim();
    
      // ----- Fail fast if body is blank -----
      if (!body) {
        context.fail("Pika requires a post body. This draft has no content after removing the title.");
        return;
      }
    
      // ----- Build Micropub properties -----
      let properties = {
        content: [body],
        "post-status": ["draft"]
      };
    
      if (title) {
        properties["name"] = [title];
      }
    
      if (draft.tags && draft.tags.length > 0) {
        properties["category"] = draft.tags.slice();
      }
    
      const payload = {
        type: ["h-entry"],
        properties: properties
      };
    
      // ----- HTTP request -----
      let http = HTTP.create();
      http.timeout = 60;
    
      let response = http.request({
        url: ENDPOINT,
        method: "POST",
        encoding: "json",
        data: payload,
        headers: {
          "Authorization": "Bearer " + token,
          "Accept": "application/json"
        }
      });
    
      // ----- Logging -----
      console.log("Pika endpoint: " + ENDPOINT);
      console.log("Payload: " + JSON.stringify(payload));
      console.log("HTTP status: " + response.statusCode);
      console.log("Success: " + response.success);
      console.log("Error: " + response.error);
      console.log("Response text: " + response.responseText);
    
      try {
        console.log("Response data: " + JSON.stringify(response.responseData));
      } catch (e) {
        console.log("Response data could not be stringified.");
      }
    
      // ----- Result handling -----
      if (response.statusCode !== 201) {
        context.fail("Micropub request failed: HTTP " + response.statusCode);
        return;
      }
    
      let location = "";
      try {
        if (response.headers) {
          location =
            response.headers["Location"] ||
            response.headers["location"] ||
            "";
        }
      } catch (e) {}
    
      console.log("Response headers: " + JSON.stringify(response.headers));
      console.log("Location header: " + location);
    
      if (location) {
        app.displaySuccessMessage("Saved to Pika as draft.");
        let opened = app.openURL(location);
        console.log("openURL result: " + opened);
      } else {
        app.displaySuccessMessage("Saved to Pika as draft.");
      }
    }
    
    run();

Options

  • After Success Default
    Notification None
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.