Qual è il problema con la mia richiesta cURL?

Ciao! Sto cercando di scrivere una richiesta cURL per il mio sito Wordpress per integrare Discourse con le sottoscrizioni di woo. Ecco la mia funzione, che sembra non funzionare. Mi manca qualcosa?

function execute_discourse_curl_request($subscription) {

    $subscription_status = $subscription->get_status();

    $user_id = $subscription->get_user_id();
    $user = get_user_by('ID', $user_id);
    $username = $user->user_login;

    $request = "";

    if ($subscription_status == 'active') {
        $request = "PUT";
    }

    if ($subscription_status == 'cancelled' || $subscription_status == 'on-hold') {
        $request = "DELETE";
    }

    $api_key = get_option( 'discourse_custom_api_key' );

    $group_id = 41;
    $api_url = 'https://forum.example.com/groups/' . $group_id . '/members.json';
    
    $data = [
        'usernames' => [$username],
    ];
    
    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => $api_url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => $request,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => [
            "Api-Key: " . $api_key,
            "Api-Username: system",
            "Content-Type: application/json"
        ],
    ]);
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);

    if ($err) {
        $to = 'hello@example.com';
        $subject = 'Errore nella richiesta cURL di aggiornamento utente Discourse';
        $message = 'Si è verificato un errore';
        wp_mail($to, $subject, $message);
    }
}
1 Mi Piace

Ciao,

Che errore ricevi? Cosa restituisce la risposta?
Questo dovrebbe aiutare a capire il problema.

Il problema è che non ricevo alcun errore o conferma. Sembra che il cURL semplicemente non funzioni. Posso vedere che la chiave API di Discourse è stata utilizzata quando viene eseguito il cURL, quindi c’è stato un certo successo, ma l’utente non viene aggiunto o rimosso dal gruppo come previsto. Posso confermare che le variabili sono tutte corrette, tuttavia.

Dovrebbe restituire un payload in caso di successo o fallimento.

Hai controllato il contenuto di $response?

Inoltre, credo che il formato del parametro usernames dovrebbe essere una stringa “username1,username2,...”.

1 Mi Piace

A meno che non stia facendo qualcosa di sbagliato, la richiesta a "/groups/${group_id}/members.json" è piuttosto poco intuitiva. Inoltre, non sembra essere documentata e non può essere visualizzata nella scheda di rete del browser quando si invia il modulo “Aggiungi utente” di Discourse nella pagina di un gruppo. Di nuovo, potrei star facendo qualcosa di sbagliato.

In ogni caso, il percorso per la richiesta è /groups/${group_id}/members.json, con l’ID numerico del gruppo sostituito a group_id. Il corpo della richiesta richiede un parametro group_id, ma tale parametro deve essere impostato sul name del gruppo. Quindi gli argomenti diventano qualcosa del genere:

$group_id = 45;
$group_name = 'publishers';
$args     = array(
    'method' => 'DELETE', // o 'PUT'
	'body'   => array(
		// 'group_id'  => $group_name, edit: questo parametro non è necessario, non sono sicuro di cosa stesse succedendo quando lo stavo testando.
		'usernames' => 'sally,Ben',
	)
);

// percorso:
/groups/${group_id}/members.json

Se hai il plugin WP Discourse configurato sul tuo sito WordPress, puoi utilizzare la sua funzione di utilità statica discourse_request per evitare di dover usare curl. Nota che ho collegato la funzione statica che si trova nel file plugin-utilities, ma il namespace che devi usare per le richieste esterne proviene da https://github.com/discourse/wp-discourse/blob/main/lib/utilities.php.

use WPDiscourse\\Utilities\\Utilities as DiscourseUtilities;

function zalg_add_users_to_group() {
	$group_id = 45;
    $group_name = 'publishers';
    $method = 'PUT'; // 'PUT' per aggiungere utenti; 'DELETE' per rimuovere utenti
	$args     = array(
		'method' => $method,
		'body'   => array(
			// 'group_id'  => $group_name, edit: questo parametro non è necessario
			'usernames' => 'sally,Ben',
		)
	);
	$response = DiscourseUtilities::discourse_request( "/groups/${group_id}/members.json", $args );
    // restituisci, registra o gestisci la risposta
}

Se stai usando WordPress come provider SSO per Discourse, c’è una funzione di utilità che ti permette di aggiungere un utente a uno o più gruppi:

