Chat GPT 이용한 자동 포스팅 구현

워드프레스에서 포스팅을 할 때는 보통 직접 글이나 자료를 통해서 하는 편이 많습니다.

하지만, 간단한 정보글 같은 경우에는 굳이 자료 조사 없이 GPT 통해서 글을 쓸 수 있습니다.

즉, 내용 자체를 통째로 GPT에게 맡기는 것이 가능하다는 거죠.

그럼 이걸 워드프레스 상에서 가능하도록 어떻게 세팅을 하면 될지 살펴보겠습니다.

파이썬 설치 및 VScode 사용 가능하다는 가정 하에 진행하겠습니다. 

로컬에서 파이썬 서버 실행하기

우선은 파이썬 서버를 이용해서 GPT와 워드프레스 API를 연결하는 환경을 만들 겁니다.

FastAPI를 사용하겠습니다.

				
					pip install fastapi uvicorn requests openai python-dotenv


				
			

위와 같은 패키지를 먼저 설치하겠습니다.

이 패키지를 이용해서 포스팅을 자동화할 전체 코드는 다음과 같습니다.

의학과 관련된 전문 포스팅을 한다고 가정해볼까요?

여기에 필요한 정보를 수정하고 발전시킬 겁니다. 

				
					from fastapi import FastAPI
import requests
import openai

app = FastAPI()

# GPT API 키 설정 (OpenAI에서 발급)
GPT_API_KEY = "your-openai-api-key"

# 워드프레스 API 설정
WP_URL = "https://yourwordpress.com/wp-json/wp/v2/posts"
WP_USER = "your_username"
WP_PASSWORD = "your_application_password"

# GPT를 활용한 콘텐츠 생성 함수
def generate_post_content(prompt):
    headers = {"Authorization": f"Bearer {GPT_API_KEY}"}
    data = {
        "model": "gpt-4",
        "messages": [{"role": "system", "content": "You are a helpful assistant for medical research blog."},
                     {"role": "user", "content": prompt}]
    }
    response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=data)
    return response.json()["choices"][0]["message"]["content"]

# 워드프레스 포스팅 함수
def create_wordpress_post(title, content, category_id=1):
    data = {
        "title": title,
        "content": content,
        "status": "publish",
        "categories": [category_id]
    }
    response = requests.post(WP_URL, json=data, auth=(WP_USER, WP_PASSWORD))
    return response.json()

# API 엔드포인트 (GPT로 콘텐츠 생성 & 워드프레스에 자동 업로드)
@app.post("/generate_post/")
def generate_post(pdf_url: str = None, website_url: str = None):
    prompt = "Summarize the key insights from the given source into a blog post format."
    if pdf_url:
        prompt += f" The source is a PDF file: {pdf_url}"
    if website_url:
        prompt += f" The source is a website: {website_url}"

    # GPT로 블로그 글 생성
    content = generate_post_content(prompt)
    title = content.split("\n")[0]  # 첫 번째 줄을 제목으로 사용

    # 워드프레스에 자동 업로드
    response = create_wordpress_post(title, content)
    return {"status": "success", "wordpress_response": response}

				
			

이제 코드를 차근차근 뜯어보겠습니다.

				
					from fastapi import FastAPI
import requests
import openai

app = FastAPI()

# GPT API 키 설정 (OpenAI에서 발급)
GPT_API_KEY = "your-openai-api-key"



				
			

실행을 할 app 에 FastAPI()을 할당합니다.

이후 GPT_API_KEY를 설정할 건데요.

위 버튼으로 이동하고, 

GPT에 로그인을 해줍시다. 

여기서 위와 같은 버튼을 눌러서 API 를 생성 가능합니다.

눌러줍시다.

fig1-4

이름을 지정합시다.

Permissions 는 모두 할당하겠습니다.

이후 Create Secret Key 버튼을 눌러주세요.

fig2-2

생성된 API Key를 Copy 통해서 복사하고 저장하세요.

이제 이 Key를 활용하면 될 겁니다. 

여기서 코드를 조금 변경할 겁니다.

				
					OPENAI_API_KEY=your-new-api-key

				
			

위와 같은 내용을 가진 “.env” 파일을 생성합니다.

생성하는 위치는 server.py 가 존재하는 디렉토리 위치에 그대로 생성하면 됩니다. 

