Idefix is a CLI php script that listens on a defined set of Mastodon on-demand follow bots for commands in toots they receive and, according to the commands, makes the receiving bot account follow or unfollow the sender’s account.

pezcurrel e64f0fde8e Updated to help text as in e64f77b commit 1 month ago
README.md e64f0fde8e Updated to help text as in e64f77b commit 1 month ago
idefix e64f77b45d Fixed a bug introduced in commands parser in previous commit 1 month ago

README.md

[[[  SYNOPSIS  ]]]

idefix [options] <project directory>

[[[  DESCRIPTION  ]]]

This is idefix v0.9.4, a CLI php script that listens on a defined set of
Mastodon on-demand follow bots for commands in toots they receive and,
according to the commands, makes the receiving bot account follow or unfollow
the sender’s account. This gives users of the defined set of Mastodon
instances the possibility to make sure their public toots will appear on the
«federated timeline» of any other instance in the set, helping them to reach
other users outside their instance, if they want to.
In order to be considered, the toots coming to any bot account must come from
an instance among those in the defined bot accounts set (see section «BOTS
CONFIG FILE» below), *except* the same instance the bot account resides on,
and they must not come from an account marked as «bot»; the incoming toot can
have any visibility (the receiving bot account will answer with a toot with
the same visibility) and can be written in english or italian language (if the
received toot’s language is italian, the bot account will answer in italian;
otherwise it will answer in english); the toot’s content must follow the
command syntax specified in the «COMMANDS» section towards the end of this
help text.
Idefix will also periodically post a configurable public announcement toot
from each defined bot account, in turn (the periodicity is configurable and
announcement toots can be disabled, see the «--annint» option description in
the «OPTIONS» section below). These announcement toots will be delivered to
all the federated timelines of all the instances which host a defined bot
account, because idefix makes sure that each defined bot account follows each
other.
Idefix can be stopped at any time with a SIGTERM, SIGHUP or SIGINT (ctrl+c)
signal without problems: it will nicely shut down and, on subsequent run, it
will «begin where it stopped».
In order for idefix to work, an existing «project directory» has to be passed
as an argument to it.

[[[  BOTS CONFIG FILE  ]]]

The «project directory» must contain a file named «idefix.botsconf». This file
should contain the accounts definitions (at least 2), one definition for each
line (empty lines and lines with an «#» character on their first column will
be ignored).
Each account definition should follow this syntax:

<account> <domain handle> <max toot length> <token>

- «account» should be the full Mastodon address of the bot’s account;
- «domain handle» should be an handle for the domain the bot’s account resides
on; for example, the handle for «mastodon.cisti.org» could be «cisti» (or
anything else); this is used in some template types, see the «TEMPLATES»
section below;
- «max toot length» should be the maximum length a toot can have on the
instance the bot’s account resides on; this value will be used to check each
toot (and each profile’s «bio», when «--setprof» option is used: see the
«OPTIONS» section below) before it is sent;
- «token» should be the access token of an «application» that has already been
created on the account (via «Preferences» -> «Development» -> «New
application», in the official Mastodon web frontend) with at least «read»,
«write» and «follow» privileges.

--- Example «idefix.botsconf» file ---
# These lines will be ignored, since they are commented out by a «#» at their
# beginning; next line will be ignored too, since it’s empty.

follbot@amarone.net amarone 500 xA9kZe9zB6EgtjsW5EVr4axYWW46c1TPC-RpQhnkAvw
follbot@nebbiolo.org nebbiolo 550 7fne902mc0954mi2ollWMNfasdf6aposdfADF9MFN12
follbot@ostrugo.info ostrugo 840 0XJfrQ2C9ddzB9H3brTcwt-afo3ZOpTN4jmZbQrPoO8
follbot@dolcetto.fail dolcetto 500 Gm3lvO4LxwaXkmhW_q6VSvcBkj_05N0bvJc0TlwnTkw
follbot@barbera.info barbera 600 l8r3kQynViz2BHw5NKBw7GajnkrSCDeqTI58KUfs6X2
--- End of example «idefix.botsconf» file ---