function zalg_sso_add_users_to_group() {
    $user_id = 1; // l'ID utente di WordPress
    $group_names = 'foo,bar,baz'; // uno o più nomi di gruppo separati da virgole, senza spazi dopo le virgole!
    DiscourseUtilities::add_user_to_discourse_group($user_id, $group_names);
}

Per aggiungere più utenti a un singolo gruppo, dovrai comunque utilizzare il metodo discourse_request presente nel primo esempio di codice.

3 Mi Piace

La risposta è solo un errore 500 :frowning:

Questo è un aiuto eroico, grazie Simon! Sarebbe molto più facile se potessi utilizzare le funzioni di supporto esistenti nel plugin WP Discourse. Sto usando il mio sito Wordpress per l’SSO.

Tuttavia, nel mio caso continuo a ricevere un errore critico quando la funzione viene attivata. Non sono sicuro del perché. Quello che dici è un po’ complicato per me, ma ecco cosa sto usando nel mio functions.php:

<?php

use WPDiscourse\Utilities\Utilities as DiscourseUtilities;

add_action('woocommerce_subscription_status_cancelled', 'zalg_sso_add_users_to_group', 10, 3);

function zalg_sso_add_users_to_group($subscription) {
    $user_id = $subscription->get_user_id();
    $group_names = 'premium';
    DiscourseUtilities::remove_user_to_discourse_group($user_id, $group_names);
}

Non sono sicuro di cosa mi stia sfuggendo?

La funzione per rimuovere un utente da uno o più gruppi si chiama remove_user_from_discourse_group, tu l’hai chiamata remove_user_to_discourse_group.

Le funzioni per aggiungere e rimuovere un utente da uno o più gruppi si trovano qui: wp-discourse/lib/utilities.php at 99325e15190f3a705284dbf582f1c4b2c0b21492 · discourse/wp-discourse · GitHub.

3 Mi Piace

Hai ragione! Errore sciocco. Grazie per il tuo aiuto, Simon. Vorrei che ci fosse una mancia. Fammi sapere se c’è qualcosa che posso fare per te. Saluti!

1 Mi Piace

Per estendere questo, sei a conoscenza di dove potrei trovare funzioni di supporto per modificare ulteriormente il profilo utente? Sarebbe fantastico se potessi impostare l’immagine del profilo utente e la biografia, se possibile.

C’è una funzione di utilità nel file Utilities per questo:

DiscourseUtilities::sync_sso_record( $sso_params );

Ieri ho pubblicato un esempio su come usarla: I cannot add user to the discouse forum from a wordpress website when user added in a membership - #10 by simon. La parte complicata è creare l’array per l’argomento sso_params. Quell’array deve contenere il campo external_id. È impostato sull’ID WordPress dell’utente:

	$sso_params = array(
		'external_id' => $user_id,
	);

Puoi includere qualsiasi campo da questo elenco nel payload: discourse/lib/discourse_connect_base.rb at 8f52fd1051e20fdff41321c5cff99fda05af86c1 · discourse/discourse · GitHub. Nota l’array BOOLS che viene mostrato appena sotto l’elenco ACCESSORS a cui ho collegato. Indica quali delle opzioni possibili sono booleani (vero/falso). Quando si effettuano richieste da WordPress, tutti i campi booleani devono essere impostati con le stringhe 'true' o 'false', non con i valori PHP true o false.

Per aggiornare l’avatar, imposta il campo avatar_url nell’array $sso_params e imposta anche il campo avatar_force_update su 'true'.

C’è un campo bio che può essere utilizzato per impostare la biografia.

Il plugin WP Discourse sta già impostando i campi bio e avatar_url. Ha anche un’impostazione “Force Avatar Update” nelle sue impostazioni SSO. Il problema potrebbe essere che queste impostazioni vengono aggiornate solo quando un utente accede a Discourse tramite il sito WordPress. La funzione sync_sso_record aggiorna i campi immediatamente, senza richiedere all’utente di accedere a Discourse.

Inoltre, se scopri che le biografie degli utenti non vengono impostate su Discourse, potrebbe essere che non vengano impostate sul tuo sito WordPress dove il plugin si aspetta che siano: wp-discourse/lib/plugin-utilities.php at 99325e15190f3a705284dbf582f1c4b2c0b21492 · discourse/wp-discourse · GitHub. Se Woocommerce ha un campo diverso per le biografie, potresti accedere a quel campo e utilizzarlo in una chiamata a sync_sso_record.

3 Mi Piace

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.