Skip to content

Commit

Permalink
add AI mode (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
BennyThink authored Feb 23, 2024
1 parent c6d0910 commit c70c3e7
Show file tree
Hide file tree
Showing 11 changed files with 336 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
/.idea/*
/coverage.txt
/builds/
.DS_Store
.DS_Store
/archiver.db
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RUN apk update && apk add --no-cache chromium-chromedriver
RUN mkdir -p /usr/share/fonts/TTF && wget -O /usr/share/fonts/TTF/SourceHanSans-VF.ttc \
https://github.com/adobe-fonts/source-han-sans/raw/release/Variable/OTC/SourceHanSans-VF.ttf.ttc

ENV TZ=Asia/Shanghai

COPY --from=builder /build/archiver /archiver
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
Expand Down
40 changes: 19 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# archiver
~~# archiver

[![codecov](https://codecov.io/gh/tgbot-collection/archiver/branch/master/graph/badge.svg?token=ELEIXK6QAR)](https://codecov.io/gh/tgbot-collection/archiver)
[![docker image builder](https://github.com/tgbot-collection/archiver/actions/workflows/builder.yaml/badge.svg)](https://github.com/tgbot-collection/archiver/actions/workflows/builder.yaml)
Expand All @@ -14,12 +14,24 @@ Send any link to this bot, and it will save it to [Internet Archive](https://arc

A screenshot of this page will be sent to you as well.

Optionally, you can use AI mode to get a more accurate screenshot.

The AI functionality is powered by [Gemini](https://ai.google.dev/).

# screenshots

## save to wayback machine

![](assets/1.png)

## get screenshot

![](assets/2.png)

# AI mode

![](assets/3.png)

# commands

```
Expand All @@ -34,26 +46,10 @@ ping - ping server

# Privacy notice

This bot **WILL NEVER** collect your user id, username, last name, first name, url or anything that could be used to
track you.

This bot won't save any personal information, neither in database nor in log.
> [!IMPORTANT]
> This bot **WILL NEVER** save your personal information unless you choose to use AI mode.
Anything that you sent to this bot is confidential from the bot's side - even your url is omitted from log system.

I value your privacy, and I know it's difficult to fight against surveillance, injustice and censorship.

> Remember, remember the Fifth of November,
> The Gunpowder Treason and Plot,
> I know of no reason
> Why the Gunpowder Treason
> Should ever be forgot.
# TODO

- [x] show snapshot result

# Usage
# Development

## Build project locally

Expand All @@ -71,12 +67,14 @@ docker run -e DRIVER=$(which chromedriver) TOKEN=1234 bennythink/archiver
```

## prebuilt binary

Download it from release, and then

```shell
TOKEN=1234 DRIVER=$(which chromedriver) ./archiver
```

# License

Apache License
Version 2.0
Version 2.0
68 changes: 68 additions & 0 deletions ai.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// archiver - ai.go
// 2024-02-20 20:58
// Benny <[email protected]>

package main

import (
"bytes"
"encoding/json"
log "github.com/sirupsen/logrus"
"io"
"net/http"
)

type Response struct {
Candidates []Candidate `json:"candidates"`
}

type Candidate struct {
Content ContentData `json:"content"`
}

type ContentData struct {
Parts []Part `json:"parts"`
}

type Part struct {
Text string `json:"text"`
}

type Content struct {
Role string `json:"role"`
Parts []Part `json:"parts"`
}

type Data struct {
Contents []Content `json:"contents"`
}

func askAI(userID int64) string {
var data Data
chats := getChats(userID)
if len(chats) > 0 {
for _, chat := range chats {
part := Part{Text: chat.Text}
content := Content{
Role: chat.Role,
Parts: []Part{part},
}
data.Contents = append(data.Contents, content)
}
}

jsonData, _ := json.Marshal(data)
log.Infoln(string(jsonData))
resp, err := http.Post(geminiURL, "application/json", bytes.NewBuffer(jsonData))
defer resp.Body.Close()
if err != nil || resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
text := string(body)
log.Errorf("Request failed, %s", text)
return text
}

var response Response
_ = json.NewDecoder(resp.Body).Decode(&response)
return response.Candidates[0].Content.Parts[0].Text
}
Binary file added assets/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package main

import (
tb "gopkg.in/telebot.v3"
"os"
"time"
)
Expand Down Expand Up @@ -42,3 +43,18 @@ const (
startText = "Hi! I'm the [Internet Archive Wayback Machine bot](https://archive.org/web/).\n" +
"You can send me any url and I'll archive it for you."
)

const (
modeNormal = "normal"
modeAI = "ai"
userRole = "user"
modelRole = "model"
)

var apiKey = os.Getenv("GEMINI_API_KEY")
var geminiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=" + apiKey

var (
selector = &tb.ReplyMarkup{}
btnPrev = selector.Data("Ask AI", "ai-init", "1")
)
84 changes: 84 additions & 0 deletions database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// archiver - database.go
// 2024-02-20 20:00
// Benny <[email protected]>

package main

import (
"github.com/glebarez/sqlite"
"gorm.io/gorm"
)

var db, _ = gorm.Open(sqlite.Open("archiver.db"), &gorm.Config{})

type User struct {
gorm.Model
UserID int64 `gorm:"index;unique"` // 假设Telegram的用户ID是整数
Mode string // AI模式和普通模式
Link string
Token string // Future use
}

type Chat struct {
gorm.Model
UserID int64 `gorm:"index"` // userID
Role string // 发送者角色:model 或 user
Text string // 保存的消息文本
}

func getUser(userID int64) *User {
var user User
db.Where("user_id = ?", userID).First(&user)
return &user
}

func enableAI(userID int64, link string) *User {
user := getUser(userID)
user.Mode = modeAI
user.Link = link
if user.UserID == 0 {
// create new user
user.UserID = userID
db.Create(&user)
} else {
// update db
db.Save(&user)
}

return user
}

func disableAI(userId int64) {
// reset mode to normal, clear link
user := getUser(userId)
user.Mode = modeNormal
user.Link = ""
db.Save(&user)
}

func getChats(userID int64) []Chat {
var chats []Chat
db.Where("user_id = ?", userID).Find(&chats)
return chats
}

func getChatsCount(userID int64) int64 {
var count int64
db.Model(&Chat{}).Where("user_id = ?", userID).Count(&count)
return count
}

func addChat(userId int64, role, text string) {
chat := Chat{
UserID: userId,
Role: role,
Text: text,
}
db.Create(&chat)
}

func deleteChat(userID int64) int64 {
// delete according to userID
t := db.Where("user_id = ?", userID).Delete(&Chat{})
return t.RowsAffected
}
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ module archiver
go 1.15

require (
github.com/glebarez/sqlite v1.10.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.3
github.com/stretchr/testify v1.8.4
github.com/tebeka/selenium v0.9.9
github.com/tgbot-collection/tgbot_ping v1.0.2
gopkg.in/telebot.v3 v3.1.3
gopkg.in/telebot.v3 v3.2.1
gorm.io/gorm v1.25.7
)
Loading

0 comments on commit c70c3e7

Please sign in to comment.