Created
November 30, 2024 08:26
-
-
Save cookienommienom/e33e622008787e2482a14ac251e93d1a to your computer and use it in GitHub Desktop.
Impressive ChatGPT o1 output related to subscription management with Discord.py and FastAPI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import discord | |
from discord.ext import commands | |
from sqlalchemy import create_engine, Column, Integer, String, Boolean | |
from sqlalchemy.orm import sessionmaker, declarative_base | |
import stripe | |
from fastapi import FastAPI, Request, HTTPException | |
import uvicorn | |
import asyncio | |
# Set up the database | |
Base = declarative_base() | |
class UserSubscription(Base): | |
__tablename__ = 'user_subscriptions' | |
id = Column(Integer, primary_key=True) | |
discord_user_id = Column(String, unique=True) | |
stripe_customer_id = Column(String) | |
has_active_subscription = Column(Boolean, default=False) | |
engine = create_engine('sqlite:///subscriptions.db') | |
Base.metadata.create_all(engine) | |
SessionLocal = sessionmaker(bind=engine) | |
# Set up Stripe | |
stripe.api_key = 'sk_test_YOUR_SECRET_KEY' # Replace with your Stripe Secret Key | |
# Initialize FastAPI | |
app = FastAPI() | |
# Stripe webhook endpoint | |
@app.post('/webhook') | |
async def stripe_webhook(request: Request): | |
payload = await request.body() | |
sig_header = request.headers.get('stripe-signature') | |
endpoint_secret = 'whsec_YOUR_WEBHOOK_SECRET' # Replace with your endpoint's secret | |
try: | |
event = stripe.Webhook.construct_event( | |
payload, sig_header, endpoint_secret | |
) | |
except ValueError as e: | |
# Invalid payload | |
raise HTTPException(status_code=400, detail=str(e)) | |
except stripe.error.SignatureVerificationError as e: | |
# Invalid signature | |
raise HTTPException(status_code=400, detail=str(e)) | |
# Handle the event | |
session = SessionLocal() | |
if event['type'] in ['customer.subscription.created', 'customer.subscription.updated']: | |
subscription = event['data']['object'] | |
customer_id = subscription['customer'] | |
# Update the user's subscription status in the database | |
user = session.query(UserSubscription).filter_by(stripe_customer_id=customer_id).first() | |
if user: | |
user.has_active_subscription = subscription['status'] == 'active' | |
session.commit() | |
elif event['type'] == 'customer.subscription.deleted': | |
subscription = event['data']['object'] | |
customer_id = subscription['customer'] | |
# Update the user's subscription status in the database | |
user = session.query(UserSubscription).filter_by(stripe_customer_id=customer_id).first() | |
if user: | |
user.has_active_subscription = False | |
session.commit() | |
session.close() | |
return {'status': 'success'} | |
# Initialize Discord Bot | |
intents = discord.Intents.default() | |
bot = commands.Bot(command_prefix='!', intents=intents) | |
# Subscribe command | |
@bot.command() | |
async def subscribe(ctx): | |
user_id = str(ctx.author.id) | |
session = SessionLocal() | |
user = session.query(UserSubscription).filter_by(discord_user_id=user_id).first() | |
if not user: | |
# Create a new Stripe customer | |
customer = stripe.Customer.create( | |
metadata={'discord_user_id': user_id} | |
) | |
# Save the customer ID in the database | |
user = UserSubscription( | |
discord_user_id=user_id, | |
stripe_customer_id=customer.id | |
) | |
session.add(user) | |
session.commit() | |
else: | |
customer = stripe.Customer.retrieve(user.stripe_customer_id) | |
# Create a Checkout Session | |
try: | |
checkout_session = stripe.checkout.Session.create( | |
customer=customer.id, | |
payment_method_types=['card'], | |
line_items=[{ | |
'price': 'YOUR_PRICE_ID', # Replace with your actual price ID | |
'quantity': 1, | |
}], | |
mode='subscription', | |
success_url='https://yourdomain.com/success', # Replace with your success URL | |
cancel_url='https://yourdomain.com/cancel', # Replace with your cancel URL | |
) | |
# Send the Checkout Session URL to the user | |
await ctx.author.send(f"Please complete your subscription: {checkout_session.url}") | |
except Exception as e: | |
await ctx.send(f"An error occurred: {str(e)}") | |
finally: | |
session.close() | |
# Check if the user is subscribed | |
def is_subscribed(): | |
async def predicate(ctx): | |
user_id = str(ctx.author.id) | |
session = SessionLocal() | |
user = session.query(UserSubscription).filter_by(discord_user_id=user_id).first() | |
if user and user.has_active_subscription: | |
result = True | |
else: | |
result = False | |
session.close() | |
return result | |
return commands.check(predicate) | |
# Premium command accessible only to subscribed users | |
@bot.command() | |
@is_subscribed() | |
async def premium_command(ctx): | |
await ctx.send("You have access to premium features!") | |
# Run FastAPI and Discord bot concurrently | |
async def main(): | |
# Start the FastAPI app | |
config = uvicorn.Config(app, host='0.0.0.0', port=8000, log_level="info") | |
server = uvicorn.Server(config) | |
# Start the bot | |
bot_task = asyncio.create_task(bot.start('YOUR_DISCORD_BOT_TOKEN')) # Replace with your bot's token | |
# Start the FastAPI server | |
server_task = asyncio.create_task(server.serve()) | |
await asyncio.gather(bot_task, server_task) | |
asyncio.run(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment