代码编织梦想

由于个人的chatGPT免费版本即将到期, Claude 很火,在网上被说成是 ChatGPT 的最强对手,是 ChatGPT 的替代品。本文我将介绍下 Claude 是什么,以及如何免费使用 Claude.

什么是Claude

看一下它是如何自我介绍的

在这里插入图片描述

Slack

Slack 是一款流行的团队协作和通讯软件。
Claude 官方给我定义了很方便的 Slack 应用 Claude-in-Slack,我们直接把它添加到 Slack 中即可使用。添加的操作也很简单:

先注册 Slack
Claude 官网,点击 Add to Slack
在跳转的页面点击 添加到 Slack
在 Slack 中选择 Claude 应用,进入聊天窗口开始使用

接下来使用Slack的api来实现调用Claude, 虽然Claude也有接口申请, 但是一直没有通过, 不知道什么原因, 但是既然在Slack中可以使用Claude, 那就取巧, 通过Slack的api来实现调用Claude吧
Slack的api地址:

api.slack.com/methods

Slack 为我们提供了各个语言的 SDK,我们以 node-slack-sdk 来作为演示示例。

获取Slack Token

为了使用 Slack 的 SDK,我们需要新建一个 Slack APP。

在这里插入图片描述

选择Form scratch, 这里说一下, 我这里带翻译是使用了谷歌插件, 最近这个插件挺火的, 也很好用, 可以安利给大家, 插件的名字是沉浸式翻译, 大家直接去谷歌商店搜索就能找到了.

在这里插入图片描述
输入 app 名称并选择自己的 workspace。

在这里插入图片描述

创建后点击我们的 APP,然后点击左侧栏的 OAuth & Permissions。下拉找到 Scopes,为我们的 User Token 添加 Scope。

在这里插入图片描述

添加需要通过接口访问的权限

在这里插入图片描述

在这里插入图片描述
只有授权了才能够通过sdk调用这些接口哦

这些接口分别代表着不同的权限

在这里插入图片描述
然后我们把 APP 安装到我们的 workspace 中:
这个按钮在auth页面的上面

在这里插入图片描述

安装后,这里会生成我们需要的 User OAuth Token,我们复制这个 Token,后面需要用。

如果更改了权限, 就要重新下载到工作区才会出现效果哈

在这里插入图片描述

获取Claude Bot ID

进入Slack应用页面, 找到对应的Claude应用, 右击选择查看应用详情

在这里插入图片描述

复制Claude的成员ID和频道ID
在这里插入图片描述

Slack Claude Server

在服务端开始来获取应用里面的数据

我们需要安装的依赖有:
https://github.com/slackapi/node-slack-sdk

$ npm install @slack/web-api @slack/socket-mode

# Or, if you prefer yarn
$ yarn add @slack/web-api @slack/socket-mode

通过readme,我们可以看到如何像应用中发送一条数据


const { WebClient } = require('@slack/web-api');

// An access token (from your Slack app or custom integration - xoxp, xoxb)
const token = process.env.SLACK_TOKEN;

const web = new WebClient(token);

// This argument can be a channel ID, a DM ID, a MPDM ID, or a group ID
const conversationId = 'C1232456';

(async () => {
  // See: https://api.slack.com/methods/chat.postMessage
  const res = await web.chat.postMessage({ channel: conversationId, text: 'Hello there' });

  // `res` contains information about the posted message
  console.log('Message sent: ', res.ts);
})();

但是我们需要把这样的数据,做成一个接口的形式, 然后方便客户端调用, 我这里选择了express来创造路由接口, 很方便和快速.

拿到客户端输入的数据之后, 我们需要将Claude返回的数据返回给客户端, readme里面就没有提供例子了.

其实方法就是读取Claude这个应用窗口的历史数据, 拿到最新的这条回复, 通过conversations.history接口来拿取数据.

