• Emily T. Burak

Discord + Napkin Bot Integration: Pt.1


Image of the Napkin app sourced from Shu Omi's blog about Napkin on Medium (big thanks to Shu for their content introducing me to Napkin and other tools!)


Making Discord bots is a favorite pastime for me, and I've been digging Napkin, a note-taking app focusing on connected thought, so I figured I'd write a small Discord bot with Discord.py, a Python library for working with Discord's API and making bots, to integrate the two. This blog is ostensibly the first in a series detailing the development of that bot, enabled by Napkin's API being exposed, at least for uploading Thoughts(notes.)


NOTE: Napkin is not a forever-free app, but I consider it worth the money, especially when integrated with Readwise for pulling in stuff like Kindle highlights. It's a growing product and I look forward to seeing more of the API exposed.


Setting up a bot in Discord and base file structure


First, some administrative stuff to get out of the way -- making the bot! I'm not going to detail setting up a Discord bot via. the developer portal here, there are plenty of resources out there for that. Instead, I'll focus on the structure and paradigm I use for Discord bots as I develop them (which will grow more complex as the bot matures.)


For a simple bot, I start with:


  • A .env file populated with the bot token and any other sensitive environment variables

  • A config.py file to reference the .env file via python-dotenv

  • A bot.py main file and entry point to run the bot


Here are the highlights of the three.


For the .env file, your structure will be something like this:



TOKEN={Your discord token}
EMAIL={Your Napkin email}
NAPKIN_TOKEN={Your Napkin API token}



For the config.py file, you'll want to use python-dotenv to pull in those values:



import os

from dotenv.main import load_dotenv

load_dotenv()

# Discord config
TOKEN = os.getenv("TOKEN", "")
NAPKIN_TOKEN = os.getenv("NAPKIN_TOKEN", "")
EMAIL = os.getenv("EMAIL", "")




Finally, the bot.py file! Here's where we integrate with Napkin, enabling the functionality of messaging the running bot to upload Thoughts to Napkin, using the requests library for the POST request to Napkin and loguru for logging:



import sys

import discord
from discord.ext import commands

import config
from loguru import logger
from time import perf_counter
import requests


def main():
    
    # setting up loguru logger
    start_time = perf_counter()
    logger.add(sys.stderr, level="DEBUG")
    # allows privledged intents for monitoring members joining, roles editing, and role assignments
    # these need to be enabled in the developer portal as well
    # note that not all of these are needed, but in early development I have left them in for flexibilit
    intents = discord.Intents.default()

    intents.guilds = True
    intents.members = True
    intents.message_content = True

    intents.presences = True

    # setting up the bot, you must pass in intents here to use them
    bot = commands.Bot(
        commands.when_mentioned_or(""),
        intents=intents,
    )

    @bot.event
    async def on_ready():
        """When discord is connected, log how long it took"""
        end_time = perf_counter()
        logger.debug(
            f"{bot.user.name} has connected to Discord in {end_time - start_time} seconds!"
        )

    @bot.event
    async def on_message(message):
        # on a message to the bot, upload the message's content
        await bot.process_commands(message)
        # check to make sure it's a DM
        if not message.guild:
            url = "https://app.napkin.one/api/createThought"
            req = {
                "email": config.EMAIL,
                "token": config.NAPKIN_TOKEN,
                "thought": message.content,
            }
            
            # upload to napkin
            requests.post(url, json=req)

        else:
            pass

    # Run Discord bot
    bot.run(config.TOKEN)


if __name__ == "__main__":
    main()

Running the bot then becomes, with everything installed and set up, as easy as a simple python bot.py for local development.


Note: This code is a bit rough, I've edited early code from the repo here to be more readable and concise, if you have any issues that can't be sorted out by looking at that point in the repo history in setting this up, definitely contact me!


I appreciate your time and interest in digging into Napkin and Discord bots, I've built out this bot a decent amount more than this, and I'll be spreading out detailing the process over a couple of blogs, I think. Have fun playing around with Napkin's API and integrating with Discord, or just use this as an example of a simple bot setup. The next blog will focus on some crunchy matters of housekeeping and deployment(such as Dockerizing all this), which is really where my passion is.


The repo for this project as it currently stands is located at https://github.com/EmilyBurak/discord-napkin-integration


Finally, I can be reached through my LinkedIn profile with any questions or comments, or leave one here/email me!


14 views0 comments