[[[  OPTIONS  ]]]

Options can be specified on command line and in a «idefix.conf» file inside
the «project directory» (see the «CONFIG FILE» section below). Options
specified on command line always supersede those specified in the config file.

-s, --sleepsecs <amount of seconds>
 Set the amount of seconds idefix will pause for after checking for new
 toots on all defined accounts.
 DEFAULT: 10 seconds.

-a, --annint <time specification>
 Set the interval for periodic announcement toot sending.
 EXAMPLE: «idefix -a 1d,10h,12m,30s» will set the interval to 1 day,
 10 hours, 12 minutes and 30 seconds (123150 seconds).
 Setting this option to the «never» special value will completely disable
 announcements.
 DEFAULT: 6 hours.

-r, --resetlats <boolean: true/t/yes/y/1=true, false/f/no/n/0=false>
 If set to true this option sets the recorded «last announcement timestamp»
 to the current time.
 DEFAULT: false

-b, --botsmasteraddr <bots’ master address>
 Set the «bots’ master» address. It has a corresponding
 «%bots_master_address%» template keyword that can be used in any template,
 see the «TEMPLATES» section below.
 DEFAULT: obelix@livellosegreto.it

-e, --enhelpurl <url>
 Set the url for english help (it is used in some reply toots and has
 a corresponding template keyword, «%en_help_url%»; see the «TEMPLATES»
 section below).
 DEFAULT: https://git.lattuga.net/pongrebio/idefix/wiki/Help

-i, --ithelpurl <url>
 Set the url for italian help (it is used in some reply toots and has
 a corresponding template keyword, «%it_help_url%»; see the «TEMPLATES»
 section below).
 DEFAULT: https://git.lattuga.net/pongrebio/idefix/wiki/Guida

-p, --setprof <«builtin»|profile configuration file name>
 Set every defined bot account’s profile «bot» flag, «bio» field and metadata
 «key-value» pairs, then exit. If the «builtin» special value is passed,
 these profile’s properties will be set according to the builtin
 configuration (see below), otherwise they will be set according to the
 configuration defined in a file inside the defined «project directory», with
 «profile configuration file name» and with «.profconf» extension.
 For example, if you created a profile configuration file named «my.profconf»
 in the «project directory», you could pass «my» as «profile configuration
 file name» to «--setprof».
 --- Example profile configuration file ---
 bot=true
 bio=Hello, I’m %current_bot_address%, managed by %bots_master_address%.
 md=Bots master : %bots_master_profile_url%
 md=Help : %en_help_url%
 --- End of example profile configuration file ---
 The profile configuration file must define a «bot» entry and a «bio» entry;
 it can also define one ore more «md» entries. The «bot» entry has to be set
 to a boolean value (true/t/yes/y/1=true, false/f/no/n/0=false); the «bio»
 entry has to be set to a bio text, that will be treated as a template (see
 section «TEMPLATES» below); each defined «md» entry can be set to
 «key : value» pairs (that is, «value» must be separated from «key» by a « : »
 string - both «key» and «value» text will be treated as templates); otherwise
 it can be set to the «delete» special expression. If no «md» entry is
 defined, all the metadata «key-value» pairs on every defined bot account’s
 profile will be left untouched; if one or more «md» entries are defined, all
 current metadata «key-value» pairs on every profile will be deleted and the
 defined ones will be set; if *any* defined «md» entry is set to «delete», all
 the profiles’ metadata fields will be deleted.
 --- Builtin profile configuration ---
 bot=true
 bio=Woof! I’m the Idefix bot on %current_bot_domain%, I am managed by\
 %bots_master_address%, if your account is on %bots_domains-or%, and if you\
 want me to follow you, to make sure your public toots will reach\
 %current_bot_domain_handle%’s federated timeline, at any time you can send\
 me a toot with the «follow me» command (I also understand the «unfollow me»\
 command). For more info just see %en_help_url% ;-)
 md=Bots master : %bots_master_profile_url%
 --- End of builtin profile configuration ---

-U, --unfollowall
 Unfollow *every* account, except the other defined idefix bot accounts,
 from *every* defined bot account.

-f, --force <boolean: true/t/yes/y/1=true, false/f/no/n/0=false>
 If set to true, it forces execution even if a lockfile exists in «project
 directory».
 DEFAULT: false

-v, --verbose <boolean: true/t/yes/y/1=true, false/f/no/n/0=false>
 If set to true, idefix will output a lot of informational messages about
 what it’s doing on STDOUT (all warning and error messages are always written
 to STDERR; all messages are always recorded into a «idefix.log» file
 inside the defined «project directory»).
 DEFAULT: false

-h, --help
 Show this help text and exit.

[[[  CONFIG FILE  ]]]

The «project directory» can contain a file named «idefix.conf» with
«option=argument» pairs, one for each line. «Option» can be any option in its
long form except «help», «setprof» and «unfollowall», «argument» must be a
valid argument for the option. Remember that any option specified on command
line supersede those specified in the config file.

--- Example «idefix.conf» file ---
# These lines will be ignored, since they are commented out by a «#» at their
# beginning; next line will be ignored too, since it’s empty.

verbose=true
sleepsecs=20
annint=3h
enhelpurl=https://x.org/mybot/help_en
ithelpurl=https://x.org/mybot/help_it
--- End of example «idefix.conf» file ---

[[[  TEMPLATES  ]]]

You can customize any template idefix uses to build its output by creating a
file named «idefix.templates» in the «project directory».
Currently defined templates are:

--- Templates list ---
Template: announcement
Description: The announcement toot
Default: Woof! I’m Idefix, from my %current_bot_address% account. If your
account is on %domains_handles_but_current-or%, and if you want me to follow
you to make sure your public toots will reach %current_bot_domain_handle%’s
federated timeline, at any time you can issue me with a «follow me» command in
a toot with any visibility, even in reply to this one. I also understand
«unfollow me» and other, more articulated commands. For more info see
%en_help_url% ;-)

Template: generic_salutation-en
Description: This text is the generic salutation used at the beginning of any
toot in reply to any request toot (english version); it *must* contain
«@%sender_address», otherwise all reply toots will be sent to the void ;-)
Default: Woof @%sender_address%

Template: generic_salutation-it
Description: This text is the generic salutation used at the beginning of any
toot in reply to any request toot (italian version); it *must* contain
«@%sender_address», otherwise all reply toots will be sent to the void ;-)
Default: Bau @%sender_address%

Template: not_from_same_instance-en
Description: This text is the final part of the toot that is sent in reply to
any request toot coming from the same instance as the bot’s one (english
version)
Default: I can’t consider toots from my own instance, %current_bot_domain% ;-)

Template: not_from_same_instance-it
Description: This text is the final part of the toot that is sent in reply to
any request toot coming from the same instance as the bot’s one (italian
version)
Default: non posso considerare i toot dalla mia stessa istanza,
%current_bot_domain% ;-)

Template: not_from_same_instance-multi-en
Description: This text is the final part of the toot that is sent in reply to
any request toot that mentions the same instance as the bot’s one among those
the sender wants to be followed from (english version)
Default: I did nothing because I can’t follow you from your own instance,
%sender_domain% ;-)

Template: not_from_same_instance-multi-it
Description: This text is the final part of the toot that is sent in reply to
any request toot that mentions the same instance as the bot’s one among those
the sender wants to be followed from (italian version)
Default: non ho fatto nulla perché non posso seguirti dalla tua stessa
istanza, %sender_domain% ;-)

Template: unsupported_instance-en
Description: This text is the final part of the toot that is sent in reply to
any request toot coming from an unsupported instance (english version)
Default: I can’t consider your toot since you are on an unsupported instance.
Instances I support are %bots_domains-and%.

