• Hello everyone,

    I would like to create a Telegram bot for our club, which loads the pictures that are posted to it directly into the media directory of WordPress…

    So far it works but I always get the error message GET 403 back… so no access.

    I have already read a lot etc but so far it has not really helped me. Do I have to set anything else in Plesk or somewhere else?

    Here is the excerpt from the LOG:

    2024-05-07 22:34:37 Access XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 301 POST /wp-json/wp/v2/media HTTP/1.1 “python-requests/2.28.2” 162 SSL/TLS access for nginx
    2024-05-07 22:34:37 Error XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 403 GET /wp-json/wp/v2/media HTTP/1.1 “python-requests/2.28.2” 118 SSL/TLS access for nginx
    2024-05-07 22:34:59 Access XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 301 POST /wp-json/wp/v2/media HTTP/1.1 “python-requests/2.28.2” 162 SSL/TLS access for nginx
    2024-05-07 22:34:59 Error XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 403 GET /wp-json/wp/v2/media HTTP/1.1 “python-requests/2.28.2” 118 SSL/TLS access for nginx

    The code in the bot works so far… I have tested it both with normal or application password. Also the test user is admin with all access rights.

    I have also read that you should check something in the NGINX config, but I have not found it. -> NGINX Config

    I used the Hoster Netcup from Germany.

    Would be cool if someone can help me 🙂

    The page I need help with: [log in to see the link]

