Skip to content

Instantly share code, notes, and snippets.

@johnsosoka
Created December 21, 2024 04:00
Show Gist options
  • Select an option

  • Save johnsosoka/1ce8b0ac81cec27fb447093a1a99f196 to your computer and use it in GitHub Desktop.

Select an option

Save johnsosoka/1ce8b0ac81cec27fb447093a1a99f196 to your computer and use it in GitHub Desktop.
#
# This example script will generate a QR code & update a notion page when a webhook is received
# It expects a folder "qr-codes" in the same directory as the script
# It expects the column in the notion page that houses the QR code to be titled "QR Code"
# This is designed to listen to webhooks & serve requests from behind an ngrok tunnel
#
#
# requirements.txt content:
#fastapi==0.115.6
#uvicorn~=0.34.0
#requests~=2.32.3
#qrcode==8.0
#pillow==11.0.0
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
import uvicorn
import json
import requests
import qrcode
# Params
notion_token = "notion api key here"
qr_code_dir = "./qr-codes"
ngrok_url = "ngrok url here"
headers = {
"Authorization": f"Bearer {notion_token}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28"
}
app = FastAPI()
# Mount the directory to serve static files,
# This is how we host the QR codes for embedding in Notion
app.mount("/static", StaticFiles(directory=qr_code_dir), name="static")
@app.post("/webhook")
async def handle_webhook(request: Request):
payload = await request.json()
await update_qr_file_field(payload)
return {"status": "success"}
async def update_qr_file_field(webhook_payload):
page_id = webhook_payload["data"]["id"]
print(f"Updating page with ID: {page_id}")
url = f"https://api.notion.com/v1/pages/{page_id}"
# Hardcoded file URL for testing purposes
file_url = await generate_qr_code(webhook_payload)
payload = {
"properties": {
"QR Code": {
"files": [
{
"name": "QR Code",
"type": "external",
"external": {
"url": file_url
}
}
]
}
}
}
# Send PATCH request to update the page
response = requests.patch(url, headers=headers, data=json.dumps(payload))
# Check the response
if response.status_code == 200:
print("QR field updated successfully!")
print(response.json())
else:
print(f"Error updating QR field: {response.status_code}")
print(response.text)
async def generate_qr_code(webhook_payload) -> str:
"""
Generate a QR code based on Page ID & Return ngrok URL
:param webhook_payload:
:return:
"""
url = webhook_payload["data"]["url"]
# Filename is the page ID
filename = webhook_payload["data"]["id"]
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(url)
qr.make(fit=True)
qr_image = qr.make_image(fill_color="black", back_color="white")
# Save the QR code image
qr_image.save(f"{qr_code_dir}/{filename}.png")
qr_url = f"{ngrok_url}/static/{filename}.png"
print(f"QR Code URL: {qr_url}")
return qr_url
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8080)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment