cron jobs will now occur every sixty seconds. Maybe configurable

in the future.
Updated readme from manual. Manual will now be generated from
 readme.
This commit is contained in:
topkecleon 2016-02-25 09:05:08 -05:00
parent ddaf304460
commit 353d6eb807
4 changed files with 132 additions and 128 deletions

240
README.md
View File

@ -1,66 +1,76 @@
#otouto
# otouto
The plugin-wielding, multipurpose Telegram bot.
The public bot runs on [@mokubot](https://telegram.me/mokubot).
[Public Bot](http://telegram.me/mokubot) ¦ [Official Channel](http://telegram.me/otouto) ¦ [Development Group](http://telegram.me/BotDevelopment)
otouto is licensed under the GNU General Public License. A copy of the license has been included in [LICENSE](https://github.com/topkecleon/otouto/blob/master/LICENSE).
otouto is an independently-developed Telegram API bot written in Lua. Originally conceived as a CLI script in February of 2015, otouto has since been open-sourced and migrated to the API, and is being developed to this day.
##What is it?
otouto is an independently developed Telegram API bot written in Lua. Originally conceived as a tg-cli script in February of 2015, otouto has since been migrated to the API, open-sourced, and it being developed to this day.
## Setup {#Setup}
You _must_ have Lua (5.2+), lua-socket, lua-sec, and lua-cjson installed. To upload files, you must have curl installed. To use fortune.lua, you must have fortune installed. Different plugins may require various API keys.
otouto uses a robust plugin system, similar to that of yagop's [telegram-bot](github.com/yagop/telegram-bot). The aim of the project is to contain any desirable feature inside one universal bot.
| Plugin | API Key | Required? |
|:-------|:--------|:----------|
| weather.lua | [OpenWeatherMap](http://openweathermap.org) API key | Y |
| lastfm.lua | [last.fm](http://last.fm) API key | Y |
| bible.lua | [Biblia](http://biblia.com) API key | Y |
| cats.lua | [The Cat API](http://thecatapi.com) API key (optional) | N |
| gImages.lua | [Google](http://console.developers.google.com) API and CSE keys | Y |
| youtube.lua | [Google](http://console.developers.google.com) API key | Y |
| apod.lua | [NASA](http://api.nasa.gov) API key | N |
| translate.lua | [Yandex](https://tech.yandex.com/keys/get/?service=trnsl) API key | Y |
| chatter.lua | [SimSimi](http://developer.simsimi.com/signUp) API key | N |
Certain plugins, such as translate.lua and greetings.lua, will require privacy mode to be disabled.
**Before doing anything**, open config.lua and set `bot_api_key` to the authentication token you received from the Botfather.
You may want to set: `admin`, your Telegram ID; `time_offset`, a positive or negative number, denoting the difference, in seconds, of your system clock to UTC; and `lang`, a lowercase, two-letter code representing your language. Some plugins are not enabled by default. If you wish to enable them, add them to the `plugins` table (before help.lua).
To start the bot, run `./launch.sh`. To stop the bot, send "/halt" from your admin account, and then Ctrl+C out of the loop. If you terminate the bot manually, you risk data loss. If you do not wish the bot to restart automatically, run it with `lua bot.lua`.
* * *
##Plugins
Here is a list of most otouto plugins.
## Plugins {#Plugins}
otouto uses a robust plugin system, similar to that of yagop's [Telegram-Bot](http://github.com/yagop/telegram-bot). The aim of the otouto project is to contain any desirable bot feature within one universal bot framework.
| Plugin | Command | Function | Alias |
|--------|---------|----------|-------|
| help.lua | /help | Returns a list of commands. | /h |
| about.lua | /about | Returns the about text as configured in config.lua. |
| apod.lua | /apod [query] | Gets Astronomy Picture of the Day for current day, or for a specific date (YYYY-MM-DD). | |
| ping.lua | /ping | The simplest plugin ever! |
| echo.lua | /echo <text> | Repeats a string of text. |
| gSearch.lua | /google <query> | Returns Google web results. | /g, /gnsfw |
| gImages.lua | /images <query> | Returns a Google image result. | /i, /insfw |
| gMaps.lua | /location <query> | Returns location data from Google Maps. | /loc |
| youtube.lua | /youtube <query> | Returns the top video result from YouTube. | /yt |
| wikipedia.lua | /wikipedia <query> | Returns the summary of a Wikipedia article. | /wiki |
| lastfm.lua | /np [username] | Returns the song you are currently listening to. |
| lastfm.lua | /fmset [username] | Sets your username for /np. /fmset - will delete it. |
| hackernews.lua | /hackernews | Returns the latest posts from Hacker News. | /hn |
| imdb.lua | /imdb <query> | Returns film information from IMDb. |
| hearthstone.lua | /hearthstone <query> | Returns data for Hearthstone cards matching the query. | /hs |
| calc.lua | /calc <expression> | Returns solutions to math expressions and conversions between common units. |
| bible.lua | /bible <reference> | Returns a Bible verse. | /b |
| urbandictionary.lua | /urbandictionary <query> | Returns the top definition from Urban Dictionary. | /ud, /urban |
| time.lua | /time <query> | Returns the time, date, and a timezone for a location. |
| weather.lua | /weather <query> | Returns current weather conditions for a given location. |
| nick.lua | /nick <nickname> | Set your nickname. /nick - will delete it. |
| whoami.lua | /whoami | Returns user and chat info for you or the replied-to user. | /who |
| eightball.lua | /8ball | Returns an answer from a magic 8-ball. |
| dice.lua | /roll <nDr> | Returns RNG dice rolls. Uses D&D notation. |
| reddit.lua | /reddit [r/subreddit \| query] | Returns the top results from a given subreddit, query, or r/all. | /r |
| xkcd.lua | /xkcd [query] | Returns an xkcd strip and its alt text. |
| slap.lua | /slap <target> | Gives someone a slap (or worse). |
| commit.lua | /commit | Returns a commit message from whatthecommit.com. |
| fortune.lua | /fortune | Returns a UNIX fortune. |
| pun.lua | /pun | Returns a pun. |
| pokedex.lua | /pokedex <query> | Returns a Pokedex entry. | /dex |
| currency.lua | /cash [amount] <currency> to <currency> | Converts one currency to another. |
| cats.lua | /cat | Returns a cat picture. |
| reactions.lua | /reactions | Returns a list of reaction emoticons which can be used through the bot. |
| apod.lua | /apod [date] | Returns the NASA Astronomy Picture of the Day. |
| control.lua | /reload | Reloads all plugins, libraries, and configuration files. |
| control.lua | /halt | Stops the bot. If the bot was run with launch.sh, this will restart it. |
| blacklist.lua | /blacklist <ID> | Blacklists or unblacklists a user, via reply or ID, from using your bot. |
| shell.lua | /shell <command> | Runs a shell command and returns the output. Use with caution. |
| luarun.lua | /lua <command> | Runs a string a Lua code and returns the output, if applicable. Use with caution. otouto does not use a sandbox. |
Most plugins are intended for public use, but a few are for other purposes, like those used alongside [Liberbot](#Liberbot-related_plugins), or for [use by the bot's owner](#Control_plugins). See [Development](#Development) for a breakdown of the components of a plugin, or [here](#List_of_plugins) for a list of plugins.
A plugin can have five components, and two of them are required:
| Component | Description | Required? |
|:----------|:------------|:----------|
| action | The main function. It accepts the `msg` table as an argument. | Y |
| triggers | A table of commands to be used for the plugin. Use Lua patterns. | Y |
| cron | An optional function to be called approximately every minute. | N |
| command | The basic command and syntax. This is listed in the help text. | N |
| doc | Usage and other info for the plugin. This is returned with "/help command" | N |
The `on_msg_receive()` function adds a few variables to the `msg` table for your convenience. These are self-explanatory: `msg.from.id_str`, `msg.to.id_str`, `msg.chat.id_str`, `msg.text_lower`, `msg.from.name`.
Return values from `action()` are optional, but they do effect the flow. If it returns a table, that table will become `msg`, and `on_msg_receive` will continue with that. If it returns `true`, it will continue with the current `msg`.
When an action or cron function fails, the exception is caught and passed to the `handle_exception()` utilty (in utilities.lua) and is either printed to the console or send to the chat/channel defined in `log_chat` in config.lua.
Interactions with the bot API are straightforward. Every binding function shares the name of the API method (eg `sendMessage()`). An additional function, `sendReply()`, accepts the `msg` table and a string as an argument, and sends the string as a reply to that message.
Several functions used in multiple plugins are defined in utilities.lua. Refer to that file for usage and documentation.
* * *
## administration.lua
## Control plugins {#Control_plugins}
Some plugins are designed to be used by the bot's owner. Here are some examples, how they're used, and what they do.
| Plugin | Command | Function |
|:-------|:--------|:---------|
| control.lua | /reload | Reloads all plugins and configuration. |
| control.lua | /halt | Saves the database and shuts down the bot properly. |
| blacklist.lua | /blacklist | Allows the admin to list people the bot will ignore. |
| shell.lua | /run | Executes shell commands on the host operating system. |
| luarun.lua | /lua | Executes Lua commands in the bot's environement. |
* * *
## administration.lua {#administration.lua}
The administration plugin enables self-hosted, single-realm group administration, supporting both normal groups and supergroups. This works by sending TCP commands to an instance of tg running on the owner's account.
To get started, run `./tg-install.sh`. Note that this script is written for Ubuntu/Debian. If you're running Arch (the only acceptable alternative), you'll have to do it yourself. If that is the case, note that otouto uses the "test" branch of tg, and the AUR package `telegram-cli-git` will not be sufficient, as it does not have support for supergroups yet.
@ -70,10 +80,11 @@ Once the installation is finished, enable `administration.lua` in your config fi
While tg is running, you may start/reload otouto with administration.lua enabled, and have access to a wide variety of administrative commands and automata. The administration "database" is stored in `administration.json`. To start using otouto to administrate a group (note that you must be the owner (or an administrator)), send `/gadd` to that group. For a list of commands, use `/ahelp`. Below I'll describe various functions now available to you.
| Command | Function | Privilege | Internal? |
|---------|----------|-----------|-----------|
|:--------|:---------|:----------|:----------|
| /groups | Returns a list of administrated groups (except those flagged "unlisted". | 1 | N |
| /ahelp | Returns a list of administrative commands and their required privileges. | 1 | Y |
| /ops | Returns a list of moderators, governors, and administrators. | 1 | Y |
| /desc | Returns the link, rules, MOTD, and enabled flags of a group. | 1 | Y |
| /rules | Returns the rules of a group. | 1 | Y |
| /motd | Returns a group's "Message of the Day". | 1 | Y |
| /link | Returns the link for a group. | 1 | Y |
@ -81,6 +92,7 @@ While tg is running, you may start/reload otouto with administration.lua enabled
| /kick | Removes the target from the group. | 2 | Y |
| /ban | Bans the target from the group. | 2 | Y |
| /unban | Unbans the target from the group. | 2 | Y |
| /changerule | Changes an individual group rule. | 3 | Y |
| /setrules | Sets the rules for a group. | 3 | Y |
| /setmotd | Sets a group's "Message of the Day". | 3 | Y |
| /setlink | Sets a group's link. | 3 | Y |
@ -89,8 +101,8 @@ While tg is running, you may start/reload otouto with administration.lua enabled
| /demod | Demotes a moderator to a user. | 3 | Y |
| /gov | Promotes a user to a governor. | 4 | Y |
| /degov | Demotes a governor to a user. | 4 | Y |
| /hammer | Bans a user from all groups. | 4 | N |
| /unhammer | Removes a global ban. | 4 | N |
| /hammer | Bans a user globally, and blacklists him. | 4 | N |
| /unhammer | Removes a user's global ban, and unblacklists him. | 4 | N |
| /admin | Promotes a user to an administrator. | 5 | N |
| /deadmin | Demotes an administrator to a user. | 5 | N |
| /gadd | Adds a group to the administrative system. | 5 | N |
@ -99,10 +111,10 @@ While tg is running, you may start/reload otouto with administration.lua enabled
Internal commands can only be run within an administrated group.
###Description of Privileges
### Description of Privileges
| # | Title | Description | Scope |
|------|-------|-------------|-------|
|:-:|:------|:------------|:------|
| 0 | Banned | Cannot enter the group(s). | Either |
| 1 | User | Default rank. | Local |
| 2 | Moderator | Can kick/ban/unban users from a group. | Local |
@ -112,10 +124,10 @@ Internal commands can only be run within an administrated group.
Obviously, each greater rank inherits the privileges of the lower, positive ranks.
###Flags
### Flags
| # | Name | Description |
|---|------|-------------|
|:-:|:----:|:-----------:|
| 1 | unlisted | Removes a group from the /groups listing. |
| 2 | antisquig | Automatically removes users for posting Arabic script or RTL characters. |
| 3 | antisquig Strict | Automatically removes users whose names contain Arabic script or RTL characters. |
@ -123,20 +135,17 @@ Obviously, each greater rank inherits the privileges of the lower, positive rank
* * *
##Liberbot Plugins
# Liberbot-related plugins {#Liberbot-related_plugins}
**Note:** This section may be out of date. The Liberbot-related plugins have not changed in very long time.
Some plugins are only useful when the bot is used in a Liberbot group, like floodcontrol.lua and moderation.lua.
**floodcontrol.lua** makes the bot compliant with Liberbot's floodcontrol function. When the bot has posted too many messages to a single group in a given period of time, Liberbot will send it a message telling it to cease posting in that group. Here is an example floodcontrol command:
`/floodcontrol {"groupid":987654321,"duration":600}`
The bot will accept these commands from both Liberbot and the configured administrator.
**moderation.lua** allows the owner to use the bot to moderate a Liberbot realm, or set of groups. This works by adding the bot to the realm's admin group and making it an administrator.
You must configure the plugin in the "moderation" section of config.lua, in the following way:
```
```lua
moderation = {
admins = {
['123456789'] = 'Adam',
@ -149,64 +158,67 @@ moderation = {
Where Adam and Eve are realm administrators, and their IDs are set as their keys in the form of strings. admin_group is the group ID of the admin group, as a negative number. realm_name is the name of your Libebot realm.
Once this is set up, put your bot in the admin group and run /add and /modhelp to get started.
Where the key is the preconfigured response (where #NAME will be replaced with the user's name or nickname) and the strings in the table are the expected greetings (followed by the bot's name and possible punctuation).
Once this is set up, put your bot in the admin group and run `/modadd` and `/modhelp` to get started.
* * *
##Setup
You **must** have Lua (5.2+), lua-socket, lua-sec, and lua-cjson installed. For uploading photos and other files, you must have curl installed. The fortune.lua plugin requires that fortune is installed.
## List of plugins {#List_of_plugins}
For weather.lua, lastfm.lua, and bible.lua to work, you must have API keys for [OpenWeatherMap](http://openweathermap.org), [last.fm](http://last.fm), and [Biblia.com](http://biblia.com), respectively. cats.lua uses an API key (via [The Cat API](http://thecatapi.com)) to get more results, though it is not required. apod.lua uses an API key (via [NASA API](https://api.nasa.gov/)) to have more queries per minute, though it is not required.
**Before you do anything, open config.lua in a text editor and make the following changes:**
> • Set bot_api_key to the authentication token you received from the Botfather.
>
> • Set admin as your Telegram ID.
You may also want to set your time_offset (a positive or negative number, in seconds, representing your computer's difference from UTC), your lang (lowercase, two-letter code representing your language), and modify your about_text. Some plugins will not be enabled by default, as they are for specific uses. If you want to use them, add them to the plugins table.
To start the bot, run `./launch.sh`. To stop the bot, press Ctrl+c twice.
You may also start the bot with `lua bot.lua`, but then it will not restart automatically.
| Plugin | Command | Function | Aliases |
|:-------|:--------|:---------|:--------|
| help.lua | /help | Returns a list of commands. | /h |
| about.lua | /about | Returns the about text as configured in config.lua. |
| ping.lua | /ping | The simplest plugin ever! |
| echo.lua | /echo <text> | Repeats a string of text. |
| gSearch.lua | /google <query> | Returns Google web results. | /g, /gnsfw |
| gImages.lua | /images <query> | Returns a Google image result. | /i, /insfw |
| gMaps.lua | /location <query> | Returns location data from Google Maps. | /loc |
| youtube.lua | /youtube <query> | Returns the top video result from YouTube. | /yt |
| wikipedia.lua | /wikipedia <query> | Returns the summary of a Wikipedia article. | /wiki |
| lastfm.lua | /np [username] | Returns the song you are currently listening to. |
| lastfm.lua | /fmset [username] | Sets your username for /np. /fmset -- will delete it. |
| hackernews.lua | /hackernews | Returns the latest posts from Hacker News. | /hn |
| imdb.lua | /imdb <query> | Returns film information from IMDb. |
| hearthstone.lua | /hearthstone <query> | Returns data for Hearthstone cards matching the query. | /hs |
| calc.lua | /calc <expression> | Returns solutions to math expressions and conversions between common units. |
| bible.lua | /bible <reference> | Returns a Bible verse. | /b |
| urbandictionary.lua | /urbandictionary <query> | Returns the top definition from Urban Dictionary. | /ud, /urban |
| time.lua | /time <query> | Returns the time, date, and a timezone for a location. |
| weather.lua | /weather <query> | Returns current weather conditions for a given location. |
| nick.lua | /nick <nickname> | Set your nickname. /nick - will delete it. |
| whoami.lua | /whoami | Returns user and chat info for you or the replied-to user. | /who |
| eightball.lua | /8ball | Returns an answer from a magic 8-ball. |
| dice.lua | /roll <nDr> | Returns RNG dice rolls. Uses D&D notation. |
| reddit.lua | /reddit [r/subreddit ¦ query] | Returns the top results from a given subreddit, query, or r/all. | /r |
| xkcd.lua | /xkcd [query] | Returns an xkcd strip and its alt text. |
| slap.lua | /slap <target> | Gives someone a slap (or worse). |
| commit.lua | /commit | Returns a commit message from whatthecommit.com. |
| fortune.lua | /fortune | Returns a UNIX fortune. |
| pun.lua | /pun | Returns a pun. |
| pokedex.lua | /pokedex <query> | Returns a Pokedex entry. | /dex |
| currency.lua | /cash [amount] <currency> to <currency> | Converts one currency to another. |
| cats.lua | /cat | Returns a cat picture. |
| reactions.lua | /reactions | Returns a list of reaction emoticons which can be used through the bot. |
| apod.lua | /apod [date] | Returns the NASA Astronomy Picture of the Day. |
| dilbert.lua | /dilbert [date] | Returns a Dilbert strip. |
| patterns.lua | /s/<from>/<to>/ | Fixed that for you. :^) |
* * *
##Development
Everybody is free to contribute to otouto. Here I will explain various things that are important to know about the plugin system.
## Contributors {#Contributors}
Everybody is free to contribute to otouto. If you are interested, you are invited to fork the [repo](http://github.com/topkecleon/otouto) and start making pull requests.. If you have an idea and you are not sure how to implement it, open an issue or bring it up in the Bot Development group.
A plugin can have five components, and three of them are optional: action, triggers, doc, command, and cron.
The creator and maintainer of otouto is [topkecleon](http://github.com/topkecleon). He can be contacted via [Telegram](http://telegram.me/topkecleon), [Twitter](http://twitter.com/topkecleon), or [email](mailto:drew@otou.to).
| Component | Description | Optional? |
|-----------|-------------|-----------|
| action | The main function of a plugin. It accepts the `msg` table. | No. |
| triggers | A table of strings which, when one is matched in a message's text, will cause `action` to be run. | No. |
| doc | The help text to be returned when a plugin is run with improper syntax or arguments. | Yes |
| command | The command with its syntax, without the slash. This is used to generate the help text. | Yes |
| cron | A function to be run every five seconds. | Yes |
There are a a few ways to contribute if you are not a programmer. For one, your feedback is always appreciated. Drop me a line on Telegram or on Twitter. Secondly, we are always looking for new ideas for plugins. Most new plugins start with community input. Feel free to suggest them on Github or in the Bot Dev group. You can also donate Bitcoin to the following address:
`1BxegZJ73hPu218UrtiY8druC7LwLr82gS`
The on_msg_receive function adds a few variables to the "msg" table: msg.from.id_str, msg.to.id_str, msg.text_lower. These are self-explanatory and can make your code a lot neater.
Return values from the action function are optional, but when they are used, they determine the fate of the message. When false/nil is returned, on_msg_receive stops and the script moves on to waiting for the next message. When true is returned, on_msg_receive continues going through the plugins for a match. When a table is returned, that table becomes the "msg" table, and on_msg_receive continues.
When a plugin action or cron function fails, the script will catch the error and print it, and, if applicable, the text which triggered the plugin, and continue.
* * *
Interactions with the Telegram bot API are straightforward. Every function is named the same as the API method it utilizes. The order of expected arguments is laid out in bindings.lua.
There are three functions which are not API methods: sendRequest, curlRequest, and sendReply. The first two are used by the other functions. sendReply is used directly. It expects the "msg" table as its first argument, and a string of text as its second. It will send a reply without image preview to the initial message.
* * *
Several functions and methods used by multiple plugins and possibly the main script are kept in utilities.lua. Refer to that file for documentation.
* * *
##Contributors
The creator and maintainer of otouto is [topkecleon](http://github.com/topkecleon). He can be contacted via [Telegram](http://telegram.me/topkecleon), [Twitter](http://twitter.com/topkecleon), or [email](mailto:topkecleon@outlook.com).
Other developers who have contributed to otouto are [Juan Potato](http://github.com/JuanPotato), [Tiago Danin](http://github.com/TiagoDanin), [Ender](http://github.com/luksireiku), [Iman Daneshi](http://github.com/Imandaneshi), and [HeitorPB](https://github.com/heitorPB).
Contributions are appreciated in any form. Monetary contributions will go toward server costs. Both programmers and donators will be eternally honored (at their discretion) on this page.
| Developers | Donators |
|:-----------|:---------|
| [Juan Potato](http://github.com/JuanPotato) | [n8](http://telegram.me/n8_c00) |
| [Tiago Danin](http://github.com/TiagoDanin) | [Alex](http://telegram.me/sandu) |
| [Ender](http://github.com/luksireiku) | [Brayden Banks](http://telegram.me/bb010g) |
| [Iman Daneshi](http://github.com/Imandaneshi) |
| [HeitorPB](https://github.com/heitorPB) |

13
bot.lua
View File

@ -33,8 +33,7 @@ bot_init = function() -- The function run when the bot is started or reloaded.
math.random()
last_update = last_update or 0 -- Set loop variables: Update offset,
last_cron = last_cron or os.time() -- the time of the last cron job,
last_db_save = os.date('%M', os.time())
last_cron = last_cron or os.date('%M', os.time()) -- the time of the last cron job,
is_started = true -- and whether or not the bot should be running.
database.usernames = database.usernames or {} -- Table to cache usernames by user ID.
@ -100,8 +99,9 @@ while is_started do -- Start a loop while the bot should be running.
print(config.errors.connection)
end
if last_cron < os.time() - 5 then -- Run cron jobs if the time has come.
last_cron = os.time() -- Update the timer variable.
if last_cron ~= os.date('%M', os.time()) then -- Run cron jobs every minute.
last_cron = os.date('%M', os.time())
save_data('otouto.db', database) -- Save the database.
for i,v in ipairs(plugins) do
if v.cron then -- Call each plugin's cron function, if it has one.
local res, err = pcall(function() v.cron() end)
@ -110,11 +110,6 @@ while is_started do -- Start a loop while the bot should be running.
end
end
end
-- Save the database.
if last_db_save ~= os.date('%M', os.time()) then
last_db_save = os.date('%M', os.time())
save_data('otouto.db', database)
end
end
end

View File

@ -1117,10 +1117,7 @@ local action = function(msg) -- wee nesting
end
local cron = function()
if os.date('%M', os.time()) ~= last_admin_cron then
last_admin_cron = os.date('%M', os.time())
tg = sender(localhost, config.cli_port)
end
tg = sender(localhost, config.cli_port)
end
local command = 'groups'

View File

@ -5,7 +5,7 @@ Returns a location from Google Maps.
Alias: /loc
```]]
triggers = {
local triggers = {
'^/location[@'..bot.username..']*',
'^/loc[@'..bot.username..']* ',
'^/loc[@'..bot.username..']*$'