Raycast 插件开发:如何获取 Chrome 指定网站的 Cookie

简介

Raycast

Raycast 是一款 Mac 上的快速启动工具,它提供了丰富的实用插件,可以帮助用户更加高效地启动应用程序、执行命令或查找信息。

Raycast 的一个重要特点是支持插件扩展,用户可以通过编写自己的插件来扩展 Raycast 的功能。通过编写插件,用户可以将一些常用的任务或功能集成到 Raycast 中,改进工作流程,以便更加高效地完成工作。

Raycast Extension 开发

选择在 Raycast 上开发效率工具的原因主要有两点:

  1. 快速:Raycast 绑定快捷键直接呼出交互面板,相比使用命令行工具,少了切换界面的步骤,优化了寻找工具入口的体验。

  2. 美观:Raycast Extension 提供了实用且风格统一的 UI 组件,例如 Action Panel、Detail、Form、List 等,开发者只需关注内部逻辑的实现。

    https://res.cloudinary.com/dgchmgebr/image/upload/v1680450686/blog/ipgnzwk9kwwqyugt2vvv.png

顺带一提,我经常使用 Python 开发命令行工具,因为要分享给同事使用,所以开发时烦恼的不是逻辑的实现,而是如何搞一套简洁大方的交互界面。

对于涉及到表单交互的工具,命令行界面很难展示和处理。我的唯一美化方式就是改变字体颜色,加上 emoji 😰,展示进度条,相当无奈。

因此,遇到 Raycast 提供的表单交互插件开发方式,我非常乐意尝试。

需求

为什么需要获取 Cookie?

在大多数网站中,访问和获取数据需要进行身份验证和授权。

  • 对于提供 OAuth 授权能力的网站,可以使用 Raycast 提供的 OAuth 功能进行授权;
  • 然而,对于绝大多数不提供 OAuth 能力的网站,只能寄希望于获取 Cookie 信息进行接口调用。

为什么从 Chrome 获取?

主要是因为我的主力浏览器是 Chrome。

同时,下文描述的实现方式里,chrome-launcherchrome-remote-interface 提供了流畅的从 Chrome 获取 Cookie 的能力。

实现

举例:获取网址 https://github.com/ 上 cookie 中 preferred_color_mode 的字段值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { Detail } from "@raycast/api";
import { useEffect, useState } from "react";
const chromeLauncher = require('chrome-launcher');
const CDP = require('chrome-remote-interface');

const domain = 'https://github.com/';
export default function Command() {
const [cookie, setCookie] = useState(null);

useEffect(() => {
const getCookie = async () => {
// 需要获取cookie的网站域名
const url = domain;
// 需要获取的cookie名称
const cookieName = 'preferred_color_mode'

try {
// 启动 chrome
// https://github.com/GoogleChrome/chrome-launcher#launching-headless-chrome
const chrome = await chromeLauncher.launch({
chromeFlags: ['--headless']
});

// 连接到 chrome
// https://github.com/cyrus-and/chrome-remote-interface
const protocol = await CDP({ port: chrome.port });
const { Network, Page } = protocol;
await Promise.all([Network.enable(), Page.enable()]);
// 导航到网站
await Page.navigate({ url });
await Page.loadEventFired();
// 获取所有cookie
const { cookies } = await Network.getAllCookies();

// 查找指定cookie
const cookie = cookies.find(c => c.name === cookieName);

// 及时关闭 chrome 进程和连接
await protocol.close();
await chrome.kill();

// 更新状态进行渲染
if (cookie) {
setCookie(`${cookie.name}=${cookie.value}`);
} else {
setCookie(`Cookie ${cookieName} not found`);
}
} catch (error) {
setCookie(`Error: ${error.message}`);
}
};

getCookie();
}, []);

return (
<Detail markdown={`Cookie from ${domain}:\n\n${cookie}`} />
)
}

效果如图

GetCookieDemo

相关链接

以下是一些相关链接,供参考: