#Source map
Where the code lives, and where to read it when these pages are not enough. The plugin system is open source in three places: the SDK and the plugins in one repository, the app side in the entinyGram client, and the original engine upstream in Inugram.
#The three repositories
| Repository | What is in it |
|---|---|
| entinyGram/plugins | the SDK (typings, command line tool, @entiny/sdk), the official plugins, the catalog and the build scripts |
| entaytion/entinyGram | the entinyGram client: the patchset and the Kotlin code that hosts plugins inside the app |
| teidesu/inugram | Inugram, the project entinyGram is built on. The plugin engine, the API and the original docs come from here |
#The plugins repository
Everything a plugin author touches is in entinyGram/plugins.
#sdk/types: the typings
sdk/types is the package @inugram/plugin-types. It is the most important thing to read: every call is documented there, with its grant, its limits and whether it is experimental.
| File | Contents |
|---|---|
common.d.ts | the core of the API: inu, accounts, messages, inu.ui, inu.icons, inu.utils, interceptors |
android.d.ts | inu.android: the current screen, bundles, native views |
android.jvm.d.ts | inu.jvm: reflection, handles, defineClass, routines |
android.xposed.d.ts | inu.xposed: hooks |
android.notification-center.d.ts | the app's internal event bus (unsafe.notificationCenter) |
android.tl.d.ts | every Telegram TL type, method and update |
canvas.d.ts | inu.canvas |
fs.d.ts | inu.fs |
dom.d.ts | the web-like globals: fetch, Blob, localStorage, timers |
grants.json | the grant catalogue: every permission, its scopes and its level |
grants.d.ts | the same grants as types |
tl-names.txt | the names of TL methods and updates a grant scope can use |
#sdk/cli: the inu command line tool
sdk/cli is @inugram/cli. Read it to see exactly what a command does.
| Path | Contents |
|---|---|
src/commands | one file per command: build, check, dev, eval, init, list, push, remove, verify |
src/utils/config.ts | the inu.config.ts schema and how it is loaded |
src/utils/manifest.ts | the manifest schema, how the header is written, and the grant validation |
src/utils/device.ts | how the tool talks to the phone over adb |
src/routines | the routine compiler: finding calls, captures, bytecode |
src/templates | the starter project inu init creates |
#sdk/docs: the original guides
sdk/docs holds the plugin guides as they come from Inugram: getting started, engine, grants, ui, telegram, interception, io, canvas, jvm, xposed and routines. The pages you are reading explain the same ideas, with entinyGram's additions.
#sdk/entiny: @entiny/sdk
sdk/entiny is the package a plugin imports to use the entinyGram SDK.
| Path | Contents |
|---|---|
src/index.ts | withEntiny, the @requires rule, the placement types, SDK_VERSION |
src/embed.ts | the embed function and its row types, the contract with the SDK plugin |
src/slots.ts | the typed list of places a setting can go |
slots.json | the same list as data: every screen, section, item and picker |
README.md | short notes on placement |
#plugins: the official plugins
plugins/ has one folder per plugin, each with an inu.config.ts and a src. They are the best examples of real code: see Worked examples.
The SDK plugin is in plugins/entiny-sdk/src:
| File | Contents |
|---|---|
index.ts | the Marketplace pages: Home, Plugins, Settings, the plugin page, install |
channel.ts | reading a Telegram channel as a catalog, and the post parser |
sources.ts | the list of sources and what is stored about them |
catalog.ts | the catalog types, and how a channel file is addressed |
navbar.ts | the native bottom bar |
embed/engine.ts | the engine that draws other plugins' rows into the app's screens |
icons | the tab icons, plain SVG files |
i18n.ts | the texts, in English, Ukrainian and Russian |
#The catalog and the scripts
| Path | Contents |
|---|---|
index.json | the catalog the Marketplace reads for official plugins |
plugins/dist | every published version of every official plugin, never changed once published |
user-plugins | the second GitHub catalog, for community bundles |
scripts/build-plugin-index.ts | builds the plugins, hashes them and refreshes the catalog |
scripts/build-user-index.ts | the same for community bundles |
scripts/pack-release.ts | packs named release files |
scripts/generate-slots.ts | regenerates the slot list from the app's strings |
#The client
The plugin host inside the app is Kotlin, in src/fork of the client repository. Read it when you want to know what happens on the other side of a call.
| Path | Contents |
|---|---|
helpers/plugins | the host: loading, permissions, sessions, the Telegram and JVM bridges, icons and UI |
helpers/plugins/PluginManager.kt | installing, enabling, updating and the dependency checks |
helpers/plugins/PluginImportHelper.kt | the import and permission sheet |
helpers/plugins/ui/PluginUi.kt | how declarative pages become native screens |
helpers/entiny/EntinyMarketBridge.kt | the small bridge the Marketplace uses to list and install plugins |
ui/settings/PluginsActivity.kt | the plugin list in the settings |
ui/settings/PluginSettingsActivity.kt | the generic host of a plugin's settings page |
The user facing list of what entinyGram adds is FEATURES.md.
#Inugram upstream
The plugin engine, the inu API and the command line tool were written in Inugram. Its sdk folder holds the same three parts you saw above: cli, docs and types.
#Finding what to hook
When you hook the app, you need the name of a class and a method. The app is Telegram for Android with a patchset, so almost every class has the stock name:
- Read the original source: DrKLO/Telegram. The classes you will see most are
AndroidUtilities,LocaleController,MessagesController,ChatActivity,DialogCellandChatMessageCell. - For the entinyGram and Inugram classes, such as
desu.inugram.InuConfig, read the client repository above. - To see the exact names and signatures in the build you target, decompile the APK with jadx.
- Hook a method with its descriptor, such as
formapMapUrl(IDDIIZII)Ljava/lang/String;, so the right overload is chosen. See Method hooks.
#Other references
- mtcute: the TL and message API of plugins follows its model, and its parse modes guide applies to
mdandhtml. - QuickJS: the JavaScript engine plugins run in.
- esbuild: the bundler the CLI uses.
- Telegram API methods: what
invokeRpccan call. - The plugins channel, @entinyGramPlugins, and the community chat, @entinyGramChat.