Skip to content

Commit

Permalink
feat: upload sent image to gcs and return image URL
Browse files Browse the repository at this point in the history
  • Loading branch information
kyong0612 committed Jan 3, 2024
1 parent 8a9c524 commit d075634
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .clouddeploy/run-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ spec:
value: dummy # from-param: ${line_access_token}
- name: GEMINI_API_KEY
value: dummy # from-param: ${gemini_key}
- name: GCS_BUCKET_FITNESS_SUPPORTER
value: fitness-supporter-prd
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
LINE_CHANNEL_SECRET=YOUR_CHANNEL_SECRET
LINE_CHANNEL_ACCESS_TOKEN=YOUR_CHANNEL_ACCESS_TOKEN
GEMINI_API_KEY=YOUR_GEMINI_API_KEY
GCS_BUCKET_FITNESS_SUPPORTER=YOUR_GCS_FITNESS_BUCKET
28 changes: 26 additions & 2 deletions handler/line-webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ package handler
import (
"context"
"fmt"
"io"
"log/slog"
"net/http"
"strings"

"github.com/cockroachdb/errors"
"github.com/google/uuid"
"github.com/kyong0612/fitness-supporter/infra/config"
"github.com/kyong0612/fitness-supporter/infra/gcs"
"github.com/kyong0612/fitness-supporter/infra/gemini"
"github.com/kyong0612/fitness-supporter/infra/line"
)
Expand Down Expand Up @@ -88,18 +93,37 @@ func generateReply(ctx context.Context, lineClient line.Client, event line.Messa
}
defer resp.Body.Close()

file := make([]byte, resp.ContentLength)
if _, err := resp.Body.Read(file); err != nil {
file, err := io.ReadAll(resp.Body)
if err != nil {
return "", errors.Wrap(err, "failed to read response body")
}

minetype := resp.Header.Get("Content-Type")

// upload image to gcs
gcsClient, err := gcs.NewClient(ctx)
if err != nil {
return "", errors.Wrap(err, "failed to create gcs client")
}
bucket := config.Get().GCSBucketFitnessSupporter

Check failure on line 108 in handler/line-webhook.go

View workflow job for this annotation

GitHub Actions / lint

assignments should only be cuddled with other assignments (wsl)
fileName := fmt.Sprintf("%s.%s", uuid.New(), strings.Split(minetype, "/")[1])
if err := gcsClient.Upload(ctx, bucket, fileName, file); err != nil {

Check failure on line 110 in handler/line-webhook.go

View workflow job for this annotation

GitHub Actions / lint

only one cuddle assignment allowed before if statement (wsl)
return "", errors.Wrap(err, "failed to upload image to gcs")
}

// generate content by AI
replyMsg, err = gemini.GenerateContentByImage(ctx, minetype, file)
if err != nil {
return "", errors.Wrap(err, "failed to generate content by image")
}

filePath, err := gcsClient.GetContentURL(ctx, bucket, fileName)
if err != nil {
return "", errors.Wrap(err, "failed to get content url")
}

replyMsg = fmt.Sprintf("画像は以下のURLから取得できます。\n%s\n\n%s", filePath, replyMsg)

default:
replyMsg = "ごめんなさい、わかりません"
}
Expand Down
10 changes: 7 additions & 3 deletions infra/config/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import (
)

type config struct {
ENV string `env:"ENV" envDefault:"local"`
Port int `env:"PORT" envDefault:"8080"`
ENV string `env:"ENV" envDefault:"local"`

Check failure on line 9 in infra/config/env.go

View workflow job for this annotation

GitHub Actions / lint

tag is not aligned, should be: env:"ENV" envDefault:"local" (tagalign)
Port int `env:"PORT" envDefault:"8080"`

Check failure on line 10 in infra/config/env.go

View workflow job for this annotation

GitHub Actions / lint

tag is not aligned, should be: env:"PORT" envDefault:"8080" (tagalign)

LINEChannelSecret string `env:"LINE_CHANNEL_SECRET,required"`
LINEChannelAccessToken string `env:"LINE_CHANNEL_ACCESS_TOKEN,required"`
GeminiAPIKey string `env:"GEMINI_API_KEY,required"`

GeminiAPIKey string `env:"GEMINI_API_KEY,required"`

GCSBucketFitnessSupporter string `env:"GCS_BUCKET_FITNESS_SUPPORTER,required"`
}

var cfg config
Expand Down
40 changes: 40 additions & 0 deletions infra/gcs/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gcs

import (
"context"

"cloud.google.com/go/storage"
"github.com/cockroachdb/errors"
)

type Client interface {
Upload(ctx context.Context, bucket, object string, data []byte) error
GetContentURL(ctx context.Context, bucket, object string) (string, error)
}

type client struct {
*storage.Client
}

func NewClient(ctx context.Context) (Client, error) {
c, err := storage.NewClient(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to create gcs client")
}
return client{c}, nil

Check failure on line 24 in infra/gcs/client.go

View workflow job for this annotation

GitHub Actions / lint

return statements should not be cuddled if block has more than two lines (wsl)
}

func (c client) Upload(ctx context.Context, bucket, object string, data []byte) error {
wc := c.Bucket(bucket).Object(object).NewWriter(ctx)
if _, err := wc.Write(data); err != nil {
return errors.Wrap(err, "failed to write data")
}
if err := wc.Close(); err != nil {

Check failure on line 32 in infra/gcs/client.go

View workflow job for this annotation

GitHub Actions / lint

if statements should only be cuddled with assignments (wsl)
return errors.Wrap(err, "failed to close writer")
}
return nil

Check failure on line 35 in infra/gcs/client.go

View workflow job for this annotation

GitHub Actions / lint

return statements should not be cuddled if block has more than two lines (wsl)
}

func (c client) GetContentURL(ctx context.Context, bucket, object string) (string, error) {
return "https://storage.googleapis.com/" + bucket + "/" + object, nil
}

0 comments on commit d075634

Please sign in to comment.