5 minute read

Auto send collaborators invitation to GitHub repos after they pay or donate

Python3 automations

In this article, I going on how to use Google forms to collect donations, support, or sponsor your project even you can use it for charity to auto-send postcards, letters after their donation to thank them.

So I’m here going to use Google form to collect information or forward to payout page with PayPal, Why Google Form? to reduce the cost of hosting our payment page with hosting providers and saving the money.

The main points we’ll go through it during this article:

  • Google Forms and Sheets
  • Python3 Automation script
  • GitHub actions

Google Forms and Sheets

Sure everyone knows about Google forms or has at lees used it many times in your work but today we go a little bit deep with it by using add-ons like (Payable Forms) to add it go to three doted next to send button and choose add-ons

Google Form add-ons

Then write down in search box Payable forms and install it

Payable Forms

When you have done with installation go to this screen to connect with your PayPal account also you can use the sample fields and then modify them as you like.

Payable Conf

Don’t forget to collect the donor or supporter GitHub account for the next step.

Python3 Automation script

Here’s my favorite part, We didn’t talk much in the preview part you know it’s easy, We have not spent more time with it but just focus on how to collect the right information for our Python script to deal with it.

So in our main.py file, we have to import the below modules and walk through this list of modules:


from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

Module: google.auth.transport.Request

Requests request adapter.

This class is used internally for making requests using various transports in a consistent way. If you use AuthorizedSession you do not need to construct or use this class directly.

This class can be useful if you want to manually refresh a Credentials instance:

import google.auth.transport.requests
import requests

request = google.auth.transport.requests.Request()

credentials.refresh(request)

Module: google.oauth2.credentials

OAuth 2.0 Credentials.

This module provides credentials based on OAuth 2.0 access and refreshes tokens. These credentials usually access resources on behalf of a user (resource owner).

Specifically, this is intended to use access tokens acquired using the Authorization Code grant and can refresh those tokens using a optional refresh token.

Obtaining the initial access and refresh token is outside of the scope of this module. Consult rfc6749 section 4.1 for complete details on the Authorization Code grant flow.

Module: google_auth_oauthlib.flow

This module provides integration with requests-oauthlib for running the OAuth 2.0 Authorization Flow and acquiring user credentials.

Module: googleapiclient.discovery

You can use the Google APIs Discovery Service for building a variety of different tools to use with Google APIs. However, the primary purpose of the Discovery document is to allow Google to create client libraries in various programming languages. This section describes how you could go about building a custom client library for Google APIs.

Source: Google Auth Library for Python and Google API Docs
check out this sample
https://developers.google.com/docs/api/quickstart/python

Authorization credentials

Authorization credentials for a desktop application. To learn how to create credentials for a desktop application, refer to Create credentials

https://developers.google.com/workspace/guides/create-credentials

For the above modules, we going to create this function, and let’s name it as gsheet_auth()

def gsheet_auth():
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'mycredentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    return creds

For this moment we have a connection with Google Sheet API all that we have to do to query all records with this function

def gsheet_query(ndays, mode):

    mode = int(mode)
    ndays = int(ndays)

    creds = gsheet_auth()
    try:
        service = build('sheets', 'v4', credentials=creds)

        # Call the Sheets API
        sheet = service.spreadsheets()
        result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID, range=SAMPLE_RANGE_NAME).execute()

        df = pd.DataFrame.from_dict(result['values'])
        df.columns = df.iloc[0]
        df.drop(df.index[0], inplace=True)

        start_date = (datetime.today() - timedelta(days=ndays)).strftime('%m/%d/%Y %H:%M:%S')  # "12/25/2021 00:00:00"
        end_date = datetime.today().strftime('%m/%d/%Y %H:%M:%S')  # "12/26/2021 00:00:00"

        after_start_date = df["Payable Last Updated"] >= start_date
        before_end_date = df["Payable Last Updated"] <= end_date
        between_two_dates = after_start_date & before_end_date
        filtered_dates = df.loc[between_two_dates]

Here’s the final part of the Python script which is a function to do auto-send collaborators invitations to your GitHub repos for this part we going to communicate with GitHub API

###########################
#### GitHub API ###########
###########################
def github_collaborator_add(COLLABORATOR_USER_NAME, REPO_NAME):
    ######################################
    # To add collaborator to your repos ##
    ######################################
    headers = {
        'Authorization': f'Bearer {GITHUB_TOKEN}'
    }
    collaborators_url = f"https://api.github.com/repos/{GITHUB_USER}/{REPO_NAME}/collaborators/{COLLABORATOR_USER_NAME}"
    payload = {"permission": "admin"}
    srs = requests.request('PUT', collaborators_url, headers=headers, json=payload) # Comment this line if you want to check the link with the values and uncomment the next line
    # srs = collaborators_url 
    return srs

Or you can change this part to send a Postcard or letters

GitHub actions

For this part, we going to run our script Automatically in schedule trigger with Github workflow

workflow

Create this directory (.github/workflows/) and then create (main.yml) paste the below script in it

Be sure (.gethub/) started with dote

name: "Auto GitHub Collaborators Invite"

on:
  schedule:
        - cron: '0 0 * * *' # run every day at midd night - GMT
  issues:
      types: [opened]

jobs:
    minesweeper:
        runs-on: ubuntu-latest
        steps:
        
        # Setup Python first
        - name: Setup Python
          uses: actions/[email protected]
          with:
            python-version: 3.8.10
    
        - name: Clone repos
          run: |
            git clone https://iven86:[email protected]/iven86/auto_github_collaborators_invite
            
        # Install require libs
        - name: Install required libraries
          run: |
            pip install -r auto_github_collaborators_invite/requirements.txt
            
        - name: Run Python Script
          env:
            SPREADSHEET_ID: $
            RANGE_NAME: $
            GH_TOKEN: $
            GH_USER: $
            GH_ORG_NAME: $
            GH_TEAM: $
            
          run: |
            SPREADSHEET_ID=$SPREADSHEET_ID RANGE_NAME=$RANGE_NAME GH_TOKEN=$GH_TOKEN GH_USER=$GH_USER GH_ORG_NAME=$GH_ORG_NAME GH_TEAM=$GH_TEAM python3 auto_github_collaborators_invite/main.py -m 3 -d 1
              
        - name: Push Updated Token To The Main Repo
          run : |
            cd auto_github_collaborators_invite
            git remote set-url origin https://iven86:[email protected]/iven86/auto_github_collaborators_invite
            git config --global user.email "[email protected]"
            git config --global user.name "iven86"
            git add .
            git commit -m "Update the token file"
            git push -f origin main

For full source code follow this link and support me!.

https://forms.gle/gSv3mDMyJh3cty8B8

For another sample about GitHub actions, read my past article

https://iven.in/devops/github-actions-run-bash-script/