말 그대로 .env 파일입니다. 

위 코드에서 your-new-api-key 여기 부분에 들어갈 것이 방금 생성한 Key입니다.

				
					from fastapi import FastAPI
import requests
import openai
import os
from dotenv import load_dotenv

# .env 파일 로드 (API Key 보호)
load_dotenv()
GPT_API_KEY = os.getenv("OPENAI_API_KEY")

# FastAPI 서버 설정
app = FastAPI()

# ✅ 테스트 엔드포인트 추가
@app.get("/ping")
def ping():
    return {"status": "FastAPI is running!"}
				
			

그럼 이제 앞쪽 코드 부분을 이렇게 변경할 수 있습니다.

안전하게 env 파일에서 값을 가져오는 형태가 되는 거죠.

터미널 창에서 해당 디렉토리로 이동을 하고 다음 명령어를 실행합니다.

				
					uvicorn server:app --reload

				
			

위 명령어를 실행하면, “http://127.0.0.1:8000/ping” 페이지에 뭔가 실행이 됩니다.

 

위와 같이 화면이 나타난다면 성공입니다.

이어서 다음 코드도 작성을 하겠습니다. 

				
					from fastapi import FastAPI
import requests
import openai
import os
from dotenv import load_dotenv

# .env 파일 로드 (API Key 보호)
load_dotenv()
GPT_API_KEY = os.getenv("OPENAI_API_KEY")

# FastAPI 서버 설정
app = FastAPI()

# ✅ 테스트 엔드포인트 (FastAPI 정상 실행 확인용)
@app.get("/ping")
def ping():
    return {"status": "FastAPI is running!"}

# ✅ GPT API를 이용한 블로그 포스트 생성
@app.post("/generate_post/")
def generate_post(pdf_url: str = None, website_url: str = None):
    prompt = "Summarize the key insights from the given source into a blog post format."
    
    if pdf_url:
        prompt += f" The source is a PDF file: {pdf_url}"
    if website_url:
        prompt += f" The source is a website: {website_url}"

    headers = {"Authorization": f"Bearer {GPT_API_KEY}"}
    data = {
        "model": "gpt-4",
        "messages": [{"role": "system", "content": "You are a helpful assistant for medical research blog."},
                     {"role": "user", "content": prompt}]
    }
    
    response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=data)
    gpt_response = response.json()
    
    if "choices" in gpt_response:
        content = gpt_response["choices"][0]["message"]["content"]
        return {"status": "success", "generated_content": content}
    
    return {"status": "error", "message": "Failed to generate content"}

				
			

자 이번에는 이렇게 코드를 추가했습니다.

/generate_post/ 라는 부분이 추가가 되었습니다.

				
					# ✅ GPT API를 이용한 블로그 포스트 생성
@app.post("/generate_post/")
def generate_post(pdf_url: str = None, website_url: str = None):
    prompt = "Summarize the key insights from the given source into a blog post format."
    
    if pdf_url:
        prompt += f" The source is a PDF file: {pdf_url}"
    if website_url:
        prompt += f" The source is a website: {website_url}"

    headers = {"Authorization": f"Bearer {GPT_API_KEY}"}
    data = {
        "model": "gpt-4",
        "messages": [{"role": "system", "content": "You are a helpful assistant for medical research blog."},
                     {"role": "user", "content": prompt}]
    }
    
    response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=data)
    gpt_response = response.json()
    
    if "choices" in gpt_response:
        content = gpt_response["choices"][0]["message"]["content"]
        return {"status": "success", "generated_content": content}
    
    return {"status": "error", "message": "Failed to generate content"}
				
			

이쪽 부분을 자세하게 보겠습니다.

우선 “generate_post” 라는 엔드 포인트로 이동하면 그 내부에 있는 “generate_post” 함수가 작동합니다.

이 함수 내부의 인자는 기본적으로 모두 None으로 설정이 되었습니다.

prompt 라는 값은 GPT에게 사용할 기본적인 명령어입니다. 

pdf_url 이 있는지, website_url 이 있는지에 따라서 prompt에 명령어가 추가가 됩니다. 

이때 전송되는 data 내부에서 messages 안에 있는 데이터들이 어떤 역할을 하는지 보겠습니다.

