反馈是任何成功的产品开发过程的基石。 对于 WordPress 插件开发人员来说,了解用户停用插件的原因可以提供宝贵的见解。
当我使用 Cloudflare 为 WordPress 开发另一个很棒的插件时,如果用户停用我的插件,我想要一个反馈系统。 我开始在网上搜索,找到的解决方案对我来说不可行。
许多 WordPress 插件创建者依靠内置的停用调查或第三方服务来收集反馈。 然而,这些方法存在局限性和问题:
- 成本:运行服务器和管理反馈收集基础设施可能会很昂贵。 因此,第三方提供商收取相当多的费用。
- 延迟:缓慢的反馈机制可能会阻止用户参与。 当用户停用插件时,他预计 10 秒内不会加载页面。
- 集成麻烦:许多反馈系统需要陡峭的学习曲线或复杂的集成过程,例如 SDK 等。
- 隐私问题:大多数第三方服务提供商都会收集电子邮件地址等敏感数据。 将用户敏感数据存储在可能会也可能不会出售这些数据、遭到黑客攻击或更糟的平台上; 就是不可行。
那么,如何才能高效、安全且经济高效地收集反馈呢? 根据 Cloudflare Workers 、KV 和 [D1](https://developers.cloudflare.com/d1/ )。
我决定基于令人惊叹的 Cloudflare Workers 平台创建自己的 REST API,有效地将使用 Pages 部署的会员区域与 API 互连。 您可以在此处 详细了解我如何构建会员区域。
这意味着我可以将 API 使用限制为尊贵的会员,同时提供存储数据的隐私和安全性。 该 API 在全球范围内运行速度极快,停机时间为零,同时保持低成本和增强的安全性。 人们还想要什么? 😃
这仅仅是开始,因为我已经为未来的服务准备了几个端点,包括免费的和付费的给客户、开发人员和合作伙伴。
入门
我的 API 入门非常简单。 注册我的会员专区 。 注册后,只需访问您的个人资料 。 如果您已经有一个帐户,则会动态生成一组 API 令牌。
您将在此页面上找到:帐户 ID、公共令牌 和 私人令牌:
- 账户ID用于识别您的账户并存储相应信息。
- 公共代币仅限于某些操作,请参阅范围。
- 私人代币不像公共代币那样受到限制,您可以使用它来读取、写入、删除您帐户上的反馈。 再次,请查看范围。
注意:我的 API 有严格的速率限制以防止滥用。 如果你玩得太多,你可能会受到至少一小时或更长时间的限制。
使用 WordPress 反馈 API 端点是免费的,这是完全免费的,所以请不要尝试滥用它,否则我将不得不禁止您的帐户。
将 API 与您的插件集成
集成非常简单,您只需按照以下步骤操作:
- 连接到
admin_footer
并注入您的反馈模式/表单。 - 使用“admin_enqueue_scripts”加载 CSS 和 JS; 确保您只在插件页面上加载它们。 提示:创建您自己的自定义样式,否则您将破坏插件页面样式,甚至与其他插件反馈模式发生冲突。
- 创建一个管理AJAX函数来处理反馈; 例如
wp_ajax_your_plugin_deactivation_feedback
。 注意:始终使用随机数来保护您的 AJAX 功能。
在收集反馈时,您需要收集一些信息并将其相应地发送到API。 由于我非常关心隐私,API 不会存储电子邮件地址或任何其他被视为机密的内容。
此外,为了尽可能遵守 GDPR,我提供了 D1 提供的所有五个位置来存储收集的数据:
- 北美西部
- 北美东部
- 西欧
- 东欧洲
- 亚太地区
考虑到这一点,我还提供了一个 GEO 辅助函数,它返回您的托管区域。 这意味着您可以自动将数据存储在托管 WordPress 的封闭区域中。
获取区域的示例函数:
1private function get_region($account, $token)
2{
3 $api_url = "https://api.mecanik.dev/v1/developer/$account/geo-info";
4
5 $response = wp_remote_post($api_url, [
6 'headers' => [
7 'Authorization' => 'Bearer '.$token,
8 'Content-Type' => 'application/json; charset=utf-8',
9 ],
10 'method' => 'GET',
11 ]);
12
13 $response_body = wp_remote_retrieve_body($response);
14 $response_data = json_decode($response_body, true);
15
16 return $response_data;
17}
这将返回一个 JSON 响应,例如:
1{
2 "longitude": "8.68370",
3 "latitude": "50.11690",
4 "continent": "EU",
5 "asn": 14061,
6 "asOrganization": "Digital Ocean",
7 "country": "DE",
8 "isEUCountry": "1",
9 "city": "Frankfurt am Main",
10 "region": "Hesse",
11 "timezone": "Europe/Berlin",
12 "postalCode": "60341",
13 "recommended-storage-region": "weur"
14}
正如您在此示例中看到的,服务器驻留在“Hesse”区域,因此 API 建议将数据存储在“weur”区域。 对此持保留态度; API 不能保证它总是返回正确的“建议”。
现在,您可以继续创建反馈对象并向 API 发送以下内容:reason
、comments
、wp_plugin_name
、wp_plugin_version
、wp_site_url
、wp_version
、wp_locale
、wp_multisite
、 php_version
、db_type
、db_version
、server_type
、server_version
、date_created
。
发送反馈的示例函数:
1public function wp_ajax_your_plugin_deactivation_feedback()
2{
3 if (!wp_verify_nonce($_POST['nonce'], 'wp_ajax_your_plugin_deactivation_feedback_nonce')) {
4 wp_send_json_error(esc_html__('Request is invalid. Please refresh the page and try again.', 'your-plugin-name'), 400, 0);
5 exit();
6 }
7
8 $account = "....";
9 $token = "....";
10 $api_url = "https://api.mecanik.dev/v1/developer/$account/wp-feedback";
11
12 $region = $this->get_region($account, $token);
13
14 $response = wp_remote_post($api_url, [
15 'headers' => [
16 'Authorization' => 'Bearer '.$token,
17 'Content-Type' => 'application/json; charset=utf-8',
18 ],
19 'body' => json_encode([
20 'reason' => sanitize_text_field($_POST['reason']),
21 'comments' => sanitize_textarea_field($_POST['comments']),
22 'wp_plugin_name' => $this->plugin_name,
23 'wp_plugin_version' => $this->version,
24 'wp_site_url' => get_bloginfo('url'),
25 'wp_version' => $this->get_wp_version(),
26 'wp_locale' => get_locale(),
27 'wp_multisite' => is_multisite(),
28 'php_version' => $this->get_php_version(),
29 'db_type' => $this->get_db_type(),
30 'db_version' => $this->get_db_version(),
31 'server_type' => $this->get_server_type(),
32 'server_version' => $this->get_server_version(),
33 'date_created' => current_time('mysql'),
34 'region' => $region['recommended-storage-region'],
35 ]),
36 'method' => 'PUT',
37 'data_format' => 'body'
38 ]);
39
40 $response_body = wp_remote_retrieve_body($response);
41 $response_data = json_decode($response_body);
42
43 if ($response_data && isset($response_data->success) && $response_data->success === false) {
44 $error_message = isset($response_data->errors[0]->message) ? esc_html($response_data->errors[0]->message) : 'Unknown error';
45 wp_send_json_error($error_message, 400);
46 exit();
47 }
48 else if ($response_data && isset($response_data->success) && $response_data->success === true && isset($response_data->error)) {
49 wp_send_json_error($response_data->error, 400);
50 exit();
51 }
52
53 wp_send_json_success($response_data, 200, 0);
54}
将返回成功保存的反馈响应,如下所示:反馈已保存在 <region_name> 区域。
。
在上面的示例函数中,您可以看到我们收集了 php_version
、db_type
、db_version
等。为了您的方便,我将提供一些示例函数:
1private function get_wp_version() {
2 global $wp_version;
3 return $wp_version;
4}
5
6private function get_php_version() {
7 return PHP_VERSION;
8}
9
10private function get_db_type() {
11 global $wpdb;
12
13 $query = "SELECT TABLE_SCHEMA FROM information_schema.TABLES WHERE TABLE_NAME = 'wp_options'";
14 $result = $wpdb->get_row($query);
15
16 if ($result && isset($result->TABLE_SCHEMA)) {
17 $table_schema = $result->TABLE_SCHEMA;
18
19 if (strpos($table_schema, 'mysql') !== false) {
20 return 'MySQL';
21 } elseif (strpos($table_schema, 'pgsql') !== false) {
22 return 'PostgreSQL';
23 } elseif (strpos($table_schema, 'sqlite') !== false) {
24 return 'SQLite';
25 }
26 }
27
28 return 'Unknown';
29}
30
31private function get_db_version() {
32 global $wpdb;
33 return $wpdb->db_version();
34}
35
36private function get_server_type() {
37 if (isset($_SERVER['SERVER_SOFTWARE'])) {
38 return explode(' ', $_SERVER['SERVER_SOFTWARE'])[0];
39 }
40 return 'Unknown';
41}
42
43private function get_server_version() {
44 $uname = php_uname('s');
45
46 $serverTypes = [
47 'Apache' => 'Apache',
48 'Nginx' => 'Nginx',
49 'LiteSpeed' => 'LiteSpeed'
50 ];
51
52 if (isset($serverTypes[$uname])) {
53 return $serverTypes[$uname];
54 }
55
56 return '0.0.0';
57}
现在您应该拥有收集 WordPress 插件停用反馈所需的一切。 根据需要进行修改以满足您的需求。
开始收集停用反馈
如果您已按照上述步骤操作,当用户尝试停用您的插件时,应该会出现反馈模式:
用户可以输入停用您的插件的原因。 您可以随时从 API 检索所有收集的反馈。
API 文档
基本端点:
https://api.mecanik.dev/v1/developer
WordPress 反馈端点:
https://api.mecanik.dev/v1/developer/{account_id}/wp-feedback
获取评论
- 方法:
GET
- 链接:
https://api.mecanik.dev/v1/developer/{account_id}/wp-feedback?region=[region]
- 链接参数:
region
(必须): 存储评论的地区代码。可以是 `wnam`, `enam`, `weur`, `eeur` 或 `apac`。
- 范围:
read:wp_feedback
- 头部:
Authorization
: 访问验证令牌。
- 响应:
200 OK
如果请求成功并返回评论数据。400 错误请求
如果区域无效。403 禁止
如果令牌未被授权。404 未找到
如果令牌不存在。406 不接受
如果提交了无效的区域。
保存评论
- 方法:
PUT
- 链接:
https://api.mecanik.dev/v1/developer/{account_id}/wp-feedback
- 范围:
write:wp_feedback
- 头部:
Authorization
: 访问验证令牌。Content-Type
: application/json
- 内容:
- 包含以下内容的JSON对象:
reason
(必须): 用户禁用的原因。接受的格式:`string`。comments
(必须): 用户禁用的评论。接受的格式:`string`。wp_plugin_name
(必须): 当前的Wordpress插件名称。接受的格式:`string`。wp_plugin_version
(必须): 当前的Wordpress插件版本。接受的格式:`0.0.0.0`。wp_site_url
(必须): 当前的Wordpress网址。接受的格式:`string`。wp_version
(必须): 当前的Wordpress版本。接受的格式:`0.0.0.0`。wp_locale
(必须): 当前的Wordpress地区设置。接受的格式:`string`。wp_multisite
(必须): 当前的Wordpress是否为多站点安装。接受的格式:`boolean`。php_version
(必须): 当前的PHP版本。接受的格式:`0.0.0.0`。db_type
(必须): 当前的数据库服务器类型。接受的格式:`string`。db_version
(必须): 当前的数据库服务器版本。接受的格式:`0.0.0.0`。server_type
(必须): 当前的web服务器类型。接受的格式:`string`。server_version
(必须): 当前的web服务器版本。接受的格式:`0.0.0.0`。date_created
(必须): 评论创建的日期。接受的格式:`YYYY-MM-DD HH:MM:SS`。region
(必填): 反饋所存儲的地區代碼。可以是 `wnam`, `enam`, `weur`, `eeur`, 或 `apac`。
- 包含以下内容的JSON对象:
- 响应:
200 OK
如果评论成功保存。400 错误请求
如果提供的数据有误。403 禁止
如果令牌未被授权。404 未找到
如果令牌不存在。500 内部服务器错误
如果保存评论时出现错误。
删除评论
- 方法:
DELETE
- 链接:
https://api.mecanik.dev/v1/developer/{account_id}/wp-feedback
- 范围:
write:wp_feedback
- 头部:
Authorization
: 访问验证令牌。
- 内容:
- 包含以下内容的JSON对象:
feedback_ids
(必需): 整数数组。 示例:`[1,2,3]`region
(必需): 存储反馈的区域代码。 它可以是 `wnam`、`enam`、`weur`、`eeur` 或 `apac`。
- 包含以下内容的JSON对象:
- 响应:
200 OK
如果评论成功删除。400 错误请求
如果提供的评论ID无效。403 禁止
如果令牌未被授权或已被撤销/封禁。404 未找到
如果令牌不存在。500 内部服务器错误
如果删除评论时出现错误。
结论
拥有这样的反馈系统将对你的插件开发产生巨大的影响。 我希望这篇文章对您有所帮助,并且您可以使用我的 API 改进您的 WordPress 插件。
我将来可能会引入激活反馈,但我对此非常怀疑,因为用户无法“选择加入”或“选择退出”它。 因此,目前我们只会收到停用反馈。
如果您有任何反馈或建议,请随时使用下面的评论系统。
评论