Qual o problema com minha requisição cURL?

Olá! Estou tentando escrever uma solicitação cURL para o meu site Wordpress para integrar o Discourse com assinaturas do woo. Aqui está minha função, que não parece funcionar. Estou perdendo alguma coisa?

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 = 'Erro na solicitação cURL de atualização do usuário Discourse';
        $message = 'Houve um erro';
        wp_mail($to, $subject, $message);
    }
}
1 curtida

Olá,

Que erro você está recebendo? O que a resposta retorna?
Isso deve ajudar a entender o problema.

O problema é que não recebo nenhum erro ou confirmação. Parece que o cURL simplesmente não funciona. Posso ver que a chave da API do Discourse foi usada quando o cURL é executado, então há algum sucesso, mas o usuário não é adicionado ou removido do grupo como pretendido. Posso confirmar que todas as variáveis estão corretas.

Deveria retornar um payload em caso de sucesso ou falha.

Você verificou o conteúdo de $response?

Além disso, acredito que o formato do parâmetro usernames deveria ser uma string “username1,username2,...” em vez disso.

1 curtida

A menos que eu esteja fazendo algo errado, a solicitação para \"/groups/${group_id}/members.json\" é um tanto contraintuitiva. Ela também não parece estar documentada e não pode ser visualizada na aba de rede do navegador ao enviar o formulário “Adicionar Usuário” do Discourse na página de um grupo. Novamente, posso estar fazendo algo errado.

De qualquer forma, o caminho para a solicitação é /groups/${group_id}/members.json, com o ID numérico do grupo substituído por group_id. O corpo da solicitação requer um parâmetro group_id, mas esse parâmetro precisa ser definido como o name do grupo. Assim, os argumentos ficam assim:

$group_id = 45;
$group_name = 'publishers';
$args     = array(
    'method' => 'DELETE', // ou 'PUT'
	'body'   => array(
		// 'group_id'  => $group_name, editar: este parâmetro não é necessário, não tenho certeza do que estava acontecendo quando o testei.
		'usernames' => 'sally,Ben',
	)
);

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

Se você tiver o plugin WP Discourse configurado em seu site WordPress, pode usar sua função auxiliar estática discourse_request para evitar ter que usar curl. Note que eu linkei para a função estática que está no arquivo plugin-utilities, mas o namespace que você precisa usar para solicitações externas é de 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' para adicionar usuários; 'DELETE' para remover usuários
	$args     = array(
		'method' => $method,
		'body'   => array(
			// 'group_id'  => $group_name, editar: este parâmetro não é necessário
			'usernames' => 'sally,Ben',
		)
	);
	$response = DiscourseUtilities::discourse_request( "/groups/${group_id}/members.json", $args );
    // retornar, registrar ou lidar com a resposta
}

Se você estiver usando o WordPress como provedor de SSO para o Discourse, há uma função auxiliar que permite adicionar um usuário a um ou mais grupos:

function zalg_sso_add_users_to_group() {
    $user_id = 1; // o ID do usuário do WordPress
    $group_names = 'foo,bar,baz'; // um ou mais nomes de grupo separados por vírgula, sem espaços após as vírgulas!
    DiscourseUtilities::add_user_to_discourse_group($user_id, $group_names);
}

Para adicionar vários usuários a um único grupo, você ainda precisará usar o método discourse_request que está no primeiro exemplo de código.

3 curtidas

A resposta é apenas um erro 500 :frowning:

Esta é uma ajuda heroica, obrigado Simon! Seria muito mais fácil se eu pudesse utilizar as funções auxiliares existentes no plugin WP Discourse. Estou usando meu site Wordpress para SSO.

No entanto, ainda recebo um erro crítico no meu caso quando a função é acionada. Não tenho certeza do porquê. O que você está dizendo está um pouco acima do meu entendimento, mas aqui está o que estou usando no meu 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);
}

Não tenho certeza do que estou perdendo?

A função para remover um usuário de um ou mais grupos é chamada remove_user_from_discourse_group, você a chamou de remove_user_to_discourse_group.

As funções para adicionar e remover um usuário de um ou mais grupos estão aqui: wp-discourse/lib/utilities.php at 99325e15190f3a705284dbf582f1c4b2c0b21492 · discourse/wp-discourse · GitHub.

3 curtidas

Você está certo! Erro bobo. Obrigado pela sua ajuda, Simon. Quem me dera haver uma caixa de gorjetas. Me avise se houver algo que eu possa fazer por você. Saúde!

1 curtida

Para expandir sobre isso, você sabe onde posso encontrar funções auxiliares para editar mais o perfil do usuário? Seria ótimo se eu pudesse definir a imagem de perfil e a biografia do usuário, se possível.

Existe uma função auxiliar no arquivo Utilities para isso:

DiscourseUtilities::sync_sso_record( $sso_params );

Ontem postei um exemplo de como usá-la: I cannot add user to the discouse forum from a wordpress website when user added in a membership - #10 by simon. A parte complicada é criar o array para o argumento sso_params. Esse array deve conter o campo external_id. Ele é definido como o ID do WordPress do usuário:

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

Você pode incluir quaisquer campos desta lista na carga útil: discourse/lib/discourse_connect_base.rb at 8f52fd1051e20fdff41321c5cff99fda05af86c1 · discourse/discourse · GitHub. Observe o array BOOLS que é mostrado logo abaixo da lista ACCESSORS que eu linkei. Ele indica quais das opções possíveis são booleans (true/false). Ao fazer requisições do WordPress, quaisquer campos booleanos devem ser definidos com as strings 'true' ou 'false', e não com os valores PHP true ou false.

Para atualizar o avatar, defina o campo avatar_url no array $sso_params e também defina o campo avatar_force_update como 'true'.

Existe um campo bio que pode ser usado para definir a bio.

O plugin WP Discourse já está definindo os campos bio e avatar_url. Ele também tem uma configuração “Force Avatar Update” em suas configurações de SSO. O problema pode ser que essas configurações só são atualizadas quando um usuário faz login no Discourse através do site WordPress. A função sync_sso_record atualiza os campos imediatamente, sem exigir que o usuário faça login no Discourse.

Além disso, se você está descobrindo que as bios dos usuários não estão sendo definidas no Discourse, pode ser que elas não estejam sendo definidas em seu site WordPress onde o plugin as espera: wp-discourse/lib/plugin-utilities.php at 99325e15190f3a705284dbf582f1c4b2c0b21492 · discourse/wp-discourse · GitHub. Se o Woocommerce tiver um campo diferente para bios, você pode acessar esse campo e usá-lo em uma chamada para sync_sso_record.

3 curtidas

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