1️⃣ System Role ("role": "system")

  • GPT가 어떤 방식으로 작동해야 하는지를 정의하는 역할
  • 대화의 방향을 설정하며, 모든 요청에 영향을 미침
  • "system" 메시지는 보통 1개만 포함됨
  • 예제에서는 GPT가 “의학 연구 블로그에 도움을 주는 어시스턴트” 역할을 하도록 설정

2️⃣ User Role ("role": "user")

  • 실제 요청을 보내는 메시지
  • "user" 메시지는 보통 사용자가 입력한 질문이나 명령어
  • 예제에서는 GPT에게 “소스 내용을 블로그 형식으로 요약해줘” 라고 요청

3️⃣ Assistant Role ("role": "assistant", 선택적)

  • 만약 이전 대화가 있다면, 이전 GPT 응답이 "assistant" 역할로 추가됨
  • 현재 예제에는 없지만, 여러 번 API 호출을 할 때 GPT가 이전 응답을 기억하도록 하려면 "assistant" 역할을 추가하면 됨.

GPT를 활용하여 정리했을 때 위와 같습니다. 

				
					
    if "choices" in gpt_response:
        content = gpt_response["choices"][0]["message"]["content"]
        return {"status": "success", "generated_content": content}
    
    return {"status": "error", "message": "Failed to generate content"}
				
			

그리고 결과를 출력하는 과정에서는 choices 라는 값이 gpt_response 내부에 있는지를 따져서 실행이 됩니다.

그것은 gpt 응답 구조에 이유가 있습니다.

예시로 gpt 응답의 구조는 다음과 같습니다.

				
					{
    "id": "chatcmpl-abc123",
    "object": "chat.completion",
    "created": 1709620000,
    "model": "gpt-4",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Here is a summary of the key insights from the given source..."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 50,
        "completion_tokens": 200,
        "total_tokens": 250
    }
}

				
			

gpt 의 응답 결과는 json 구조 내에서 choices 라는 key 값 내부에 있습니다.

때문에 choices가 존재하지 않는다면 답을 불러올 수 없기 때문에 이것을 오류로 처리를 합니다. 

그럼 실제로 이용을 하기 위해 어떠한 명령어를 쓰면 되느냐?

				
					curl -X POST "http://127.0.0.1:8000/generate_post/" \
-H "Content-Type: application/json" \
-d '{"website_url": "https://www.ncbi.nlm.nih.gov/"}'
				
			

위와 같이 작동을 하면 됩니다.

특정 엔드 포인트로 POST 형식으로 데이터를 전송합니다.

이 형식은 json 형식임을  알려줍니다.

특정한 웹 사이트의 url을 알려줍니다.

그럼 이것 통해 prompt 가 작성이 되고… 결과가 나타는데요.

				
					  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Title: Study Finds Link Between Anxiety and Cardiovascular Health\n\nA recent study published in the Journal of Psychosomatic Research has shed light on the relationship between anxiety and cardiovascular health. The study, conducted by a team of researchers from renowned universities, aimed to investigate the impact of anxiety on the heart and blood vessels of individuals.\n\nThe researchers gathered data from a large sample of participants and found a clear correlation between anxiety levels and cardiovascular health. Individuals with high levels of anxiety were more likely to exhibit signs of heart disease and other cardiovascular issues compared to those with lower levels of anxiety.\n\nFurthermore, the study revealed that chronic anxiety could lead to long-term damage to the cardiovascular system, increasing 
the risk of developing conditions such as hypertension, heart attack, and stroke. The findings highlight the importance of addressing mental health concerns, such as anxiety, in order to protect and maintain cardiovascular well-being.\n\nLead researcher Dr. Smith emphasized the need for healthcare providers to consider the psychological well-being of patients when assessing cardiovascular risk factors. By addressing anxiety and providing appropriate interventions, healthcare professionals can potentially improve the overall cardiovascular health outcomes for individuals.\n\nIn conclusion, this study underscores the significant impact of anxiety on cardiovascular health and emphasizes the importance of a holistic approach to patient care. By recognizing and addressing mental health issues, healthcare providers can better support individuals in maintaining a healthy heart and overall well-being.",
        "refusal": null
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ]
				
			

이런 식으로 나타나는 것을 확인했습니다.

