User Tools

Site Tools


lemmy-api-php

Lemmy API PHP Command Line Client

After the recent (June 2023) influx of Lemmy spam accounts, there isn't an easy way to delete the hundreds of spam accounts that showed up over night (before I felt forced to enable captchas and email verification etc).

I built a small API command line client to basically allow me to run the purgePerson API command easily in a loop.

You can run it very simply with something like this:

./lemmy-api.php purgePerson 116

or to iterate over a number of ids:

for i in 145 156 162; do ./lemmy-api.php purgePerson $i; done

and to work through all IDs from 170-240:

for i in `seq 170 240`; do ./lemmy-api.php purgePerson $i; done 

You can view the code on my repo at https://git.mckillop.org/gitweb/?p=lemmy-api-php or checkout directly with git using:

git clone https://git.mckillop.org/lemmy-api-php

Made a copy of the config file and edit config.php to add your domain, username and password to get started.

cd lemmy-api-php
cp config.example.php config.php

Here is some example code for a PHP command line tool that will let you purge local users.

config.php
<?php
$lemmy_domain = ""; // e.g. lemmy.ml
$username = "";
$password = "";
$token_file = ".lemmy-api-token"; // this is where your token is cached, can be any location
?>
lemmy-api.php
#!/usr/bin/php
<?php
require("config.php");
 
$implemented_commands = array(
        "purgePerson"   => "PERSONID [reason]",
        "deletePost"    => "POSTID"
);
 
if(empty($argv[1]) or empty($argv[2])) {
        echo "Usage: ./".basename(__FILE__)." COMMAND [parameters]\n";
        echo "You can get help on a specific command with ./".basename(__FILE__)." help COMMAND\n";
        echo "Available commands: ".implode(", ", array_keys($implemented_commands))."\n";
        exit(0);
} else {
        $selected_command = $argv[1];
}
 
// generate token, or load one from the cache file
if(!file_exists($token_file)) {
        echo "Logging in for the first time and storing token...";
        $data = json_decode(http_post($lemmy_api_url."user/login", array('username_or_email'=>$username, 'password'=>$password)), true);
        $token = $data['jwt'];
        if(!empty($token)) {
                echo "OK";
                file_put_contents($token_file, $token);
        } else {
                echo "Error logging in.";
        }
        echo "\n";
} else {
        $token = file_get_contents($token_file);
}
 
 
switch($selected_command) {
        case "help":
                if(in_array($argv[2], array_keys($implemented_commands))) {
                        echo "Usage: ./".basename(__FILE__)." {$argv[2]} ".$implemented_commands[$argv[2]]."\n";
                } else {
                        echo "Unrecognised command, available commands: ".implode(", ", array_keys($implemented_commands))."\n";
                }
                break;
        case "purgePerson":
                if(sizeof($argv) > 4)
                        exit("Too many parameters, if supplying a reason, please use enclose with quotation marks\n");
                $person_id = $argv[2];
                $reason = "";
                if(!empty($argv[3]))
                        $reason = $argv[3];
                echo "Attempting to purge person $person_id...";
                $data = json_decode(http_post($lemmy_api_url."admin/purge/person", array('auth' => $token, 'person_id'=>intval($person_id), 'reason'=>$reason)), true);
                $status = "ERROR";
                if(!empty($data['success']) and $data['success'] == 1)
                        $status = "OK";
                echo $status."\n";
                break;
        case "deletePost":
                $post_id = $argv[2];
                echo "Attempting to delete post ID $post_id...";
                $data = json_decode(http_post($lemmy_api_url."post/delete", array('auth' => $token, 'post_id'=>intval($post_id), 'deleted'=>true)), true);
                $status = "ERROR";
                if(!empty($data['post_view']) and $data['post_view']['post']['deleted'] == 1)
                        $status = "OK";
                echo $status."\n";
                break;
        default:
                echo "Unrecognised command";
                break;
}
 
function http_post($url, $data) {
        $ch = curl_init();
        $payload = json_encode($data);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER,
                array('Content-Type:application/json')
        );
        $result = curl_exec($ch);
        if(curl_errno($ch))
                print_r(curl_error($ch));
        return $result;
}
 
 
?>

That should be enough to get you started using the API from the command line. If I get time I'll put a more complete version of this with some other useful commands (like banPerson) on my repo as I find a use for them.

Getting Local Lemmy Users

To get the list of local users (person_id column) on your Lemmy instance, connect to the postgres database. For me, in docker, this is something like:

sudo docker exec -it <containerId> bash
psql -U lemmy
select * from local_user;

Pre v0.18

While working on this, I discovered the API purgePerson command didn't actually work - something to do with the order of routes. Working with @ksynwa:matrix.org in the Lemmy Development Matrix room, he found a fix and made a PR that was accepted into v0.18 (so this should be working in subsequent version of Lemmy (after v0.17.4).

lemmy-api-php.txt · Last modified: 2023/06/28 13:55 by neil