LammaDevelopers Open Lamma

SDKs

Build Lamma bots in Python with the patterns you know from discord.py.

lamma.py lets you build Lamma bots in Python with the names and patterns you know from discord.py. It runs on Lamma's own REST API and gateway and never talks to Discord.

#Example

Python
import lamma
from lamma import app_commands
from lamma.ext import commands

intents = lamma.Intents.default()
intents.message_content = True


class MyBot(commands.Bot):
    async def setup_hook(self):
        await self.tree.sync()  # global commands show up everywhere at once


bot = MyBot(command_prefix='!', intents=intents)


@bot.command()
async def hello(ctx):
    await ctx.reply(f'Hello, {ctx.author.display_name}!')


@bot.tree.command(description='Roll a die')
@app_commands.describe(sides='How many sides')
async def roll(interaction: lamma.Interaction, sides: app_commands.Range[int, 2, 100]):
    await interaction.response.send_message(f'You rolled a d{sides}', ephemeral=True)


bot.run()  # reads LAMMA_TOKEN

#Options

OptionDefaultNotes
base_urlLAMMA_URLAnother copy of Lamma to reach, such as a local one. Defaults to Lamma's own address
intentsrequiredWhich events to receive
gateway_urlfrom GET /v1/gateway, or LAMMA_GATEWAY_URLSet it when your bot reaches Lamma by another address
max_messages1000Messages kept, in memory only, for edit and delete events
allowed_mentionsevery mention allowedThe default for every message

#Coming from discord.py

Most bots port by changing import discord to import lamma as discord, from discord.ext import commands to from lamma.ext import commands, and setting LAMMA_TOKEN. The migration guide has the details.

discord.pylamma.py
discord.Client(intents=...), commands.Bot(...)The same
Intents.default(), .message_content, .members, .guilds, .messages, .reactions, .moderation, .expressionsThe same. Other flags are accepted, ignored with one warning, and read as False
Int IDs, guild.get_channel(id), discord.utils.get(..., id=...)The same. Lookups also take an ID as a string
TextChannel, VoiceChannel, CategoryChannel, channel.type, guild.text_channels, guild.voice_channelsThe same. Bots can post in a voice channel's text chat
discord.Permissions and its presets, role.permissions, member.guild_permissions, interaction.permissions, interaction.app_permissionsThe same
MessageFlags, PublicUserFlags, MemberFlags, ChannelFlags, RoleFlags, AttachmentFlags, EmbedFlags, SystemChannelFlags, ApplicationFlags, MemberCacheFlags, AppCommandContext and the other flag classesThe same names and bits. Lamma has none of these features, so the flags on messages, users, members, channels and roles are always empty
app_commands.checks.has_permissions(), bot_has_permissions()The same, exact for the channel
commands.bot_has_permissions(), has_guild_permissions(), bot_has_guild_permissions()The same
commands.has_permissions()Uses the author's server-wide permissions, because Lamma doesn't send channel overrides. It warns once
channel.permissions_for(guild.me)The same for the bot itself. For anyone else it raises ClientException
client.run(token), await client.start(token)The same. run() defaults to LAMMA_TOKEN
setup_hook, on_ready, on_message, on_message_edit, on_message_delete, on_raw_*, on_guild_join, on_guild_remove, on_interactionThe same
on_member_join, on_member_update, on_member_remove, on_member_ban, on_member_unban, on_audit_log_entry_createThe same. Timeouts, bans and audit entries need moderation access
guild.audit_logs(...)The same. Entries Discord has no action for have action set to None and entry.lamma_action
channel.send(), message.reply(), edit(), delete(), add_reaction()The same
channel.history(), channel.fetch_message()The same
guild.fetch_members(), guild.fetch_member()The same. Needs members.read
discord.EmbedThe same. Images and thumbnails aren't shown yet
app_commands.CommandTree, @tree.command, describe, choices, Range, LiteralThe same
Option types str, int, float, bool, Member, User, TextChannel, VoiceChannel, RoleThe same
tree.sync(), tree.sync(guild=...)The same. Global commands appear at once
interaction.response.send_message(ephemeral=True), defer(), edit_original_response(), followup.send()The same, within 3 seconds and 15 minutes
commands.Cog, Cog.listener(), @bot.command(), Context, converters, checksThe same
await bot.load_extension('cogs.fun') with async def setup(bot), unload_extension(), reload_extension()The same
discord.utils.get, find, format_dt, escape_markdown, escape_mentionsThe same

#What's different

  • IDs are Lamma IDs, so a Discord ID won't find anything.
  • channel.permissions_for() only works for the bot itself. Lamma doesn't send channel overwrites to bots, so it raises ClientException for anyone else rather than guess. Use interaction.permissions for the person who ran a command, or member.guild_permissions for server-wide permissions.
  • Lamma's Mention roles permission has no Discord flag, so it isn't part of Permissions.
  • default_permissions and guild_only are accepted but have no effect yet, so check interaction.permissions in your command code.
  • Channel options aren't limited by type yet. If someone picks a voice channel for a TextChannel parameter, the command fails with app_commands.TransformerError.
  • There are no buttons, views, select menus, modals, autocomplete, context menus or subcommand groups yet. app_commands.Group and commands.GroupCog raise so you notice.
  • Bots can't upload files yet. discord.File works, but file= and files= are left out of the message with one warning.
  • Bots can't send DMs, show a status or show typing. user.send() raises Forbidden with code 50007, as Discord does for someone with DMs closed. typing() and change_presence() do nothing. Each logs one warning.
  • Bots can't kick, ban or time out members yet.
  • client.fetch_user() only returns people the bot has already seen.
  • Reaction events are raw only: use on_raw_reaction_add and on_raw_reaction_remove.
  • When the connection drops, the client reconnects and on_ready runs again. There is no resume, so read anything you missed with channel.history().

See Coming from Discord for everything that differs.