이 과정에서 일어날 수 있는 오류는 다음 섹션에 정리하겠습니다.

일어날 수 있는 오류 해결법

				
					OPENAI_API_KEY=your-new-api-key

				
			

보안을 위해 사용했던 .env 파일 내부의 key 값이 있죠?

이때 공백이 여기 들어가면 안 됩니다.

우선 이거 체크해주세요. 

				
					{
    "id": "chatcmpl-abc123",
    "object": "chat.completion",
    "created": 1709620000,
    "model": "gpt-4",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Here is a summary of the key insights from the given source..."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 50,
        "completion_tokens": 200,
        "total_tokens": 250
    }
}

				
			

그리고 이쪽에서 model 이 “gpt-4” 이죠?

이걸 적절한 gpt 모델로 사용해야 할 수도 있습니다.

왜냐하면 돈이 들거든요.

토큰이 있어야지 사용 가능한 모델들이 있어서 결제가 필요할 수 있습니다. 

위 버튼을 통해 결제 페이지로 이동하고 미리 돈을 넣어두면 이용 가능합니다.

제 경우에는 결제해서 토큰 넣어두고 하니까 쉽게 되더군요.

워드프레스 포스팅 자동화

포스팅의 핵심입니다.

GPT 통해서 포스팅의 내용을 받는 방법은 성공을 했습니다.

그렇다면 이 받은 내용을 가지고 글을 쓸 수 있어야 합니다.

이를 위해서 우리는 워드프레스의 REST API를 활용할 것입니다.

				
					WP_URL=https://yourdomain.com/wp-json/wp/v2/posts
WP_USER=your email
WP_PASSWORD=your password
				
			

이를 위해서는 위와 같은 정보들을 .env 파일에 추가하면 됩니다.

여기서 WP_URL의 도메인은 여러분의 워드프레스 주소를 사용합니다.

WP_USER 은 wp-admin 로그인을 위해 사용하는 이메일을 넣습니다.

WP_PASSWORD는 설정이 따로 필요합니다.

패스워드 설정을 위해서 Users >> Profile 로 이동합시다.

그리고 아래로 스크롤을 쭉 하다 보면…

이렇게 특정한 패스워드를 생성하고 추가가 가능합니다.

여기에 추가한 패스워드를 앞서 .env 내부에 패스워드로 넣으면 됩니다.

				
					from fastapi import FastAPI
import requests
import os
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import Optional  # 🔹 Optional 타입 사용

# .env 파일 로드 (API Key 보호)
load_dotenv()
GPT_API_KEY = os.getenv("OPENAI_API_KEY")
WP_URL = os.getenv("WP_URL")  # WordPress REST API URL
WP_USER = os.getenv("WP_USER")  # WordPress 로그인 ID
WP_PASSWORD = os.getenv("WP_PASSWORD")  # WordPress 애플리케이션 비밀번호

# FastAPI 서버 설정
app = FastAPI()

# ✅ JSON 데이터 처리를 위한 모델 정의 (에러 수정)
class GeneratePostRequest(BaseModel):
    pdf_url: Optional[str] = None
    website_url: Optional[str] = None

# ✅ WordPress REST API를 활용한 포스팅 함수
def create_wordpress_post(title, content):
    headers = {
        "Content-Type": "application/json"
    }
    auth = (WP_USER, WP_PASSWORD)  # 기본 인증 사용

    data = {
        "title": title,
        "content": content,
        "status": "publish",
        "categories": [38]
    }

    response = requests.post(WP_URL, json=data, headers=headers, auth=auth)

    print("🔹 WordPress API 응답 코드:", response.status_code)
    print("🔹 WordPress API 응답 내용:", response.text)

    if response.status_code == 201:
        return {"status": "success", "post_id": response.json()["id"], "message": "Post successfully published!"}
    else:
        return {"status": "error", "message": response.text}

# ✅ GPT API를 이용한 블로그 포스트 생성 및 WordPress 업로드
@app.post("/generate_and_post/")
def generate_and_post(request: GeneratePostRequest):
    print(f"📌 Received website_url: {request.website_url}")  
    print(f"📌 Received pdf_url: {request.pdf_url}")  

    prompt = """
    주어진 정보를 기반으로 블로그 포스트 형식으로 정리해 주세요.
    - 제목은 간결하고 핵심적인 내용으로 구성해 주세요.
    - 본문은 5~6개의 문단으로 자세하게 작성해 주세요.
    - 내용은 자연스럽고 읽기 쉽게 정리해 주세요.
    - 반드시 한국어로 작성해 주세요.
    """

    if request.pdf_url:
        prompt += f"\n해당 자료는 PDF 파일입니다: {request.pdf_url}"
    
    if request.website_url:
        prompt += f"\n해당 자료는 웹사이트의 URL입니다. 이 URL의 내용을 웹에서 읽고 참고해주세요. : {request.website_url}"

    print("📌 Final Prompt:", prompt)  

    headers = {"Authorization": f"Bearer {GPT_API_KEY}"}

    data = {
        "model": "gpt-4",
        "messages": [
            {"role": "system", "content": "당신은 한국어 블로그 글을 작성하는 도우미입니다."},
            {"role": "user", "content": prompt}
        ],
        "temperature": 0.7,
        "max_tokens": 1024
    }

    response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=data)
    
    print("🔹 GPT API 응답 코드:", response.status_code)
    print("🔹 GPT API 응답 내용:", response.text)

    gpt_response = response.json()

    if "choices" in gpt_response:
        content = gpt_response["choices"][0]["message"]["content"]
        print("📌 GPT 생성 글:", content)

        title = content.split("\n")[0]

        wp_response = create_wordpress_post(title, content)
        return wp_response

    return {"status": "error", "message": "Failed to generate content"}

				
			

이제 다음과 같이 전체 server.py를 구성할 수 있게 됐습니다.

실행하는 방법은 다음과 같습니다.

우선은 터미널에서 server.py 가 있는 프로젝트 루트로 이동합니다.

				
					uvicorn server:app --reload

				
			

서버를 위 명령어로 실행합니다.

이후 Git Bash 창을 켭니다.

				
					curl -X POST "http://127.0.0.1:8000/generate_and_post/" \
-H "Content-Type: application/json" \
-d '{"website_url": "https://www.ncbi.nlm.nih.gov/"}'

				
			

위 명령어를 사용합니다.

이때 website_url 에 내가 요약해서 포스팅을 하고 싶은 웹 사이트의 링크를 담습니다.

				
					{"status":"success","post_id":7372,"message":"Post successfully published!"}

				
			

위와 같이 결과 성공 메시지가 나온다면 포스팅이 되었다는 뜻입니다.

실제로 내가 설정한 기본 포스팅 양식으로 값이 담겨서 나타나는 것을 볼 수 있습니다.

만약 더 다양한 정보를 담아서 포스팅을 만들고 싶다면, 다음과 같이 포스팅에 사용하는 data 의 key 값들을 더 여러 개로 하면 됩니다.

				
					data = {
    "title": "My First API Post",  # 글 제목
    "content": "This is a post created using WordPress REST API!",  # 본문 내용
    "status": "publish",  # "publish" (즉시 공개) / "draft" (초안 저장)
    "categories": [1, 2],  # 카테고리 ID (배열)
    "tags": [3, 4],  # 태그 ID (배열)
    "author": 1,  # 작성자 ID
    "excerpt": "This is a short summary of the post.",  # 요약문 (excerpt)
    "comment_status": "open",  # 댓글 허용 ("open") / 비허용 ("closed")
    "ping_status": "open",  # 핑백 허용 ("open") / 비허용 ("closed")
    "featured_media": 15,  # 썸네일 이미지 (미디어 ID)
    "format": "standard",  # 글 형식 ("standard", "aside", "gallery", 등)
    "meta": {"custom_field": "Custom Value"}  # 커스텀 필드 추가 가능
}

				
			

워드프레스 포스팅에 사용이 가능한 다양한 key 값들과, 그것에 관한 설명입니다.

이를 활용해서 더 많은 정보들을 GPT 통해 받고, 그것을 활용해 포스팅에 활용해보세요.

마치며...

GPT API를 활용한 포스팅 자동화 방식이었습니다.

또 다른 방식으로 포스팅 자동화를 할 수 있는데

그것 또한 포스팅을 준비하겠습니다.

다음에도 또 비루한 주제를 가지고 포스팅을 해보겠습니다.

여기까지 봐주신 분들 정말 감사합니다.^^