Skip to content

Instantly share code, notes, and snippets.

@kkdai
Created April 12, 2024 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkdai/7206ed95d66a762c4c8109e428a38c80 to your computer and use it in GitHub Desktop.
Save kkdai/7206ed95d66a762c4c8109e428a38c80 to your computer and use it in GitHub Desktop.
LINE Bot Cloud Function - demo code in Go
package helloworld
import (
"context"
"fmt"
"net/http"
"io"
"log"
"os"
"github.com/GoogleCloudPlatform/functions-framework-go/functions"
"google.golang.org/api/option"
"github.com/google/generative-ai-go/genai"
"github.com/line/line-bot-sdk-go/v8/linebot"
"github.com/line/line-bot-sdk-go/v8/linebot/messaging_api"
"github.com/line/line-bot-sdk-go/v8/linebot/webhook"
)
var bot *messaging_api.MessagingApiAPI
var blob *messaging_api.MessagingApiBlobAPI
var geminiKey string
var channelToken string
func init() {
var err error
geminiKey = os.Getenv("GOOGLE_GEMINI_API_KEY")
channelToken = os.Getenv("ChannelAccessToken")
bot, err = messaging_api.NewMessagingApiAPI(channelToken)
if err != nil {
log.Fatal(err)
}
blob, err = messaging_api.NewMessagingApiBlobAPI(channelToken)
if err != nil {
log.Fatal(err)
}
functions.HTTP("HelloHTTP", HelloHTTP)
}
func HelloHTTP(w http.ResponseWriter, r *http.Request) {
cb, err := webhook.ParseRequest(os.Getenv("ChannelSecret"), r)
if err != nil {
if err == linebot.ErrInvalidSignature {
w.WriteHeader(400)
} else {
w.WriteHeader(500)
}
return
}
for _, event := range cb.Events {
log.Printf("Got event %v", event)
switch e := event.(type) {
case webhook.MessageEvent:
switch message := e.Message.(type) {
// Handle only on text message
case webhook.TextMessageContent:
req := message.Text
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(geminiKey))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// For text-only input, use the gemini-pro model
model := client.GenerativeModel("gemini-pro")
resp, err := model.GenerateContent(ctx, genai.Text(req))
if err != nil {
log.Fatal(err)
}
var ret string
for _, cand := range resp.Candidates {
for _, part := range cand.Content.Parts {
ret = ret + fmt.Sprintf("%v", part)
log.Println(part)
}
}
if _, err := bot.ReplyMessage(
&messaging_api.ReplyMessageRequest{
ReplyToken: e.ReplyToken,
Messages: []messaging_api.MessageInterface{
&messaging_api.TextMessage{
Text: ret,
},
},
},
); err != nil {
log.Print(err)
return
}
// Handle only image message
case webhook.ImageMessageContent:
log.Println("Got img msg ID:", message.Id)
//Get image binary from LINE server based on message ID.
content, err := blob.GetMessageContent(message.Id)
if err != nil {
log.Println("Got GetMessageContent err:", err)
}
defer content.Body.Close()
data, err := io.ReadAll(content.Body)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(geminiKey))
if err != nil {
log.Fatal(err)
}
defer client.Close()
model := client.GenerativeModel("gemini-pro-vision")
value := float32(0.8)
model.Temperature = &value
prompt := []genai.Part{
genai.ImageData("png", data),
genai.Text("Describe this image with scientific detail, reply in zh-TW:"),
}
log.Println("Begin processing image...")
resp, err := model.GenerateContent(ctx, prompt...)
log.Println("Finished processing image...", resp)
if err != nil {
log.Fatal(err)
}
var ret string
for _, cand := range resp.Candidates {
for _, part := range cand.Content.Parts {
ret = ret + fmt.Sprintf("%v", part)
log.Println(part)
}
}
if _, err := bot.ReplyMessage(
&messaging_api.ReplyMessageRequest{
ReplyToken: e.ReplyToken,
Messages: []messaging_api.MessageInterface{
&messaging_api.TextMessage{
Text: ret,
},
},
},
); err != nil {
log.Print(err)
return
}
// Handle only video message
case webhook.VideoMessageContent:
log.Println("Got video msg ID:", message.Id)
default:
log.Printf("Unknown message: %v", message)
}
case webhook.FollowEvent:
log.Printf("message: Got followed event")
case webhook.PostbackEvent:
data := e.Postback.Data
log.Printf("Unknown message: Got postback: " + data)
case webhook.BeaconEvent:
log.Printf("Got beacon: " + e.Beacon.Hwid)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment