Skip to content

Instantly share code, notes, and snippets.

@ruanbekker
Created March 10, 2024 15:54
Show Gist options
  • Select an option

  • Save ruanbekker/946dac18fca09c25a5c09bcc63c70c92 to your computer and use it in GitHub Desktop.

Select an option

Save ruanbekker/946dac18fca09c25a5c09bcc63c70c92 to your computer and use it in GitHub Desktop.

Revisions

  1. ruanbekker created this gist Mar 10, 2024.
    163 changes: 163 additions & 0 deletions python_github_discussions_graphql.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,163 @@
    """
    This script uses the GraphQL API to create discussions programatically using Python and Requests.
    """

    import os
    import time
    import json
    import requests

    def url_builder(path):
    response = f'https://{domain_name}/{path}'
    return response

    def list_mdx_files(repo, path):
    mdx_files = []
    contents = repo.get_contents(path)
    for content_item in contents:
    if content_item.type == "dir":
    mdx_files += list_mdx_files(repo, content_item.path)
    elif content_item.path.endswith('.mdx'):
    mdx_files.append(content_item.path)
    return mdx_files

    def create_github_discussion(token, repo_owner, repo_name, category_id, title, body):
    """
    Create a discussion in a GitHub repository using the GraphQL API.
    Parameters:
    - token (str): Personal Access Token (PAT) with permissions to access the repository.
    - repo_owner (str): Owner of the repository (username or organization).
    - repo_name (str): Name of the repository.
    - category_id (str): The ID of the discussion category.
    - title (str): Title of the discussion.
    - body (str): Body content of the discussion.
    """

    # GraphQL endpoint
    url = "https://api.github.com/graphql"

    # GraphQL query. Note: This is a mutation, not a query.
    query = """
    mutation($input: CreateDiscussionInput!) {
    createDiscussion(input: $input) {
    discussion {
    url
    }
    }
    }
    """

    # Variables for the mutation
    variables = {
    "input": {
    "repositoryId": get_repository_id(token, repo_owner, repo_name),
    "categoryId": category_id,
    "title": title,
    "body": body
    }
    }

    # Request headers
    headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
    }

    # Make the POST request
    response = requests.post(url, headers=headers, data=json.dumps({"query": query, "variables": variables}))

    if response.status_code == 200:
    response_data = response.json()
    if 'errors' in response_data:
    print("Failed to create discussion:", response_data['errors'])
    else:
    print("Discussion created successfully. URL:", response_data['data']['createDiscussion']['discussion']['url'])
    else:
    print(f"Failed to create discussion. Status code: {response.status_code}, Response: {response.text}")

    def get_repository_id(token, owner, name):
    """
    Get the GitHub repository ID using the GraphQL API.
    Parameters:
    - token (str): Personal Access Token (PAT).
    - owner (str): Owner of the repository.
    - name (str): Name of the repository.
    """
    url = "https://api.github.com/graphql"
    query = """
    query($name: String!, $owner: String!) {
    repository(name: $name, owner: $owner) {
    id
    }
    }
    """
    variables = {"name": name, "owner": owner}
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.post(url, json={'query': query, 'variables': variables}, headers=headers)
    if response.status_code == 200:
    return response.json()['data']['repository']['id']
    else:
    print(f"Error fetching repository ID. Status code: {response.status_code}, Response: {response.text}")
    return None

    def fetch_discussion_categories(token, repo_owner, repo_name):
    """
    Fetch discussion categories for a repository using the GraphQL API.
    Parameters:
    - token (str): Personal Access Token (PAT) with permissions to access the repository.
    - repo_owner (str): Owner of the repository (username or organization).
    - repo_name (str): Name of the repository.
    """
    url = "https://api.github.com/graphql"
    query = """
    query RepositoryDiscussionCategories($owner: String!, $name: String!) {
    repository(owner: $owner, name: $name) {
    discussionCategories(first: 10) {
    nodes {
    id
    name
    }
    }
    }
    }
    """
    variables = {"owner": repo_owner, "name": repo_name}
    headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
    }

    response = requests.post(url, headers=headers, data=json.dumps({"query": query, "variables": variables}))
    if response.status_code == 200:
    categories = response.json()['data']['repository']['discussionCategories']['nodes']
    for category in categories:
    print(f"Category ID: {category['id']}, Name: {category['name']}")
    else:
    print(f"Failed to fetch discussion categories. Status code: {response.status_code}, Response: {response.text}")

    # pat that can write to discussions
    token = os.getenv('GITHUB_TOKEN')
    repo_owner = os.getenv('GITHUB_REPO_OWNER') # "ruanbekker"
    repo_name = os.getenv('GITHUB_REPO_NAME') # "blog-giscus"
    category_id = os.getenv('GITHUB_DISCUSSIONS_CATEGORY_ID')
    team_slug = None

    # use this to scan the category ids
    # fetch_discussion_categories(token, repo_owner, repo_name)

    discussion_topics_to_be_created = [
    {
    'title': 'blog/2024/01/01/my-discussion-topic',
    'body': 'Discussion for https://my.domain/blog/2024/01/01/my-discussion-topic'
    }
    ]

    for each_topic in discussion_topics_to_be_created:
    discussion_title = each_topic['title']
    discussion_body = each_topic['body']
    print(f"Title: {discussion_title}, Body: {discussion_body}")
    create_github_discussion(token, repo_owner, repo_name, category_id, discussion_title, discussion_body)
    time.sleep(1)