Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support image generation #75

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions event.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ var axios = require("axios");
const EventDB = aircode.db.table("event");
const MsgTable = aircode.db.table("msg"); // 用于保存历史会话的表

const {Configuration, OpenAIApi} = require("openai");

// 如果你不想配置环境变量,或环境变量不生效,则可以把结果填写在每一行最后的 "" 内部
const FEISHU_APP_ID = process.env.APPID || ""; // 飞书的应用 ID
const FEISHU_APP_SECRET = process.env.SECRET || ""; // 飞书的应用的 Secret
Expand All @@ -13,6 +15,11 @@ const OPENAI_KEY = process.env.KEY || ""; // OpenAI 的 Key
const OPENAI_MODEL = process.env.MODEL || "gpt-3.5-turbo"; // 使用的模型
const OPENAI_MAX_TOKEN = process.env.MAX_TOKEN || 1024; // 最大 token 的值

const configuration = new Configuration({
apiKey: OPENAI_KEY,
});
const openai = new OpenAIApi(configuration);

const client = new lark.Client({
appId: FEISHU_APP_ID,
appSecret: FEISHU_APP_SECRET,
Expand All @@ -24,6 +31,15 @@ function logger(param) {
console.debug(`[CF]`, param);
}

async function getOpenaiImageUrl(prompt){
const resp = await openai.createImage({
prompt:prompt,
n:1,
size:"1024x1024"
});
return resp.data.data[0].url;
}

// 回复消息
async function reply(messageId, content) {
try{
Expand Down Expand Up @@ -104,6 +120,14 @@ async function clearConversation(sessionId) {

// 指令处理
async function cmdProcess(cmdParams) {
if(cmdParams && cmdParams.action.startsWith("/image")){
len = cmdParams.action.length;
prompt = cmdParams.action.substring(7,len);
logger(prompt)
url = await getOpenaiImageUrl(prompt);
await reply(cmdParams.messageId,url);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是不是可以考虑将其变成飞书自己的图片?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

飞书bot根据url生成图片的接口似乎不是很好用,目测需要下载成二进制然后上传图片,我调用飞书的上传图片接口的时候没拿到飞书的响应

async function getImageData(url) {
  return new Promise((resolve, reject) => {
    https.get(url, (response) => {
      const { statusCode } = response;
      const contentType = response.headers["content-type"];

      if (statusCode !== 200) {
        reject(new Error(`请求失败了: 状态码: ${statusCode}`));
        response.resume();
        return;
      }

      if (!/^image\//.test(contentType)) {
        reject(new Error(`无效的内容类型: ${contentType}`));
        response.resume();
        return;
      }

      let imageData = Buffer.from([]);

      response
        .on("data", (chunk) => {
          imageData = Buffer.concat([imageData, chunk]);
        })
        .on("end", () => {
          resolve(imageData);
        })
        .on("error", (error) => {
          reject(error);
        });
    });
  });
}


async function uploadImage(imageData,url){
  logger("upload image!");
  let resp = await client.im.image.create({
    data:{
      image_type:"message",
      image: imageData
    }
  });
  logger(console.dir(resp));
  if(resp.code!=0){
    return;
  }
  await ImageTable.save({url:url,image_key:resp.data.image_key});
  return resp.data.image_key;
}

return;
}
switch (cmdParams && cmdParams.action) {
case "/help":
await cmdHelp(cmdParams.messageId);
Expand All @@ -125,6 +149,7 @@ async function cmdHelp(messageId) {
Usage:
/clear 清除上下文
/help 获取更多帮助
/image ${提示词} 根据提示词生成图片
`
await reply(messageId, helpText);
}
Expand Down