Template: unsupported_instance-it
Description: This text is the final part of the toot that is sent in reply to
any request toot coming from an unsupported instance (italian version)
Default: non posso considerare il tuo toot perché viene da un’istanza non
supportata. Le istanze che supporto sono %bots_domains-e%.

Template: not_from_other_bots-en
Description: This text is the final part of the toot that is sent in reply to
any request toot coming from an account that has the «bot» profile property
enabled (english version)
Default: I’m sorry but I can’t consider toots coming from other bot accounts.

Template: not_from_other_bots-it
Description: This text is the final part of the toot that is sent in reply to
any request toot coming from an account that has the «bot» profile property
enabled (italian version)
Default: mi spiace ma non posso considerare i toot da altri account bot.

Template: follow_success-en
Description: This text is the «success» part of the toot that is sent in reply
to a «follow me» command toot (english version)
Default: I’m following you from

Template: follow_success-it
Description: This text is the «success» part of the toot that is sent in reply
to a «follow me» command toot  (italian version)
Default: ti sto seguendo da

Template: follow_failure-en
Description: This text is the «failure» part of the toot that is sent in reply
to a «follow me» command toot (english version)
Default: due to technical problems I could not follow you from

Template: follow_failure-it
Description: This text is the «failure» part of the toot that is sent in reply
to a «follow me» command toot (italian version)
Default: a causa di problemi tecnici non sono riuscito a seguirti da

Template: unfollow_success-en
Description: This text is the «success» part of the toot that is sent in reply
to an «unfollow me» command toot (english version)
Default: I am no longer following you from

Template: unfollow_success-it
Description: This text is the «failure» part of the toot that is sent in reply
to an «unfollow me» command toot (italian version)
Default: non ti sto più seguendo da

Template: unfollow_failure-en
Description: This text is the «failure» part of the toot that is sent in reply
to an «unfollow me» command toot (english version)
Default: due to technical problems I couldn’t unfollow your account from

Template: unfollow_failure-it
Description: This text is the «failure» part of the toot that is sent in reply
to an «unfollow me» command toot (italian version)
Default: a causa di problemi tecnici non sono riuscito ad unfolloware il tuo
account da

Template: syntax_error-en
Description: This text is the final part of the toot that is sent in reply to
any malformed command toot (english version)
Default: I couldn’t understand what you wrote in your toot, if you want to
know which commands I understand please read here: %en_help_url% :-)

Template: syntax_error-it
Description: This text is the final part of the toot that is sent in reply to
any malformed command toot (italian version)
Default: non sono riuscito a capire quel che mi hai scritto nel tuo toot, se
vuoi sapere che comandi capisco per favore leggi qui: %it_help_url% :-)

Template: wrong_instance_spec-en
Description: This text is part of any toot that is sent to any (un)follow
request toot with unknown (wrong) instance reference(s), and it can be
followed by a «: » and a list of such wrong instance references (english
version)
Default: I couldn’t recognize some of the instance references in your toot

Template: wrong_instance_spec-it
Description: This text is part of any toot that is sent to any (un)follow
request toot with unknown (wrong) instance reference(s), and it can be
followed by a «: » and a list of such wrong instance references (italian
version)
Default: non riconosco alcuni dei riferimenti a istanze che hai fatto nel tuo
toot
--- End of templates list ---

Idefix currently recognizes and expands the following keywords in templates:

--- Template keywords list ---
%rn%
 expands to a «new line characters combo» («\r\n»): text will wrap there

%en_help_url%
 expands to currently set url for english help (see option «--enhelpurl»)

%it_help_url%
 expands to currently set url for italian help (see option «--ithelpurl»)

%sender_address%
 expands to the sender’s full Mastodon address; only available in reply toots,
 not in announcement toots

%sender_domain%
 expands to the sender’s instance domain; only available in reply toots, not
 in announcement toots

%bots_master_address%
 expands to the currently set «botsmasteraddr» option

%bots_master_profile_url%
 expands to the bots master Mastodon profile url according to the currently
 set «botsmasteraddr» option

%current_bot_address%
 expands to the currently considered bot’s full Mastodon address

