diff --git a/.gitignore b/.gitignore
index 96506f5..ab753e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ config.php
pic/
old/
vendor/
+cache/
diff --git a/00-app-create.php b/00-app-create.php
new file mode 100644
index 0000000..a598bd9
--- /dev/null
+++ b/00-app-create.php
@@ -0,0 +1,26 @@
+build()
+ ->setBaseUri('https://'.$conf['instance']);
+
+// create an app and get app based authorization:
+$app = $client->methods()->apps()->create(
+ 'Admin Bot',
+ ['https://admin.piaille.fr/callback.php'],
+ 'read write admin:read admin:write',
+ 'https://piaille.fr',
+);
+
+if (!isset($app->client_id, $app->client_secret)) {
+ exit('could not create app!');
+}
+
+echo "client_id: ".$app->client_id."\n";
+echo "client_secret: ".$app->client_secret."\n";
+echo "set them in config.php\n";
diff --git a/01-inscription-mastodon.php b/01-inscription-mastodon.php
new file mode 100644
index 0000000..54fe951
--- /dev/null
+++ b/01-inscription-mastodon.php
@@ -0,0 +1,24 @@
+build()
+ ->setBaseUri('https://'.$conf['instance']);
+
+// get user based authorization:
+// generate authorize url
+// (we'll reuse the app created above)
+$authUrl = $client->getAuthorizeUrl(
+ 'code',
+ $conf['client_id'],
+ 'https://admin.piaille.fr/callback.php',
+ 'read write admin:read admin:write',
+);
+
+// redirect user to this url, where they can log in:
+echo "URL: ".$authUrl."&state=".$argv[1]."\n";
+
diff --git a/02-get-access-token.php b/02-get-access-token.php
new file mode 100644
index 0000000..7a24b9d
--- /dev/null
+++ b/02-get-access-token.php
@@ -0,0 +1,23 @@
+build()
+ ->setBaseUri('https://'.$conf['instance']);
+
+$code=$argv[1];
+
+// obtain a token using this code:
+$token = $client->methods()->oauth()->token(
+ 'authorization_code', // NB: different from app token call above!
+ $code,
+ $conf['client_id'],
+ $conf['client_secret'],
+ 'https://admin.piaille.fr/callback.php',
+ null,
+ 'read write admin:read admin:write',
+);
+echo "TOKEN: ".$token->access_token."
\n";
diff --git a/job-auto-suspend-account.php b/job-auto-suspend-account.php
new file mode 100644
index 0000000..54e03f5
--- /dev/null
+++ b/job-auto-suspend-account.php
@@ -0,0 +1,60 @@
+build()
+ ->setBaseUri('https://'.$conf['instance']);
+$client->setAccessToken($conf['token']);
+
+$badidfile=__DIR__."/cache/latest-auto-suspend-id";
+//$pending = $client->methods()->admin()->accounts()->v2('local','pending');
+
+// get 1000 recent statuses from the latest we had and search for bad message patterns :
+
+if (is_file($badidfile))
+ $latest=intval(file_get_contents($badidfile));
+else
+ $latest=0;
+
+echo "starting at $latest\n";
+
+$suspend_stmt = $db->prepare('SELECT username,domain, suspended_at from accounts WHERE id=?');
+
+$sql= 'select id, account_id, text from statuses ';
+if ($latest) $sql.=' WHERE id> '.$latest.' ';
+$sql.=' order by id desc limit 10000;';
+
+$stmt = $db->prepare($sql);
+$stmt->execute();
+$first=true;
+while ($status = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ if ($first) $latest=$status['id'];
+
+ if (preg_match('#/share.google#',$status['text'])) {
+ preg_match_all('#mention">@([^<]*)#',$status['text'],$mat);
+ if (isset($mat[1]) && count($mat[1])>10) {
+ // more than 10 mentions + /share.google = suspend this account.
+ $suspend_stmt->execute([$status['account_id']]);
+ $badboy = $suspend_stmt->fetch(PDO::FETCH_ASSOC);
+ if (!$badboy) {
+ echo "WEIRD: found account ".$status['account_id']." in the statuses but not in the DB !\n";
+ continue;
+ }
+
+ if ($badboy['suspended_at']) {
+ echo "found account ".$badboy['username']."@".$badboy['domain']." but already suspended, skip\n";
+ } else {
+ echo "found account ".$badboy['username']."@".$badboy['domain']." will suspend it\n";
+ $client->methods()->admin()->accounts()->action( id: $status['account_id'], type: 'suspend', text: 'Automatic suspention from the Admin Bot Case #1');
+ }
+
+ }
+
+ }
+ $first=false;
+}
+
+file_put_contents($badidfile,$latest);
diff --git a/job-refuse-auto-subscription.php b/job-refuse-auto-subscription.php
new file mode 100644
index 0000000..8bc98f2
--- /dev/null
+++ b/job-refuse-auto-subscription.php
@@ -0,0 +1,70 @@
+build()
+ ->setBaseUri('https://'.$conf['instance']);
+$client->setAccessToken($conf['token']);
+
+$pending = $client->methods()->admin()->accounts()->v2('local','pending');
+// pending is now a Vazaha\Mastodon\Results\Admin\AccountResult whose "items" are Vazaha\Mastodon\Models\Admin\AccountModel Objects
+//print_r($pending);
+
+
+$roles=[
+ 0 => '_unknown_ ',
+ 1 => 'hosting ',
+ 3 => 'cdn ',
+ 4 => 'land isp ',
+ 5 => 'reserved ',
+ 6 => 'mobile isp',
+ 8 => 'commercial',
+ 9 => 'government',
+ 10 => 'university',
+];
+
+if (!($pending instanceof Vazaha\Mastodon\Results\Admin\AccountResult)) {
+ echo "Pending is not a AccountResult, weird\n";
+ print_r($pending);
+ exit();
+}
+
+// now scan all the results and refuse the one we want to refuse:
+// if we have a account request with more than 20 character from any of those maps, we refuse the account request:
+$refuse_map=[
+ "ru" => "абвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЭЮЯ",
+ "ar" => "ﺍﺎبﺏﺐﺒﺑتﺕﺖﺘﺗثﺙﺚﺜﺛجﺝﺞﺠﺟحﺡﺢﺤﺣخﺥﺦﺨﺧدﺩﺪذﺫﺬرﺭﺮزﺯﺰسﺱﺲﺴﺳشﺵﺶﺸﺷصﺹﺺﺼﺻضﺽﺾﻀﺿطﻁﻂﻄﻃظﻅﻆﻈﻇعﻉﻊﻌﻋغﻍﻎﻐﻏفﻑﻒﻔﻓقﻕﻖﻘﻗكﻙﻚﻜﻛلﻝﻞﻠﻟمﻡﻢﻤﻣنﻥﻦﻨﻧﻩﻪﻬوﻭﻮيﻱﻲﻴﻳآﺁﺂةﺓﺔىﻯﻰ"
+];
+
+
+foreach ($pending as $account) {
+ if ($account->invite_request=="Automated protocol deliverability probe") {
+ echo "Will REFUSE immediately this automated account: ".$account->username."\n";
+ $client->methods()->admin()->accounts()->reject($account->id);
+ } else {
+
+ echo "Pending account ".$account->username." ID ".$account->id."\n";
+ echo "Languager: ".$account->locale." Reason: ".$account->invite_request."\n";
+ echo "IP: ".$account->ip." (info: ".ipinfo($account->ip)."\n";
+ echo "\n";
+ }
+ // $client->methods()->admin()->accounts()->reject($account->id);
+}
+
+
+function ipinfo($ip) {
+ global $roles;
+ $res=json_decode(file_get_contents('https://waf1.octopuce.fr/ipinfo.php?ip='.$ip),true);
+ $s="";
+ $s .= "role: ".($roles[($res['role']??0)]??' ')." ";
+ $s .= "ip: $ip ";
+ $s .= "country: ".($res['country']??'unknown')." ";
+ $s .= "score: ".($res['score']??0)." ";
+ $s .= "prefix: ".($res['rdap']??'unknown')." ";
+ $s .= "isp: ".($res['isp']??'unknown')." ";
+ if (isset($res['whitelisted']) && $res['whitelisted']) $s .= "WHITELISTED! ";
+ return $s;
+}