github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/filesystem/driver/cos/scf.go (about) 1 package cos 2 3 import ( 4 "archive/zip" 5 "bytes" 6 "encoding/base64" 7 "io" 8 "io/ioutil" 9 "net/url" 10 "strconv" 11 "strings" 12 "time" 13 14 model "github.com/cloudreve/Cloudreve/v3/models" 15 "github.com/cloudreve/Cloudreve/v3/pkg/hashid" 16 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" 17 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" 18 scf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf/v20180416" 19 ) 20 21 const scfFunc = `# -*- coding: utf8 -*- 22 # SCF配置COS触发,向 Cloudreve 发送回调 23 from qcloud_cos_v5 import CosConfig 24 from qcloud_cos_v5 import CosS3Client 25 from qcloud_cos_v5 import CosServiceError 26 from qcloud_cos_v5 import CosClientError 27 import sys 28 import logging 29 import requests 30 31 logging.basicConfig(level=logging.INFO, stream=sys.stdout) 32 logger = logging.getLogger() 33 34 35 def main_handler(event, context): 36 logger.info("start main handler") 37 for record in event['Records']: 38 try: 39 if "x-cos-meta-callback" not in record['cos']['cosObject']['meta']: 40 logger.info("Cannot find callback URL, skiped.") 41 return 'Success' 42 callback = record['cos']['cosObject']['meta']['x-cos-meta-callback'] 43 key = record['cos']['cosObject']['key'] 44 logger.info("Callback URL is " + callback) 45 46 r = requests.get(callback) 47 print(r.text) 48 49 50 51 except Exception as e: 52 print(e) 53 print('Error getting object {} callback url. '.format(key)) 54 raise e 55 return "Fail" 56 57 return "Success" 58 ` 59 60 // CreateSCF 创建回调云函数 61 func CreateSCF(policy *model.Policy, region string) error { 62 // 初始化客户端 63 credential := common.NewCredential( 64 policy.AccessKey, 65 policy.SecretKey, 66 ) 67 cpf := profile.NewClientProfile() 68 client, err := scf.NewClient(credential, region, cpf) 69 if err != nil { 70 return err 71 } 72 73 // 创建回调代码数据 74 buff := &bytes.Buffer{} 75 bs64 := base64.NewEncoder(base64.StdEncoding, buff) 76 zipWriter := zip.NewWriter(bs64) 77 header := zip.FileHeader{ 78 Name: "callback.py", 79 Method: zip.Deflate, 80 } 81 writer, err := zipWriter.CreateHeader(&header) 82 if err != nil { 83 return err 84 } 85 _, err = io.Copy(writer, strings.NewReader(scfFunc)) 86 zipWriter.Close() 87 88 // 创建云函数 89 req := scf.NewCreateFunctionRequest() 90 funcName := "cloudreve_" + hashid.HashID(policy.ID, hashid.PolicyID) + strconv.FormatInt(time.Now().Unix(), 10) 91 zipFileBytes, _ := ioutil.ReadAll(buff) 92 zipFileStr := string(zipFileBytes) 93 codeSource := "ZipFile" 94 handler := "callback.main_handler" 95 desc := "Cloudreve 用回调函数" 96 timeout := int64(60) 97 runtime := "Python3.6" 98 req.FunctionName = &funcName 99 req.Code = &scf.Code{ 100 ZipFile: &zipFileStr, 101 } 102 req.Handler = &handler 103 req.Description = &desc 104 req.Timeout = &timeout 105 req.Runtime = &runtime 106 req.CodeSource = &codeSource 107 108 _, err = client.CreateFunction(req) 109 if err != nil { 110 return err 111 } 112 113 time.Sleep(time.Duration(5) * time.Second) 114 115 // 创建触发器 116 server, _ := url.Parse(policy.Server) 117 triggerType := "cos" 118 triggerDesc := `{"event":"cos:ObjectCreated:Post","filter":{"Prefix":"","Suffix":""}}` 119 enable := "OPEN" 120 121 trigger := scf.NewCreateTriggerRequest() 122 trigger.FunctionName = &funcName 123 trigger.TriggerName = &server.Host 124 trigger.Type = &triggerType 125 trigger.TriggerDesc = &triggerDesc 126 trigger.Enable = &enable 127 128 _, err = client.CreateTrigger(trigger) 129 if err != nil { 130 return err 131 } 132 133 return nil 134 }