%current_bot_profile_url%
 expands to the currently considered bot’s profile url

%current_bot_username%
 expands to the currently considered bot’s username

%current_bot_domain%
 expands to the currently considered bot’s domain

%current_bot_domain_handle%
 expands to the currently considered bot’s instance’s handle

%domains_handles-or%
 expands to a list of all instances handles separated by «, », with last two
 separated by « or »

%domains_handles-and%
 expands to a list of all instances handles separated by «, », with last two
 separated by « and »

%domains_handles-o%
 expands to a list of all instances handles separated by «, », with last two
 separated by « o » («o» is the italian word for «or»)

%domains_handles-e%
 expands to a list of all instances handles separated by «, », with last two
 separated by « e » («e» is the italian word for «and»)

%domains_handles_but_current-or%
 expands to a list of all instances handles, excluding the currently
 considered bot’s one, separated by «, », with last two separated by « or »

%domains_handles_but_current-and%
 expands to a list of all instances handles, excluding the currently
 considered bot’s one, separated by «, », with last two separated by « and »

%domains_handles_but_current_with-o%
 expands to a list of all instances handles, excluding the currently
 considered bot’s one, separated by «, », with last two separated by « o »

%domains_handles_but_current_with-e%
 expands to a list of all instances handles, excluding the currently
 considered bot’s one, separated by «, », with last two separated by « e »

%bots_addresses-or%
 expands to a list of all bots’ full Mastodon addresses separated by «, »,
 with last two separated by « or »

%bots_addresses-and%
 expands to a list of all bots’ full Mastodon addresses separated by «, »,
 with last two separated by « and »

%bots_addresses-o%
 expands to a list of all bots’ full Mastodon addresses separated by «, »,
 with last two separated by « o »

%bots_addresses-e%
 expands to a list of all bots’ full Mastodon addresses separated by «, »,
 with last two separated by « or »

%bots_addresses_but_current-or%
 expands to a list of all bots’ full Mastodon addresses, excluding the
 currently considered bot’s one, separated by «, », with last two separated
 by « or »

%bots_addresses_but_current-and%
 expands to a list of all bots’ full Mastodon addresses, excluding the
 currently considered bot’s one, separated by «, », with last two separated
 by « and »

%bots_addresses_but_current-o%
 expands to a list of all bots’ full Mastodon addresses, excluding the
 currently considered bot’s one, separated by «, », with last two separated
 by « o »

%bots_addresses_but_current-e%
 expands to a list of all bots’ full Mastodon addresses, excluding the
 currently considered bot’s one, separated by «, », with last two separated
 by « e »

%bots_domains-or%
 expands to a list of all bots’ domains separated by a «, », with last two
 separated by « or »

%bots_domain-and%
 expands to a list of all bots’ domains separated by a «, », with last two
 separated by « and »

%bots_domains-o%
 expands to a list of all bots’ domains separated by a «, », with last two
 separated by « o »

%bots_domains-e%
 expands to a list of all bots’ domains separated by a «, », with last two
 separated by « e »

%bots_domains_but_current-or%
 expands to a list of all bots’ domains, excluding the currently considered
 bot’s one, separated by a «, », with last two separated by « or »

%bots_domains_but_current-and%
 expands to a list of all bots’ domains, excluding the currently considered
 bot’s one, separated by a «, », with last two separated by « and »

%bots_domains_but_current-o%
 expands to a list of all bots’ domains, excluding the currently considered
 bot’s one, separated by a «, », with last two separated by « o »

%bots_domains_but_current-e%
 expands to a list of all bots’ domains, excluding the currently considered
 bot’s one, separated by a «, », with last two separated by « e »
--- End of template keywords list ---

Let’s make an example of «idefix.templates» template file (template
definitions are kept short in this example, so they don’t wrap in this help
text, but they can have any length).

--- Example «idefix.templates» file ---
# These lines will be ignored, since they are commented out by a «#» at their
# beginning; next line will be ignored too, since it’s empty.