Viewing 6 replies - 1 through 6 (of 6 total)
  • Moderator threadi

    (@threadi)

    Do you also send the X-WP-Nonce header in the request? See: https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/

    Thread Starter gurke258

    (@gurke258)

    Hello 🙂

    I’ve build in this now into my python code, but i get the same result: 403 🙁

    Moderator threadi

    (@threadi)

    Unfortunately, without the source code or a debug output of the HTTP request, it is almost impossible to help you further.

    Thread Starter gurke258

    (@gurke258)

    No Problem 🙂

    There is my Code:

    import requests
    
    import telebot
    
    # Telegram Bot Token
    
    TOKEN = 'XXXXXXXXXXXXXXXXXX'
    
    # WordPress REST API URL
    
    WORDPRESS_URL = 'https://retro-lan-projekt.de/wp-json'
    
    WORDPRESS_USERNAME = 'XXXXX'
    
    WORDPRESS_PASSWORD = 'XXXXXXXXX'
    
    
    bot = telebot.TeleBot(TOKEN)
    
    
    def upload_to_wordpress(file_id):
    
      
    
        endpoint = f"{WORDPRESS_URL}/wp-json/wp/v2/media"
    
      
    
        nonce = get_wp_nonce()
    
      
    
        file_info = bot.get_file(file_id)
    
        file_url = f"https://api.telegram.org/file/bot{TOKEN}/{file_info.file_path}"
    
       
    
        file_content = requests.get(file_url).content
    
        
    
        headers = {
    
            'X-WP-Nonce': nonce
    
        }
    
        files = {'file': file_content}
    
      
    
        response = requests.post(endpoint, headers=headers, files=files, auth=(WORDPRESS_USERNAME, WORDPRESS_PASSWORD))
    
      
    
        return response
    
    
    
    def get_wp_nonce():
    
      
        nonce_endpoint = f"{WORDPRESS_URL}/wp-json/wp/v2/users/me"
    
      
    
        response = requests.get(nonce_endpoint, auth=(WORDPRESS_USERNAME, WORDPRESS_PASSWORD))
    
        
    
        nonce = response.headers.get('X-WP-Nonce')
    
      
    
        return nonce
    
    
    
    @bot.message_handler(content_types=['photo'])
    
    def handle_media(message):
    
        file_id = message.photo[-1].file_id  # Das letzte Foto wird genommen (Annahme: das größte)
    
        bot.reply_to(message, "Foto empfangen")
    
    
        response = upload_to_wordpress(file_id)
    
        
    
        if response.status_code == 201:
    
            bot.reply_to(message, "Datei erfolgreich hochgeladen!")
    
        else:
    
            bot.reply_to(message, f"Es gab ein Problem beim Hochladen der Datei. Statuscode: {response.status_code}")
    
    
    bot.polling()

    That ist the Output vom protocoll

    2024-05-09 20:05:18 Access POST /wp-json/wp-json/wp/v2/media HTTP/1.1 “python-requests/2.28.2″162 SSL/TLS-Zugriff für nginx
    2024-05-09 20:05:18 Error GET /wp-json/wp-json/wp/v2/media HTTP/1.1 “python-requests/2.28.2″118 SSL/TLS-Zugriff für nginx

    • This reply was modified 2 years, 2 months ago by gurke258.
    • This reply was modified 2 years, 2 months ago by gurke258.
    Moderator threadi

    (@threadi)

    You are trying to retrieve the nonce from users/me, which is also not possible without authentication.

    Have a look at other implementations of this with Python, e.g. here: https://stackoverflow.com/questions/67639473/wordpress-authentication-for-rest-api-with-nonces-using-python

    Or implement basic authentication as described in the article above: https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/#basic-authentication-with-application-passwords

    Thread Starter gurke258

    (@gurke258)

    
    
    
    import argparse
    
    import os
    
    import re
    
    from urllib.parse import urljoin
    
    from bs4 import BeautifulSoup
    
    import requests
    
    import telebot
    
    # Define the Telegram bot token
    
    TOKEN = 'XXXX'
    
    bot = telebot.TeleBot(TOKEN)
    
    class BaseUrlSession(requests.Session):
    
        """Extend Requests' Session class with the ability to specify a base URL"""
    
        def __init__(self, base_url=None):
    
            super().__init__()
    
            self.base_url = base_url
    
        def request(self, method, url, *args, **kwargs):
    
            joined_url = urljoin(self.base_url, url)
    
            return super().request(method, joined_url, *args, **kwargs)
    
    def log_in(session: BaseUrlSession, username: str, password: str) -> None:
    
        response = session.post(
    
            "wp-login.php",
    
            data={"log": username, "pwd": password, "wp-submit": "Log In"},
    
            allow_redirects=False,
    
            timeout=10,
    
        )
    
        if response.status_code != 302 or "Set-Cookie" not in response.headers:
    
            raise RuntimeError("Login failed")
    
    def get_wp_rest_nonce(session):
    
        response = session.get("wp-admin/post-new.php", timeout=10)
    
        response.raise_for_status()
    
        soup = BeautifulSoup(response.content, "html.parser")
    
        js_elem = soup.find(id="wp-api-request-js-extra")
    
        if not js_elem:
    
            raise RuntimeError(
    
                "Could not find the script containing the wp_rest nonce"
    
            )
    
        js = js_elem.text.strip()
    
        match = re.search(r'"nonce":"([0-9a-f]+)"', js)
    
        if not match:
    
            raise RuntimeError(
    
                "Could not parse the script containing the wp_rest nonce"
    
            )
    
        return match.group(1)
    
    @bot.message_handler(content_types=['photo'])
    
    def handle_media(message):
    
        try:
    
            base_url = "https://retro-lan-projekt.de/"
    
            username = "XXX"
    
            password = os.environ.get("XXXXX", "")
    
            session = BaseUrlSession(base_url=base_url)
    
            log_in(session, username, password)
    
            session.headers["X-WP-Nonce"] = get_wp_rest_nonce(session)
    
            bot.reply_to(message, "Photo uploaded successfully.")
    
        except Exception as e:
    
            bot.reply_to(message, f"There was an error: {e}")
    
    if __name__ == "__main__":
    
        bot.polling()

    Okay I tried, but it fails 🙁

    I think thats too complicated for me…

Viewing 6 replies - 1 through 6 (of 6 total)

The topic ‘WordPress REST API – Error 403’ is closed to new replies.