CALUDE_BOT_ID: 是频道ID
CALUDE_CHANNEL_ID: 是成员ID
CALUDE_TOKEN: 是上面拿到的User OAuth Token

import { WebClient } from '@slack/web-api'
import { Router } from "express";

const routes = Router();
// An access token (from your Slack app or custom integration - xoxp, xoxb)
const token = process.env.CALUDE_TOKEN;

const web = new WebClient(token);

// This argument can be a channel ID, a DM ID, a MPDM ID, or a group ID
const conversationId = process.env.CALUDE_CHANNEL_ID;

routes.all("*", function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
})

function sleep(ms: number) {
  return new Promise(resolve=>setTimeout(resolve, ms))
}

routes.post('/chat-process', async (req, res) => {
  
  res.setHeader('Content-type', 'application/octet-stream')
  try {
    const { prompt } = req.body
    const ans = await web.chat.postMessage({ channel: conversationId || '', text: prompt});
    let firstChunk = true
    for(let i = 0; i < 500; i++) {
      try {
        // Call the conversations.history method using WebClient
        const result = await web.conversations.history({
          channel: process.env.CALUDE_BOT_ID || '',
          oldest: ans.ts,
          limit: 2
        });
    
        const conversationHistory = result.messages;
        if (!conversationHistory) {
          sleep(1000)
          continue
        }
        else if(conversationHistory != undefined && Array.isArray(conversationHistory) && conversationHistory[0]?.text?.indexOf('_Typing…_') != -1) {

          res.write(firstChunk ? `${conversationHistory[0].text}` : `${conversationHistory[0].text}`)
          firstChunk = false
          sleep(1000)
          continue
        }
        res.write(`${conversationHistory[0].text}`)
        res.end()
        break;
      }
      catch (error) {
        console.error(error);
      }
    }
  }
  catch (error) {
    res.json({
      err: JSON.stringify(error)
    })
  }
  finally {
    res.end()
  }
})


export default routes;

将接口的content-Type设置成application/octet-stream, 是为了不用等到Claude完全解答完再返回给客户端, 可以先返回一些内容, 然后慢慢加载, 这样会增强用户体验感, 同时也能防止接口响应时间太长, 用户一直未得到答案

这里设置一个循环500次, 其实就是为了保证500次之后, 能够返回完整的数据, 当然如果提前结束了,就会break退出循环.

Claude Client

我这里是一个vue+vite项目, 核心请求接口代码如下:

async function onConversation() {
  let message = prompt.value

  if (loading.value)
    return

  if (!message || message.trim() === '')
    return

  controller = new AbortController()


  scrollToBottom()
  addMessage('', false)
  loading.value = true
  prompt.value = ''
  
  try {
    const fetchChatAPIOnce = async () => {
      await fetchCaludeAPIProcess({
        prompt: message,
        onDownloadProgress: ({ event }) => {
          const xhr = event.target
          const { responseText } = xhr
          // Always process the final line
          const lastIndex = responseText.lastIndexOf('⭐', responseText.length - 2)
          let chunk = responseText
          if (lastIndex !== -1) {
            chunk = responseText.substring(lastIndex)
          }
          list.value[list.value.length - 1].message = chunk
          scrollToBottom()
        },
      })
    }
    await fetchChatAPIOnce()
  }
  catch (error: any) {
    const errorMessage = error?.message ?? 'common.wrong'

    if (error.message === 'canceled') {

      scrollToBottomIfAtBottom()
      return
    }
    list.value[list.value.length - 1].message = errorMessage
    console.error(errorMessage)
    scrollToBottomIfAtBottom()
  }
  finally {
    loading.value = false
  }
}

每次都是以⭐开头, 所以我这边就是去取最后一个⭐开头的数据, 然后渲染到页面就可以了

在这里插入图片描述

最终的效果如下:

在这里插入图片描述
最后提供我的线上链接供大家体验一下:
Claude

好了, 今天的分享到这里就结束了, 感谢观看!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44859233/article/details/130717643