announcement=Hello, I’m %current_bot_address%, an on-demand follow bot.
generic_salutation-en=Hello %sender_address%
follow_failure-en=some technical problems kept me from following you from
generic_salutation-it=Ciao %sender_address%
follow_failure-it=qualche problema tecnico mi ha impedito di seguirti da
--- End of example «idefix.templates» file ---

With this example template file and the example bots config file that you can
read in the «BOTS CONFIG FILE» section above, the announcement toot for the
first defined account would have this content: «Hello, I’m
follbot@amarone.net, an on-demand follow bot.», while the reply toot for a
failed attempt at following «someone@ostrugo.info» who sent a
«@follbot@nebbiolo.org follow me» from a client that was set to send toot in
english language would be «Hello @someone@ostrugo.info, some technical
problems kept me from following you from follbot@nebbiolo.org»; all other
templates will retain their default value.

[[[  COMMANDS  ]]]

A «command toot» should have this syntax:

<@bot_account> <command>

Idefix understands commands in english and italian language.
«Command» has this syntax:

<follow me|unfollow me>[ from <list of instances|«all[ instances]»>]
 In its simplest forms, «follow me» or «unfollow me», this command will make
 the recipient bot account follow or unfollow the sender’s account; in its
 extended form, «follow me from ...» or «unfollow me from ...», it will make
 the bots account on the specified instances follow or unfollow the sender’s
 account. The «list of instances» can contain both instances’ complete domains
 and handles; each one has to be separated from the following by at least one
 space, or by «,» and at least one space. If instead of or inside such a list
 of instances an «all» or «all instances» string is passed, the sender’s
 account will be followed or unfollowed from all the instances on which an
 «idefix account» is present and defined in the «BOTS CONFIG FILE», except the
 «idefix account» residing on the same instance as the sender’s.

<seguimi|non seguirmi[ più]>[ da <lista di istanze|«tutte[ le istanze]»>]
 Same as above, in italian language.

--- Example toot ---
@follbot@nebbiolo.org follow me from ostrugo.info, amarone
--- End of example toot ---

With the example bots config file that you can read in the «BOTS CONFIG FILE»
section above, this example toot, although addressed to follbot@nebbiolo.org,
would make the sender’s account be followed by follbot@ostrugo.info and
follbot@amarone.net.

[[[  FILES  ]]]

On every run, idefix writes informations in some files inside the defined
«project directory»; these files are:

«idefix.log»: the log file, storing all info about what idefix does;

«idefix.network»: the «network table» file, storing info about which defined
bot accounts each defined bot account is already following; on first run on
the defined «project directory» and every time idefix finds new bot accounts
definitions in the corresponding «idefix.botsconf» config file (see «BOTS
CONFIG FILE» section above), it makes (only) the necessary «cross-follows» to
ensure each bot account follow each other, and accordingly updates the
«idefix.network» file; you can force a complete «bot accounts network
reconstruction» on next idefix run by simply deleting this file;

«idefix.lastann»: in this file idefix stores the timestamp of the moment the
last «announcement» toot was sent and the address of the bot account it was
sent from (see «--annint» option explanation in the «OPTIONS» section above);

«*.bookmark»: in these files, each named after a defined bot account’s full
Mastodon address, idefix stores the account’s last seen notification id.

«idefix.lock»: this file is created at idefix start and normally deleted on
idefix exit; if this file exists when idefix gets started, idefix assumes
another idefix instance is already running on the «project directory» the lock
file is in, and exits with an error message before doing anything; if you know
for sure that no other idefix is running on that «project directory», you can
force idefix execution by using the «-f» or «--force» option, or by removing
the lock file.

[[[  EXIT VALUES  ]]]

0: regular run
1: initialization error
2: runtime error

[[[  DISCLAIMER AND LICENSE  ]]]

This program comes with ABSOLUTELY NO WARRANTY; for details see the source.
This is free software, and you are welcome to redistribute it under certain
conditions; see <http://www.gnu.org/licenses/> for details.