From 6bd56eb9b740742a7041edd7c37af96b12ab63a8 Mon Sep 17 00:00:00 2001 From: wood chen <95951386+woodchen-ink@users.noreply.github.com> Date: Sun, 28 Jan 2024 01:36:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E5=A4=8D=E6=B5=81=E5=BC=8F=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 11 - .gitignore | 5 - .goreleaser.yaml | 22 - Dockerfile | 54 +- LICENSE | 687 ++++++++++++++++++++- code/.gitignore | 2 + code/handlers/card_role_action.go | 75 --- code/handlers/event_common_action.go | 43 +- code/handlers/handler.go | 2 - code/handlers/msg.go | 96 +-- code/initialization/config.go | 5 +- code/initialization/gin.go | 71 +++ code/initialization/lark_client.go | 15 + code/services/loadbalancer/loadbalancer.go | 106 ++++ code/services/openai/audio.go | 66 ++ code/services/openai/gpt3.go | 25 +- code/services/openai/picture.go | 297 +++++++++ code/services/openai/test_file/img.png | Bin 0 -> 13697 bytes code/services/openai/test_file/test.jpg | Bin 0 -> 84666 bytes code/services/openai/test_file/test.wav | Bin 0 -> 40398 bytes code/utils/audio/ogg.go | 61 ++ code/utils/audio/wav.go | 107 ++++ code/utils/strings.go | 38 ++ code/utils/strings_test.go | 109 ++++ commands/custom.go | 76 --- commands/draw.go | 69 --- commands/message.go | 168 ----- commands/model.go | 60 -- commands/offline.go | 32 - commands/online.go | 32 - commands/ping.go | 24 - commands/reset.go | 36 -- commands/utils.go | 99 --- config/config.go | 63 -- docker-compose.yaml | 17 +- docker-compose.yml | 14 - entrypoint.sh | 89 --- go.mod | 119 ---- go.sum | 444 ------------- logs.go | 64 -- main.go | 202 ------ server.go | 184 ------ version.go | 4 - 43 files changed, 1575 insertions(+), 2118 deletions(-) delete mode 100644 .env.example delete mode 100644 .gitignore delete mode 100644 .goreleaser.yaml create mode 100644 code/.gitignore delete mode 100644 code/handlers/card_role_action.go create mode 100644 code/initialization/gin.go create mode 100644 code/initialization/lark_client.go create mode 100644 code/services/loadbalancer/loadbalancer.go create mode 100644 code/services/openai/audio.go create mode 100644 code/services/openai/picture.go create mode 100644 code/services/openai/test_file/img.png create mode 100644 code/services/openai/test_file/test.jpg create mode 100644 code/services/openai/test_file/test.wav create mode 100644 code/utils/audio/ogg.go create mode 100644 code/utils/audio/wav.go create mode 100644 code/utils/strings.go create mode 100644 code/utils/strings_test.go delete mode 100644 commands/custom.go delete mode 100644 commands/draw.go delete mode 100644 commands/message.go delete mode 100644 commands/model.go delete mode 100644 commands/offline.go delete mode 100644 commands/online.go delete mode 100644 commands/ping.go delete mode 100644 commands/reset.go delete mode 100644 commands/utils.go delete mode 100644 config/config.go delete mode 100644 docker-compose.yml delete mode 100644 entrypoint.sh delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 logs.go delete mode 100644 main.go delete mode 100644 server.go delete mode 100644 version.go diff --git a/.env.example b/.env.example deleted file mode 100644 index 8e81dc1..0000000 --- a/.env.example +++ /dev/null @@ -1,11 +0,0 @@ -APP_ID= -APP_SECRET= - -OPENAI_API_KEY= - -OPENAI_API_SERVER= - -OPENAI_API_TYPE= -OPENAI_AZURE_RESOURCE= -OPENAI_AZURE_DEPLOYMENT= -OPENAI_AZURE_API_VERSION= diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3b0887d..0000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -tmp/ -gzchatgpt -main -chatgpt-for-chatbot-feishu -.env diff --git a/.goreleaser.yaml b/.goreleaser.yaml deleted file mode 100644 index e42e89a..0000000 --- a/.goreleaser.yaml +++ /dev/null @@ -1,22 +0,0 @@ -env: - - GO111MODULE=on - -builds: - - env: - - CGO_ENABLED=0 - goos: - - linux - - darwin - # - windows - goarch: - - amd64 - - arm64 - # - arm - # - "386" - goarm: - - "7" - mod_timestamp: "{{ .CommitTimestamp }}" - flags: - - -trimpath - ldflags: - - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X main.builtBy=go-zoox diff --git a/Dockerfile b/Dockerfile index 6e4e3a2..b154ee3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,46 +1,20 @@ -# Builder -FROM --platform=$BUILDPLATFORM whatwewant/builder-go:v1.20-1 as builder +FROM golang:1.18 as golang + +ENV GO111MODULE=on \ + CGO_ENABLED=1 \ + GOPROXY=https://goproxy.cn,direct WORKDIR /build +ADD /code /build -COPY go.mod ./ +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags '-w -s' -o feishu_chatgpt -COPY go.sum ./ +FROM alpine:latest -RUN go mod download +WORKDIR /app -COPY . . - -ARG TARGETARCH - -RUN CGO_ENABLED=0 \ - GOOS=linux \ - GOARCH=$TARGETARCH \ - go build \ - -trimpath \ - -ldflags '-w -s -buildid=' \ - -v -o chatgpt-for-chatbot-feishu - -# Server -FROM whatwewant/go:v1.20-1 -# FROM whatwewant/zmicro:v1 - -LABEL MAINTAINER="Zero" - -LABEL org.opencontainers.image.source="https://github.com/go-zoox/chatgpt-for-chatbot-feishu" - -ARG VERSION=latest - -ENV MODE=production - -COPY --from=builder /build/chatgpt-for-chatbot-feishu /bin - -ENV VERSION=${VERSION} - -RUN zmicro package install ngrok - -# RUN zmicro package install cpolar - -COPY ./entrypoint.sh / - -CMD /entrypoint.sh +RUN apk add --no-cache bash +COPY --from=golang /build/feishu_chatgpt /app +COPY --from=golang /build/role_list.yaml /app +EXPOSE 9000 +ENTRYPOINT ["/app/feishu_chatgpt"] diff --git a/LICENSE b/LICENSE index d9b9bd8..f288702 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,674 @@ -MIT License + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 -Copyright (c) 2023 go-zoox + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + Preamble -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/code/.gitignore b/code/.gitignore new file mode 100644 index 0000000..d742ec8 --- /dev/null +++ b/code/.gitignore @@ -0,0 +1,2 @@ +/apikey_usage.json +*.pem diff --git a/code/handlers/card_role_action.go b/code/handlers/card_role_action.go deleted file mode 100644 index bb81156..0000000 --- a/code/handlers/card_role_action.go +++ /dev/null @@ -1,75 +0,0 @@ -package handlers - -import ( - "context" - larkcard "github.com/larksuite/oapi-sdk-go/v3/card" - "start-feishubot/initialization" - "start-feishubot/services" - "start-feishubot/services/openai" -) - -func NewRoleTagCardHandler(cardMsg CardMsg, - m MessageHandler) CardHandlerFunc { - return func(ctx context.Context, cardAction *larkcard.CardAction) (interface{}, error) { - - if cardMsg.Kind == RoleTagsChooseKind { - newCard, err, done := CommonProcessRoleTag(cardMsg, cardAction, - m.sessionCache) - if done { - return newCard, err - } - return nil, nil - } - return nil, ErrNextHandler - } -} - -func NewRoleCardHandler(cardMsg CardMsg, - m MessageHandler) CardHandlerFunc { - return func(ctx context.Context, cardAction *larkcard.CardAction) (interface{}, error) { - - if cardMsg.Kind == RoleChooseKind { - newCard, err, done := CommonProcessRole(cardMsg, cardAction, - m.sessionCache) - if done { - return newCard, err - } - return nil, nil - } - return nil, ErrNextHandler - } -} - -func CommonProcessRoleTag(msg CardMsg, cardAction *larkcard.CardAction, - cache services.SessionServiceCacheInterface) (interface{}, - error, bool) { - option := cardAction.Action.Option - //replyMsg(context.Background(), "已选择tag:"+option, - // &msg.MsgId) - roles := initialization.GetTitleListByTag(option) - //fmt.Printf("roles: %s", roles) - SendRoleListCard(context.Background(), &msg.SessionId, - &msg.MsgId, option, *roles) - return nil, nil, true -} - -func CommonProcessRole(msg CardMsg, cardAction *larkcard.CardAction, - cache services.SessionServiceCacheInterface) (interface{}, - error, bool) { - option := cardAction.Action.Option - contentByTitle, error := initialization.GetFirstRoleContentByTitle(option) - if error != nil { - return nil, error, true - } - cache.Clear(msg.SessionId) - systemMsg := append([]openai.Messages{}, openai.Messages{ - Role: "system", Content: contentByTitle, - }) - cache.SetMsg(msg.SessionId, systemMsg) - //pp.Println("systemMsg: ", systemMsg) - sendSystemInstructionCard(context.Background(), &msg.SessionId, - &msg.MsgId, contentByTitle) - //replyMsg(context.Background(), "已选择角色:"+contentByTitle, - // &msg.MsgId) - return nil, nil, true -} diff --git a/code/handlers/event_common_action.go b/code/handlers/event_common_action.go index ab5e875..631f002 100644 --- a/code/handlers/event_common_action.go +++ b/code/handlers/event_common_action.go @@ -3,10 +3,9 @@ package handlers import ( "context" "fmt" - larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1" - "start-feishubot/initialization" - "start-feishubot/services/openai" "start-feishubot/utils" + + larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1" ) type MsgInfo struct { @@ -86,24 +85,6 @@ func (*ClearAction) Execute(a *ActionInfo) bool { return true } -type RolePlayAction struct { /*角色扮演*/ -} - -func (*RolePlayAction) Execute(a *ActionInfo) bool { - if system, foundSystem := utils.EitherCutPrefix(a.info.qParsed, - "/system ", "角色扮演 "); foundSystem { - a.handler.sessionCache.Clear(*a.info.sessionId) - systemMsg := append([]openai.Messages{}, openai.Messages{ - Role: "system", Content: system, - }) - a.handler.sessionCache.SetMsg(*a.info.sessionId, systemMsg) - sendSystemInstructionCard(*a.ctx, a.info.sessionId, - a.info.msgId, system) - return false - } - return true -} - type HelpAction struct { /*帮助*/ } @@ -132,23 +113,3 @@ func (*BalanceAction) Execute(a *ActionInfo) bool { } return true } - -type RoleListAction struct { /*角色列表*/ -} - -func (*RoleListAction) Execute(a *ActionInfo) bool { - if _, foundSystem := utils.EitherTrimEqual(a.info.qParsed, - "/roles", "角色列表"); foundSystem { - //a.handler.sessionCache.Clear(*a.info.sessionId) - //systemMsg := append([]openai.Messages{}, openai.Messages{ - // Role: "system", Content: system, - //}) - //a.handler.sessionCache.SetMsg(*a.info.sessionId, systemMsg) - //sendSystemInstructionCard(*a.ctx, a.info.sessionId, - // a.info.msgId, system) - tags := initialization.GetAllUniqueTags() - SendRoleTagsCard(*a.ctx, a.info.sessionId, a.info.msgId, *tags) - return false - } - return true -} diff --git a/code/handlers/handler.go b/code/handlers/handler.go index d9a0ea8..1defddf 100644 --- a/code/handlers/handler.go +++ b/code/handlers/handler.go @@ -95,9 +95,7 @@ func (m MessageHandler) msgReceivedHandler(ctx context.Context, event *larkim.P2 &ProcessMentionAction{}, //判断机器人是否应该被调用 &EmptyAction{}, //空消息处理 &ClearAction{}, //清除消息处理 - &RoleListAction{}, //角色列表处理 &HelpAction{}, //帮助处理 - &RolePlayAction{}, //角色扮演处理 &MessageAction{ chatgpt: chatgpt.NewGpt3(&m.config), }, //消息处理 diff --git a/code/handlers/msg.go b/code/handlers/msg.go index 7ef227e..49d7345 100644 --- a/code/handlers/msg.go +++ b/code/handlers/msg.go @@ -19,13 +19,11 @@ type CardKind string type CardChatType string var ( - ClearCardKind = CardKind("clear") // 清空上下文 - PicModeChangeKind = CardKind("pic_mode_change") // 切换图片创作模式 - PicResolutionKind = CardKind("pic_resolution") // 图片分辨率调整 - PicTextMoreKind = CardKind("pic_text_more") // 重新根据文本生成图片 - PicVarMoreKind = CardKind("pic_var_more") // 变量图片 - RoleTagsChooseKind = CardKind("role_tags_choose") // 内置角色所属标签选择 - RoleChooseKind = CardKind("role_choose") // 内置角色选择 + ClearCardKind = CardKind("clear") // 清空上下文 + PicModeChangeKind = CardKind("pic_mode_change") // 切换图片创作模式 + PicResolutionKind = CardKind("pic_resolution") // 图片分辨率调整 + PicTextMoreKind = CardKind("pic_text_more") // 重新根据文本生成图片 + PicVarMoreKind = CardKind("pic_var_more") // 变量图片 ) var ( @@ -401,59 +399,6 @@ func withPicResolutionBtn(sessionID *string) larkcard. Build() return actions } -func withRoleTagsBtn(sessionID *string, tags ...string) larkcard. - MessageCardElement { - var menuOptions []MenuOption - - for _, tag := range tags { - menuOptions = append(menuOptions, MenuOption{ - label: tag, - value: tag, - }) - } - cancelMenu := newMenu("选择角色分类", - map[string]interface{}{ - "value": "0", - "kind": RoleTagsChooseKind, - "sessionId": *sessionID, - "msgId": *sessionID, - }, - menuOptions..., - ) - - actions := larkcard.NewMessageCardAction(). - Actions([]larkcard.MessageCardActionElement{cancelMenu}). - Layout(larkcard.MessageCardActionLayoutFlow.Ptr()). - Build() - return actions -} - -func withRoleBtn(sessionID *string, titles ...string) larkcard. - MessageCardElement { - var menuOptions []MenuOption - - for _, tag := range titles { - menuOptions = append(menuOptions, MenuOption{ - label: tag, - value: tag, - }) - } - cancelMenu := newMenu("查看内置角色", - map[string]interface{}{ - "value": "0", - "kind": RoleChooseKind, - "sessionId": *sessionID, - "msgId": *sessionID, - }, - menuOptions..., - ) - - actions := larkcard.NewMessageCardAction(). - Actions([]larkcard.MessageCardActionElement{cancelMenu}). - Layout(larkcard.MessageCardActionLayoutFlow.Ptr()). - Build() - return actions -} func replyMsg(ctx context.Context, msg string, msgId *string) error { msg, i := processMessage(msg) @@ -645,15 +590,6 @@ func sendClearCacheCheckCard(ctx context.Context, replyCard(ctx, msgId, newCard) } -func sendSystemInstructionCard(ctx context.Context, - sessionId *string, msgId *string, content string) { - newCard, _ := newSendCard( - withHeader("🥷 已进入角色扮演模式", larkcard.TemplateIndigo), - withMainText(content), - withNote("请注意,这将开始一个全新的对话,您将无法利用之前话题的历史信息")) - replyCard(ctx, msgId, newCard) -} - func sendOnProcessCard(ctx context.Context, sessionId *string, msgId *string) (*string, error) { newCard, _ := newSendCardWithOutHeader( @@ -694,7 +630,7 @@ func sendHelpCard(ctx context.Context, sessionId *string, msgId *string) { newCard, _ := newSendCard( withHeader("🎒需要帮助吗?", larkcard.TemplateBlue), - withMainMd("**我是具备打字机效果的聊天机器人!**"), + withMainMd("**我是具备打字机效果的Oapi飞书聊天机器人**"), withSplitLine(), withMdAndExtraBtn( "** 🆑 清除话题上下文**\n文本回复 *清除* 或 */clear*", @@ -704,8 +640,6 @@ func sendHelpCard(ctx context.Context, "chatType": UserChatType, "sessionId": *sessionId, }, larkcard.MessageCardButtonTypeDanger)), - withMainMd("🛖 **内置角色列表** \n"+" 文本回复 *角色列表* 或 */roles*"), - withMainMd("🥷 **角色扮演模式**\n文本回复*角色扮演* 或 */system*+空格+角色信息"), withSplitLine(), withMainMd("🎒 **需要更多帮助**\n文本回复 *帮助* 或 */help*"), ) @@ -744,21 +678,3 @@ func sendBalanceCard(ctx context.Context, msgId *string, ) replyCard(ctx, msgId, newCard) } - -func SendRoleTagsCard(ctx context.Context, - sessionId *string, msgId *string, roleTags []string) { - newCard, _ := newSendCard( - withHeader("🛖 请选择角色类别", larkcard.TemplateIndigo), - withRoleTagsBtn(sessionId, roleTags...), - withNote("提醒:选择角色所属分类,以便我们为您推荐更多相关角色。")) - replyCard(ctx, msgId, newCard) -} - -func SendRoleListCard(ctx context.Context, - sessionId *string, msgId *string, roleTag string, roleList []string) { - newCard, _ := newSendCard( - withHeader("🛖 角色列表"+" - "+roleTag, larkcard.TemplateIndigo), - withRoleBtn(sessionId, roleList...), - withNote("提醒:选择内置场景,快速进入角色扮演模式。")) - replyCard(ctx, msgId, newCard) -} diff --git a/code/initialization/config.go b/code/initialization/config.go index 8e2079e..0c64d34 100644 --- a/code/initialization/config.go +++ b/code/initialization/config.go @@ -2,12 +2,13 @@ package initialization import ( "fmt" - "github.com/spf13/pflag" "os" "strconv" "strings" "sync" + "github.com/spf13/pflag" + "github.com/spf13/viper" ) @@ -85,7 +86,7 @@ func LoadConfig(cfg string) *Config { UseHttps: getViperBoolValue("USE_HTTPS", false), CertFile: getViperStringValue("CERT_FILE", "cert.pem"), KeyFile: getViperStringValue("KEY_FILE", "key.pem"), - OpenaiApiUrl: getViperStringValue("API_URL", "https://api.openai.com"), + OpenaiApiUrl: getViperStringValue("API_URL", "https://oapi.czl.net"), HttpProxy: getViperStringValue("HTTP_PROXY", ""), AzureOn: getViperBoolValue("AZURE_ON", false), AzureApiVersion: getViperStringValue("AZURE_API_VERSION", "2023-03-15-preview"), diff --git a/code/initialization/gin.go b/code/initialization/gin.go new file mode 100644 index 0000000..cdc9323 --- /dev/null +++ b/code/initialization/gin.go @@ -0,0 +1,71 @@ +package initialization + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +func loadCertificate(config Config) (cert tls.Certificate, err error) { + cert, err = tls.LoadX509KeyPair(config.CertFile, config.KeyFile) + if err != nil { + return cert, fmt.Errorf("failed to load certificate: %v", err) + } + + // check certificate expiry + if len(cert.Certificate) == 0 { + return cert, fmt.Errorf("no certificates found in %s", config.CertFile) + } + parsedCert, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return cert, fmt.Errorf("failed to parse certificate: %v", err) + } + cert.Leaf = parsedCert + certExpiry := cert.Leaf.NotAfter + if certExpiry.Before(time.Now()) { + return cert, fmt.Errorf("certificate expired on %v", certExpiry) + } + + return cert, nil +} + +func startHTTPServer(config Config, r *gin.Engine) (err error) { + log.Printf("http server started: http://localhost:%d/webhook/event\n", config.HttpPort) + err = r.Run(fmt.Sprintf(":%d", config.HttpPort)) + if err != nil { + return fmt.Errorf("failed to start http server: %v", err) + } + return nil +} +func startHTTPSServer(config Config, r *gin.Engine) (err error) { + cert, err := loadCertificate(config) + if err != nil { + return fmt.Errorf("failed to load certificate: %v", err) + } + server := &http.Server{ + Addr: fmt.Sprintf(":%d", config.HttpsPort), + Handler: r, + TLSConfig: &tls.Config{ + Certificates: []tls.Certificate{cert}, + }, + } + fmt.Printf("https server started: https://localhost:%d/webhook/event\n", config.HttpsPort) + err = server.ListenAndServeTLS("", "") + if err != nil { + return fmt.Errorf("failed to start https server: %v", err) + } + return nil +} +func StartServer(config Config, r *gin.Engine) (err error) { + if config.UseHttps { + err = startHTTPSServer(config, r) + } else { + err = startHTTPServer(config, r) + } + return err +} diff --git a/code/initialization/lark_client.go b/code/initialization/lark_client.go new file mode 100644 index 0000000..27ad97d --- /dev/null +++ b/code/initialization/lark_client.go @@ -0,0 +1,15 @@ +package initialization + +import ( + lark "github.com/larksuite/oapi-sdk-go/v3" +) + +var larkClient *lark.Client + +func LoadLarkClient(config Config) { + larkClient = lark.NewClient(config.FeishuAppId, config.FeishuAppSecret) +} + +func GetLarkClient() *lark.Client { + return larkClient +} diff --git a/code/services/loadbalancer/loadbalancer.go b/code/services/loadbalancer/loadbalancer.go new file mode 100644 index 0000000..930482b --- /dev/null +++ b/code/services/loadbalancer/loadbalancer.go @@ -0,0 +1,106 @@ +package loadbalancer + +import ( + "fmt" + "math/rand" + "sync" + "time" +) + +type API struct { + Key string + Times uint32 + Available bool +} + +type LoadBalancer struct { + apis []*API + mu sync.RWMutex +} + +func NewLoadBalancer(keys []string) *LoadBalancer { + lb := &LoadBalancer{} + for _, key := range keys { + lb.apis = append(lb.apis, &API{Key: key}) + } + //SetAvailabilityForAll true + lb.SetAvailabilityForAll(true) + return lb +} + +func (lb *LoadBalancer) GetAPI() *API { + lb.mu.RLock() + defer lb.mu.RUnlock() + + var availableAPIs []*API + for _, api := range lb.apis { + if api.Available { + availableAPIs = append(availableAPIs, api) + } + } + if len(availableAPIs) == 0 { + //随机复活一个 + fmt.Printf("No available API, revive one randomly\n") + rand.Seed(time.Now().UnixNano()) + index := rand.Intn(len(lb.apis)) + lb.apis[index].Available = true + return lb.apis[index] + } + + selectedAPI := availableAPIs[0] + minTimes := selectedAPI.Times + for _, api := range availableAPIs { + if api.Times < minTimes { + selectedAPI = api + minTimes = api.Times + } + } + selectedAPI.Times++ + //fmt.Printf("API Availability:\n") + //for _, api := range lb.apis { + // fmt.Printf("%s: %v\n", api.Key, api.Available) + // fmt.Printf("%s: %d\n", api.Key, api.Times) + //} + + return selectedAPI +} +func (lb *LoadBalancer) SetAvailability(key string, available bool) { + lb.mu.Lock() + defer lb.mu.Unlock() + + for _, api := range lb.apis { + if api.Key == key { + api.Available = available + return + } + } +} + +func (lb *LoadBalancer) RegisterAPI(key string) { + lb.mu.Lock() + defer lb.mu.Unlock() + + if lb.apis == nil { + lb.apis = make([]*API, 0) + } + + lb.apis = append(lb.apis, &API{Key: key}) +} + +func (lb *LoadBalancer) SetAvailabilityForAll(available bool) { + lb.mu.Lock() + defer lb.mu.Unlock() + + for _, api := range lb.apis { + api.Available = available + } +} + +func (lb *LoadBalancer) GetAPIs() []*API { + lb.mu.RLock() + defer lb.mu.RUnlock() + + apis := make([]*API, len(lb.apis)) + copy(apis, lb.apis) + return apis +} diff --git a/code/services/openai/audio.go b/code/services/openai/audio.go new file mode 100644 index 0000000..da67fde --- /dev/null +++ b/code/services/openai/audio.go @@ -0,0 +1,66 @@ +package openai + +import ( + "bytes" + "fmt" + "io" + "mime/multipart" + "os" +) + +type AudioToTextRequestBody struct { + File string `json:"file"` + Model string `json:"model"` + ResponseFormat string `json:"response_format"` +} + +type AudioToTextResponseBody struct { + Text string `json:"text"` +} + +func audioMultipartForm(request AudioToTextRequestBody, w *multipart.Writer) error { + f, err := os.Open(request.File) + if err != nil { + return fmt.Errorf("opening audio file: %w", err) + } + + fw, err := w.CreateFormFile("file", f.Name()) + if err != nil { + return fmt.Errorf("creating form file: %w", err) + } + + if _, err = io.Copy(fw, f); err != nil { + return fmt.Errorf("reading from opened audio file: %w", err) + } + + fw, err = w.CreateFormField("model") + if err != nil { + return fmt.Errorf("creating form field: %w", err) + } + + modelName := bytes.NewReader([]byte(request.Model)) + if _, err = io.Copy(fw, modelName); err != nil { + return fmt.Errorf("writing model name: %w", err) + } + w.Close() + + return nil +} + +func (gpt *ChatGPT) AudioToText(audio string) (string, error) { + requestBody := AudioToTextRequestBody{ + File: audio, + Model: "whisper-1", + ResponseFormat: "text", + } + audioToTextResponseBody := &AudioToTextResponseBody{} + err := gpt.sendRequestWithBodyType(gpt.ApiUrl+"/v1/audio/transcriptions", + "POST", formVoiceDataBody, requestBody, audioToTextResponseBody) + //fmt.Println(audioToTextResponseBody) + if err != nil { + //fmt.Println(err) + return "", err + } + + return audioToTextResponseBody.Text, nil +} diff --git a/code/services/openai/gpt3.go b/code/services/openai/gpt3.go index 5ea27bf..bdb39b8 100644 --- a/code/services/openai/gpt3.go +++ b/code/services/openai/gpt3.go @@ -5,29 +5,8 @@ import ( ) const ( - Fresh AIMode = 0.1 - Warmth AIMode = 0.4 - Balance AIMode = 0.7 - Creativity AIMode = 1.0 -) - -var AIModeMap = map[string]AIMode{ - "清新": Fresh, - "温暖": Warmth, - "平衡": Balance, - "创意": Creativity, -} - -var AIModeStrs = []string{ - "清新", - "温暖", - "平衡", - "创意", -} - -const ( - maxTokens = 4096 - engine = "gpt-4-0613" + maxTokens = 2000 + temperature = 0.7 ) type Messages struct { diff --git a/code/services/openai/picture.go b/code/services/openai/picture.go new file mode 100644 index 0000000..f3bbf58 --- /dev/null +++ b/code/services/openai/picture.go @@ -0,0 +1,297 @@ +package openai + +import ( + "bufio" + "fmt" + "image" + "image/jpeg" + "image/png" + "io" + "mime/multipart" + "os" +) + +type ImageGenerationRequestBody struct { + Prompt string `json:"prompt"` + N int `json:"n"` + Size string `json:"size"` + ResponseFormat string `json:"response_format"` +} + +type ImageResponseBody struct { + Created int64 `json:"created"` + Data []struct { + Base64Json string `json:"b64_json"` + } `json:"data"` +} + +type ImageVariantRequestBody struct { + Image string `json:"image"` + N int `json:"n"` + Size string `json:"size"` + ResponseFormat string `json:"response_format"` +} + +func (gpt *ChatGPT) GenerateImage(prompt string, size string, + n int) ([]string, error) { + requestBody := ImageGenerationRequestBody{ + Prompt: prompt, + N: n, + Size: size, + ResponseFormat: "b64_json", + } + + imageResponseBody := &ImageResponseBody{} + err := gpt.sendRequestWithBodyType(gpt.ApiUrl+"/v1/images/generations", + "POST", jsonBody, requestBody, imageResponseBody) + + if err != nil { + return nil, err + } + + var b64Pool []string + for _, data := range imageResponseBody.Data { + b64Pool = append(b64Pool, data.Base64Json) + } + return b64Pool, nil +} + +func (gpt *ChatGPT) GenerateOneImage(prompt string, + size string) (string, error) { + b64s, err := gpt.GenerateImage(prompt, size, 1) + if err != nil { + return "", err + } + return b64s[0], nil +} + +func (gpt *ChatGPT) GenerateOneImageWithDefaultSize( + prompt string) (string, error) { + return gpt.GenerateOneImage(prompt, "512x512") +} + +func (gpt *ChatGPT) GenerateImageVariation(images string, + size string, n int) ([]string, error) { + requestBody := ImageVariantRequestBody{ + Image: images, + N: n, + Size: size, + ResponseFormat: "b64_json", + } + + imageResponseBody := &ImageResponseBody{} + err := gpt.sendRequestWithBodyType(gpt.ApiUrl+"/v1/images/variations", + "POST", formPictureDataBody, requestBody, imageResponseBody) + + if err != nil { + return nil, err + } + + var b64Pool []string + for _, data := range imageResponseBody.Data { + b64Pool = append(b64Pool, data.Base64Json) + } + return b64Pool, nil +} + +func (gpt *ChatGPT) GenerateOneImageVariation(images string, + size string) (string, error) { + b64s, err := gpt.GenerateImageVariation(images, size, 1) + if err != nil { + return "", err + } + return b64s[0], nil +} + +func pictureMultipartForm(request ImageVariantRequestBody, + w *multipart.Writer) error { + + f, err := os.Open(request.Image) + if err != nil { + return fmt.Errorf("opening audio file: %w", err) + } + fw, err := w.CreateFormFile("image", f.Name()) + if err != nil { + return fmt.Errorf("creating form file: %w", err) + } + if _, err = io.Copy(fw, f); err != nil { + return fmt.Errorf("reading from opened audio file: %w", err) + } + + err = w.WriteField("size", request.Size) + if err != nil { + return fmt.Errorf("writing size: %w", err) + } + + err = w.WriteField("n", fmt.Sprintf("%d", request.N)) + if err != nil { + return fmt.Errorf("writing n: %w", err) + } + + err = w.WriteField("response_format", request.ResponseFormat) + if err != nil { + return fmt.Errorf("writing response_format: %w", err) + } + + //err = w.WriteField("user", "user123456") + + //fw, err = w.CreateFormField("model") + //if err != nil { + // return fmt.Errorf("creating form field: %w", err) + //} + //modelName := bytes.NewReader([]byte(request.Model)) + //if _, err = io.Copy(fw, modelName); err != nil { + // return fmt.Errorf("writing model name: %w", err) + //} + + //fmt.Printf("w.FormDataContentType(): %s ", w.FormDataContentType()) + + w.Close() + + return nil +} + +func VerifyPngs(pngPaths []string) error { + foundPng := false + var expectedWidth, expectedHeight int + + for _, pngPath := range pngPaths { + f, err := os.Open(pngPath) + if err != nil { + return fmt.Errorf("os.Open: %v", err) + } + + fi, err := f.Stat() + if err != nil { + return fmt.Errorf("f.Stat: %v", err) + } + if fi.Size() > 4*1024*1024 { + return fmt.Errorf("image size too large, "+ + "must be under %d MB", 4) + } + + image, err := png.Decode(f) + if err != nil { + return fmt.Errorf("image must be valid png, got error: %v", err) + } + width := image.Bounds().Dx() + height := image.Bounds().Dy() + if width != height { + return fmt.Errorf("found non-square image with dimensions %dx%d", width, height) + } + + if !foundPng { + foundPng = true + expectedWidth = width + expectedHeight = height + } else { + if width != expectedWidth || height != expectedHeight { + return fmt.Errorf("dimensions of all images must match, got both (%dx%d) and (%dx%d)", width, height, expectedWidth, expectedHeight) + } + } + } + + return nil +} + +func ConvertToRGBA(inputFilePath string, outputFilePath string) error { + // 打开输入文件 + inputFile, err := os.Open(inputFilePath) + if err != nil { + return fmt.Errorf("打开文件时出错:%w", err) + } + defer inputFile.Close() + + // 解码图像 + img, _, err := image.Decode(inputFile) + if err != nil { + return fmt.Errorf("解码图像时出错:%w", err) + } + + // 将图像转换为RGBA模式 + rgba := image.NewRGBA(img.Bounds()) + for x := 0; x < img.Bounds().Max.X; x++ { + for y := 0; y < img.Bounds().Max.Y; y++ { + rgba.Set(x, y, img.At(x, y)) + } + } + + // 创建输出文件 + outputFile, err := os.Create(outputFilePath) + if err != nil { + return fmt.Errorf("创建输出文件时出错:%w", err) + } + defer outputFile.Close() + + // 编码图像为 PNG 格式并写入输出文件 + if err := png.Encode(outputFile, rgba); err != nil { + return fmt.Errorf("编码图像时出错:%w", err) + } + + return nil +} + +func ConvertJpegToPNG(jpgPath string) error { + // Open the JPEG file for reading + f, err := os.Open(jpgPath) + if err != nil { + return err + } + defer f.Close() + + // Check if the file is a JPEG image + _, err = jpeg.Decode(f) + if err != nil { + // The file is not a JPEG image, no need to convert it + return fmt.Errorf("file %s is not a JPEG image", jpgPath) + } + + // Reset the file pointer to the beginning of the file + _, err = f.Seek(0, 0) + if err != nil { + return err + } + + // Create a new PNG file for writing + pngPath := jpgPath[:len(jpgPath)-4] + ".png" // replace .jpg extension with .png + out, err := os.Create(pngPath) + if err != nil { + return err + } + defer out.Close() + + // Decode the JPEG image and encode it as PNG + img, err := jpeg.Decode(f) + if err != nil { + return err + } + err = png.Encode(out, img) + if err != nil { + return err + } + + return nil +} + +func GetImageCompressionType(path string) (string, error) { + // 打开文件 + file, err := os.Open(path) + if err != nil { + return "", err + } + defer file.Close() + + // 创建 bufio.Reader + reader := bufio.NewReader(file) + + // 解码图像 + _, format, err := image.DecodeConfig(reader) + if err != nil { + fmt.Println("err: ", err) + return "", err + } + + fmt.Println("format: ", format) + // 返回压缩类型 + return format, nil +} diff --git a/code/services/openai/test_file/img.png b/code/services/openai/test_file/img.png new file mode 100644 index 0000000000000000000000000000000000000000..3071bd714edc8dd084b4be3efce7a251225c5d8c GIT binary patch literal 13697 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

+=)|zW9bmcJqZA5f;T`~W;|z~ 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�d18r){G|`(y=M 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

R7m2yG;0uDQA7wbSh5Ami339`M~AxFW5l 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 W1bukm1XBTIp>@RfQTfR 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 qj1PI$&WLqc(IXMJ`UQ;I6td(-%a9ekpe=CND>/dev/null - fi - - if [ -n "$tunnel_subdomain" ]; then - zmicro ngrok http --subdomain "$tunnel_subdomain" ${PORT} --log $tunnel_log >>$tunnel_log 2>&1 & - else - zmicro ngrok http ${PORT} --log $tunnel_log >>$tunnel_log 2>&1 & - fi - - log::info "[$(timestamp)] starting ngrok ..." - # sleep 3 - - local url="" - while [ -z "$url" ]; do - sleep 1 - - log::info "[$(timestamp)] checking whether ngrok connected ..." - url=$(cat $tunnel_log | grep "url=" | head -n 1 | awk -F '=' '{print $8}') - if [ -n "$url" ]; then - break - fi - - if [ "$DEBUG" = "true" ]; then - log::info "[$(timestamp)] show ngrok connection info start ..." - cat $tunnel_log - log::info "[$(timestamp)] show ngrok connection info end ..." - fi - done - - log::info "[$(timestamp)] ngrok url: $(color::green $url)" - - export SITE_URL=$url - else - log::error "[$(timestamp)] unsupport TUNNEL_TYPE: $TUNNEL_TYPE" - return 1 - fi -} - -run() { - core "$@" -} - -run "$@" diff --git a/go.mod b/go.mod deleted file mode 100644 index b3d0072..0000000 --- a/go.mod +++ /dev/null @@ -1,119 +0,0 @@ -module github.com/go-zoox/chatgpt-for-chatbot-feishu - -go 1.20 - -require ( - github.com/go-zoox/chalk v1.0.2 - github.com/go-zoox/chatbot-feishu v1.3.0 - github.com/go-zoox/chatgpt-client v1.6.3 - github.com/go-zoox/cli v1.3.6 - github.com/go-zoox/core-utils v1.3.1 - github.com/go-zoox/feishu v1.4.2 - github.com/go-zoox/fetch v1.8.1 - github.com/go-zoox/fs v1.3.14 - github.com/go-zoox/logger v1.4.6 - github.com/go-zoox/openai-client v1.5.2 - github.com/go-zoox/retry v1.0.3 - github.com/go-zoox/zoox v1.12.37 -) - -require ( - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/creack/pty v1.1.21 // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/docker/cli v24.0.7+incompatible // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v24.0.7+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-errors/errors v1.5.1 // indirect - github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/go-zoox/cache v1.0.6 // indirect - github.com/go-zoox/command v1.3.0 // indirect - github.com/go-zoox/commands-as-a-service v1.6.10 // indirect - github.com/go-zoox/compress v1.0.1 // indirect - github.com/go-zoox/concurrency v1.2.0 // indirect - github.com/go-zoox/config v1.2.10 // indirect - github.com/go-zoox/cookie v1.2.0 // indirect - github.com/go-zoox/counter v1.2.1 // indirect - github.com/go-zoox/cron v1.2.0 // indirect - github.com/go-zoox/crypto v1.1.8 // indirect - github.com/go-zoox/datetime v1.2.2 // indirect - github.com/go-zoox/debug v1.0.2 // indirect - github.com/go-zoox/dotenv v1.2.3 // indirect - github.com/go-zoox/encoding v1.2.1 // indirect - github.com/go-zoox/errors v1.0.2 // indirect - github.com/go-zoox/gzip v1.0.0 // indirect - github.com/go-zoox/headers v1.0.8 // indirect - github.com/go-zoox/i18n v1.0.3 // indirect - github.com/go-zoox/ini v1.0.4 // indirect - github.com/go-zoox/jobqueue v1.0.0 // indirect - github.com/go-zoox/jsonrpc v1.2.2 // indirect - github.com/go-zoox/jwt v1.3.0 // indirect - github.com/go-zoox/kv v1.5.9 // indirect - github.com/go-zoox/lru v1.0.1 // indirect - github.com/go-zoox/mq v1.0.1 // indirect - github.com/go-zoox/proxy v1.5.6 // indirect - github.com/go-zoox/pubsub v1.2.2 // indirect - github.com/go-zoox/random v1.0.4 // indirect - github.com/go-zoox/ratelimit v1.2.1 // indirect - github.com/go-zoox/safe v1.0.1 // indirect - github.com/go-zoox/session v1.2.0 // indirect - github.com/go-zoox/tag v1.2.3 // indirect - github.com/go-zoox/uuid v0.0.1 // indirect - github.com/goccy/go-yaml v1.11.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/uuid v1.5.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect - github.com/joho/godotenv v1.5.1 // indirect - github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/morikuni/aec v1.0.0 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.2 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/redis/go-redis/v9 v9.3.0 // indirect - github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sevlyar/go-daemon v0.1.6 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/tidwall/gjson v1.17.0 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.1 // indirect - github.com/urfave/cli/v2 v2.25.7 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/crypto v0.16.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -// replace github.com/go-zoox/chatbot-feishu => ../chatbot-feishu - -// replace github.com/go-zoox/feishu => ../feishu - -// replace github.com/go-zoox/logger => ../logger - -// replace github.com/go-zoox/chatbot-feishu => ../../go-zoox/chatbot-feishu - -// replace github.com/go-zoox/openai-client => ../../go-zoox/openai-client - -// replace github.com/go-zoox/chatgpt-client => ../../go-zoox/chatgpt-client - -// replace github.com/go-zoox/feishu => ../../go-zoox/feishu - -// replace github.com/go-zoox/zoox => ../zoox diff --git a/go.sum b/go.sum deleted file mode 100644 index 3c85bca..0000000 --- a/go.sum +++ /dev/null @@ -1,444 +0,0 @@ -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= -github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= -github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg= -github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= -github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= -github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= -github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/go-zoox/cache v1.0.6 h1:Ozix1WuLvyMb4laZozL2LVEjYA5SwjmoFfqUXO3Luhg= -github.com/go-zoox/cache v1.0.6/go.mod h1:rDQPnldnf1V8tKCn5e1MrkDXI2BFTws7PniTQQa2lpc= -github.com/go-zoox/chalk v1.0.1/go.mod h1:z5+qvE9nEJI5uT4px2tyoFa/xxkqf3CUo22KmXLKbNI= -github.com/go-zoox/chalk v1.0.2 h1:DCWft37fogmvqF37JdbGSLg28L/tQeA8u0lMvb62KOg= -github.com/go-zoox/chalk v1.0.2/go.mod h1:z5+qvE9nEJI5uT4px2tyoFa/xxkqf3CUo22KmXLKbNI= -github.com/go-zoox/chatbot-feishu v1.3.0 h1:FW8F0ApQRQELHpwaG5dzrSLwXBTBegRs1eGILXC/UnA= -github.com/go-zoox/chatbot-feishu v1.3.0/go.mod h1:EmJRYc27aLYWoPAupEsUBmzhn8r/5YYbzgAGXZjBlHo= -github.com/go-zoox/chatgpt-client v1.6.3 h1:+xNDXQWT5wJ18fgzenWxu63XA8LcJTfANkq4X8xhom8= -github.com/go-zoox/chatgpt-client v1.6.3/go.mod h1:kVESS3pFzNvMOhuxMbT2Je+OgQfs4svP80LaO/2fV/o= -github.com/go-zoox/cli v1.3.6 h1:+A4l9aBBvqO/xXjwZ1PCcX0ue/HZ/Ft0Wp/dDq27iVE= -github.com/go-zoox/cli v1.3.6/go.mod h1:25ox3mVRJdRSyLJLvK8OHYEuXtMtfkTseWkJjlK9kM4= -github.com/go-zoox/command v1.2.9 h1:7vY0TJ3iXB7qmmhdmx+CcRWDrrPq0ITEm8NXLMLT/g4= -github.com/go-zoox/command v1.2.9/go.mod h1:U6Jt52RImxJVpSHAwYl4V5eESk5QRpRXoboXqu1oz5k= -github.com/go-zoox/command v1.3.0 h1:9VpRqEYXWJTbVjrfkTmKYmWSDqpYv7TKsQ9nker8yAE= -github.com/go-zoox/command v1.3.0/go.mod h1:U6Jt52RImxJVpSHAwYl4V5eESk5QRpRXoboXqu1oz5k= -github.com/go-zoox/commands-as-a-service v1.6.5 h1:JQJpgP9VorTySGDP1gd1jC/Ildy4gTok6zWkD3S9NEs= -github.com/go-zoox/commands-as-a-service v1.6.5/go.mod h1:oWIRqTWIzmJdgVB1UoAgiCfFoswhJ8PDfATmb+JLsHE= -github.com/go-zoox/commands-as-a-service v1.6.10 h1:bpTgqTcy0SzJX7swlct/Iw67ueiuzVXuqgW7zuDtEHE= -github.com/go-zoox/commands-as-a-service v1.6.10/go.mod h1:he7ThLjNUzWzw5sZNANoxsmUvEYSprvlQNbHw+iJagw= -github.com/go-zoox/compress v1.0.1 h1:EyNxo5NscMLua5fvUdiGSF+BwhuTfMeyppu7OwKAW7Q= -github.com/go-zoox/compress v1.0.1/go.mod h1:iV6CcNulf3OuEfA1h1VOsaBqYH81cVSg5wNi5HDx2h4= -github.com/go-zoox/concurrency v1.2.0 h1:iucwSWQ0Y9fFIG+eZvyHjMrIPSnaKJTGfOcGbIx91yg= -github.com/go-zoox/concurrency v1.2.0/go.mod h1:rghauUPHEDp8HJzaVlU851HWqiAqD8lUVp45K/dtNvw= -github.com/go-zoox/config v1.2.10 h1:mebuz6O0N81OXOCwtV+LKOiFuAfZ5wyaGsuzkGSSpf4= -github.com/go-zoox/config v1.2.10/go.mod h1:KnSEhz7AVMqQfznJzgpzFhQfgy8UZYeone/osbvnVUE= -github.com/go-zoox/cookie v1.2.0 h1:MO33lPQ/QGJIAEzgrsAfEpJc25lcJ/XR0w+smM19sNQ= -github.com/go-zoox/cookie v1.2.0/go.mod h1:+xEawxty0L+z+4EIvTF2AaHUkUM7oIecGZ9XrEaYqsI= -github.com/go-zoox/core-utils v1.0.4/go.mod h1:EknM3KLL6/kagL95wZbWE7mRRcYCG/fHqiJ/EH0ihAs= -github.com/go-zoox/core-utils v1.0.12/go.mod h1:EknM3KLL6/kagL95wZbWE7mRRcYCG/fHqiJ/EH0ihAs= -github.com/go-zoox/core-utils v1.0.13/go.mod h1:EknM3KLL6/kagL95wZbWE7mRRcYCG/fHqiJ/EH0ihAs= -github.com/go-zoox/core-utils v1.3.1 h1:uH8cWA3hYOox68+b87/j4sxUGkHjqf/EFsN/JIasCFE= -github.com/go-zoox/core-utils v1.3.1/go.mod h1:raOOwr2l2sJQyjR0Dg33sg0ry4U1/L2eNTuLFRpUXWs= -github.com/go-zoox/counter v1.0.1/go.mod h1:PICilZTrnO4dFstDPlXpjc6sdWYBG7hm/XDmjAcHaX0= -github.com/go-zoox/counter v1.2.1 h1:MPShpjJWQ/qt3pYQxuyBL/Ci6X4mtihTC3cwDr1VOI8= -github.com/go-zoox/counter v1.2.1/go.mod h1:gOA/Bk2iWt9K4vm2Std2ciEgHwQqWSzvcyUI+jFVduY= -github.com/go-zoox/cron v1.1.2 h1:4iEIXIYu8MFRWBZccPaQ7wkpmvBs/N6a0FzWYiup9AU= -github.com/go-zoox/cron v1.1.2/go.mod h1:7aOIpwGDyyg+NqX+041NO+9f8FhAngWiLqBPBN6kZ9k= -github.com/go-zoox/cron v1.2.0 h1:WAcfeg0R6sASs9HjNwDz+uEIUrl62jj0zBSOF3oox9c= -github.com/go-zoox/cron v1.2.0/go.mod h1:vN6JqnvSgF9Rjjg/+cTxm8HywA3U+0cwP9RW3kdkg4E= -github.com/go-zoox/crypto v1.0.3/go.mod h1:HaWRg4tHZamqNyOnNoaK+Rw5eto+su66i8bMMP8UCBU= -github.com/go-zoox/crypto v1.1.8 h1:oI2KPLy+SsGeb+h5A99n9MTQVp4jBhwJWkqjStUzz9I= -github.com/go-zoox/crypto v1.1.8/go.mod h1:JqgNr9HcFFGQkMCGLJ9djtfg/RWVLxtunG01HD3lUXM= -github.com/go-zoox/datetime v1.0.4/go.mod h1:os6lYW/GXNpCIseFrBr8DNcOiPuwl5Ttc/kxo4JnMjw= -github.com/go-zoox/datetime v1.2.2 h1:JrI4ekdsvpsenGzrNQAOmobBTYyotaXD3YDXngvCbM4= -github.com/go-zoox/datetime v1.2.2/go.mod h1:qvaCrzjhq/g/gstx4sx06Nl4ll2pLSrkRa9ueLjrZ9A= -github.com/go-zoox/debug v1.0.1/go.mod h1:7HvnBeV1dVuuGVnXSLdJ5OE6X/wIXAjIEyiaA7NqQPA= -github.com/go-zoox/debug v1.0.2 h1:nnaSGUC1F3218P3BN6ZhRR5GNKtx5DKZ1RtsvAhIjyA= -github.com/go-zoox/debug v1.0.2/go.mod h1:7HvnBeV1dVuuGVnXSLdJ5OE6X/wIXAjIEyiaA7NqQPA= -github.com/go-zoox/dotenv v1.0.7/go.mod h1:N2bXxghq3Zk+lpiOxv+m+0yjnGubVqJGJDR/9jWm3N0= -github.com/go-zoox/dotenv v1.1.0/go.mod h1:elKALomz436YKX4Syo+f02ozIQYq2yFaprj6jL6GnCQ= -github.com/go-zoox/dotenv v1.2.3 h1:9wx4sL2u/FrRLkzoOb7ozYii6NoGsl05KoGdZm1ebIE= -github.com/go-zoox/dotenv v1.2.3/go.mod h1:hhl5WZUxI+DNJN6Zos1y7Nq0jDCXciphswPSYtInqg0= -github.com/go-zoox/encoding v1.0.5/go.mod h1:WFF+m/IWYHtClMrcKnrdZHHf3cdIF8de2uTOILPM7lw= -github.com/go-zoox/encoding v1.0.7/go.mod h1:h6ZgI27IaUSBq1ntaZjnSruPdRFuBLNUmfp57TaPxs4= -github.com/go-zoox/encoding v1.2.1 h1:38rQRsfL1f1YHZaqsPaGcNMkPnzatnPlYiHioUh9F4A= -github.com/go-zoox/encoding v1.2.1/go.mod h1:NdcM7Ln73oVW3vJgx3MH4fJknCcdQfq+NgJ0tuCo7tU= -github.com/go-zoox/errors v1.0.2 h1:1NLMoEVlDU1+qrvvPj+rrJXOvQPdeZ3DekVBFrI5PFY= -github.com/go-zoox/errors v1.0.2/go.mod h1:HJ5NKQb9cu3IbI0Jayw7xZiblLBEIglpaIOMxvQnWnk= -github.com/go-zoox/feishu v1.4.0 h1:zdk0Qf4RuvVBUH/S/eOqgV1ZHS4IuphZkYT4TauTtBM= -github.com/go-zoox/feishu v1.4.0/go.mod h1:Wz3RsfxM9mZEMvsFR1tHbkqrjk9XvXioQo8Gnr5kvbk= -github.com/go-zoox/feishu v1.4.2 h1:XU+M4r8ga5JPO3dDdRbkc5Fd+0ShXy3c6xJd0TE6cFk= -github.com/go-zoox/feishu v1.4.2/go.mod h1:Wz3RsfxM9mZEMvsFR1tHbkqrjk9XvXioQo8Gnr5kvbk= -github.com/go-zoox/fetch v1.3.5/go.mod h1:AkS6v/DlotjmUs+7qJsoFGFkpROr9LVtiKYb000v3Kw= -github.com/go-zoox/fetch v1.4.4/go.mod h1:WExVnds3HZ1A6jJu9KuqtICfkJpvUdR4uONUnw9TG+0= -github.com/go-zoox/fetch v1.7.16 h1:3bRoF2bG+M5PnWoFXka64PfHRx35Y60Mu70z2F5USDM= -github.com/go-zoox/fetch v1.7.16/go.mod h1:zaDVj8s8gPFzEeFFsD2oWc5D1z8uKKQwwnilmPdSQOk= -github.com/go-zoox/fetch v1.8.1 h1:Zh2yW/loXSoSebKZ1UkKKMpH/E51HtFb9L0zpr+2R2I= -github.com/go-zoox/fetch v1.8.1/go.mod h1:RaYJe2EZ/4M9zUyJl9x8HhMkQ/4HfxvdqYVkRp8IY1k= -github.com/go-zoox/fs v1.2.4/go.mod h1:aywpClMqf6YO8+QnuwC3p3EvFWe88h0tWH65rpxtY00= -github.com/go-zoox/fs v1.2.5/go.mod h1:aywpClMqf6YO8+QnuwC3p3EvFWe88h0tWH65rpxtY00= -github.com/go-zoox/fs v1.3.14 h1:u5vws9DdxCKh6U6SztIGIzVcZyydXbpSrV0S+cXzP7c= -github.com/go-zoox/fs v1.3.14/go.mod h1:GGcmvYa1Kyvspc8YzPt0peLGie+KlCoo2gkg4XbGRiY= -github.com/go-zoox/gzip v1.0.0 h1:11ZTgxAPgexmZ/NJaEEuN2FDCJuvg9sips+XDR+48Yw= -github.com/go-zoox/gzip v1.0.0/go.mod h1:7g9vTpKek1dft1Yi1Ryi4A6dq9snMgq94Qq8wSte8L0= -github.com/go-zoox/headers v1.0.8 h1:HZJisMHhKwdySVNbV4Awc5kaMxFfAwBIHpcWOGch+iw= -github.com/go-zoox/headers v1.0.8/go.mod h1:WEgEbewswEw4n4qS1iG68Kn/vOQVCAKGwwuZankc6so= -github.com/go-zoox/i18n v1.0.3 h1:PqeOKyhI9MxbA9TyWDgm7zcCL5WRSlxhANHWou04VHk= -github.com/go-zoox/i18n v1.0.3/go.mod h1:WURpyaWOrVVN4f3mEQtl5A0kie5bK4ExQJ0PnHSOfTI= -github.com/go-zoox/ini v1.0.4 h1:N4mUbAO0juYIRrv3ysjKtpEn/+yQv57eQietsgpkAYQ= -github.com/go-zoox/ini v1.0.4/go.mod h1:SisQneNLb1EBeZ5bA5GnrJd8FNg372hQrPh+gb3IzV4= -github.com/go-zoox/jobqueue v1.0.0 h1:pVv/eGI0CLLHUP3rDVyn0ALzsobtaxTOnkWw/JhW9Vg= -github.com/go-zoox/jobqueue v1.0.0/go.mod h1:jUCZxrQcM28orhac67eNLU7SBiVNXehxSelj7j4MM88= -github.com/go-zoox/jsonrpc v1.2.2 h1:asaoJgJkfyH5eblLQ1WzrZDe8ERL6v9GT4pKR/LJ3IE= -github.com/go-zoox/jsonrpc v1.2.2/go.mod h1:HdxJW/T0hkVHlfm+ULRnNEqvTtvZ7o4qxdQGQW76khM= -github.com/go-zoox/jwt v1.0.0/go.mod h1:a6ANQHmSs+b9GJv5aad2cQLl8opFmP3hMOxZtgXRmis= -github.com/go-zoox/jwt v1.3.0 h1:beyPOdiiNrNK8dqFijt5kdtaeh1dZKtM7/kaCMGbV0U= -github.com/go-zoox/jwt v1.3.0/go.mod h1:Cfc+t0XhNCgDjXLR5sK6ao7qz1GSIq896gZ1usNb7t8= -github.com/go-zoox/kv v1.4.1/go.mod h1:dc3whoIvGrYmQA2wi6g6ZE0oOtRg+loxaJEj6bLKlJA= -github.com/go-zoox/kv v1.4.3/go.mod h1:hRCBcPBHilKmeSEsn4o67LBaXurX0+m3Tq9Ec4aIRWk= -github.com/go-zoox/kv v1.5.9 h1:xEjIRJVcwIg2PhO0ZL+KWR5mCI/f5VshmcOjZPd4FRA= -github.com/go-zoox/kv v1.5.9/go.mod h1:sD2FmWrme1gzWaLciBAPyK0BtW3BluM02UGskOqf2MA= -github.com/go-zoox/logger v1.2.0/go.mod h1:mBImRV6zpbGtiIjDz/C9vWi80wWc2OTOl9N9P0SAJgk= -github.com/go-zoox/logger v1.4.6 h1:zHUaB6KQ9rD/N3hM0JJ3/JCNdgtedf4mVBBNNSyWCOg= -github.com/go-zoox/logger v1.4.6/go.mod h1:o7ddvv/gMoMa0TomPhHoIz11ZWRbQ92pF6rwYbOY3iQ= -github.com/go-zoox/lru v1.0.1 h1:AvRHxKEeEFSH9UXyfDQ5lj8nr66p6tJS3kVf/eTVyMg= -github.com/go-zoox/lru v1.0.1/go.mod h1:xxtYsRbJ2iJKEL4OIEZ6lk0xjuGJHHZmZZhGtH5qwv0= -github.com/go-zoox/mq v1.0.1 h1:JZSgWfp4JJDVKN8FgUkWWNDb3HOhV15dIdi+ecZENwQ= -github.com/go-zoox/mq v1.0.1/go.mod h1:0Zhgww1wcFNC37NJZjtumai03MvBAZuQ4VhezcAiFJE= -github.com/go-zoox/openai-client v1.5.2 h1:oOxXRb+0H0e59SfXz23zVZtP/G/FBuNZeOws3qTjE10= -github.com/go-zoox/openai-client v1.5.2/go.mod h1:h6vfyPajS1ScdALzDb+CwcSiMH3WKqScma0qH+SlRF8= -github.com/go-zoox/proxy v1.2.3/go.mod h1:T+gbngAtIgvambbYibAbzrjwdu8j5pduJdA2j6RYi94= -github.com/go-zoox/proxy v1.5.6 h1:Ha5wsSjIi57TcYJnb4iBrW1xmJlNW2E7dWjUIwIe6iE= -github.com/go-zoox/proxy v1.5.6/go.mod h1:KLWeJqfQk1upCvEdXt3tEuM8xSu0ApbA9FNLOmyHysY= -github.com/go-zoox/pubsub v1.2.2 h1:dpcFlZRSGhX0YqT/WoOJgP5bP2VDqswPqXiiFZCki1w= -github.com/go-zoox/pubsub v1.2.2/go.mod h1:LWX0NAg80hkeGdZf7PJOEGnyN6CXooCxpIlh2MxESDo= -github.com/go-zoox/random v1.0.0/go.mod h1:W+PTQiInxaCngiXpSvycucAKvu1tE/tKlZ9kaMp2/Ys= -github.com/go-zoox/random v1.0.4 h1:icckpkCowQ0eGiiMkHFOJz9Qc9noOcinP+ggqWUIBH4= -github.com/go-zoox/random v1.0.4/go.mod h1:W+PTQiInxaCngiXpSvycucAKvu1tE/tKlZ9kaMp2/Ys= -github.com/go-zoox/ratelimit v1.0.1/go.mod h1:5MtLMrfQRbZHI+tKC4eyHZorrZX005Sy/Dldnk8qYOU= -github.com/go-zoox/ratelimit v1.2.1 h1:iFuD6Md2jDERFXF2oiAzyt+px+SIOu+ICHIoB7v2KgY= -github.com/go-zoox/ratelimit v1.2.1/go.mod h1:CyFcL4Cpm7O8jvry9O+AlxyrgJGgvl4ebo4j0D3CGHA= -github.com/go-zoox/retry v1.0.3 h1:qpGq2Dqe9/mjhryDDwMEFWN+YDLHvpXL5hfwKJ1yTC4= -github.com/go-zoox/retry v1.0.3/go.mod h1:4NJ0wCtxGgHwzHYIN4bG1VnQ19w3rY2kzyOpNfm7x5o= -github.com/go-zoox/safe v1.0.1 h1:JwWK7xCyv7eyzBbwzQvhK/Ajm8gG2Q9Cvd/KXpdF2zI= -github.com/go-zoox/safe v1.0.1/go.mod h1:lT0iEBmpoia7xfh2bWzdurzdv++4QRUAfeEzIhCnpoA= -github.com/go-zoox/session v1.2.0 h1:hzjcZYV3+cVmocnC6MazhtELONMtRlIuEezCYvbxY9Q= -github.com/go-zoox/session v1.2.0/go.mod h1:SLHzCK3DDknqot28deZQFBPz5hm9QHcUeRra8y9GT8E= -github.com/go-zoox/tag v1.0.2/go.mod h1:TNFY+IN6FgsD0KGV6mrnuVXONUq7zpH01k53BcNsT8k= -github.com/go-zoox/tag v1.0.6/go.mod h1:jrbJgC1dZAN5+vZlmrUKu1/UpbOo0xVyCC1MfLpGGqk= -github.com/go-zoox/tag v1.0.9/go.mod h1:jrbJgC1dZAN5+vZlmrUKu1/UpbOo0xVyCC1MfLpGGqk= -github.com/go-zoox/tag v1.1.0/go.mod h1:yMB7bMseqbOshUW9O9Dqfq0C7Mmy9OkccV/meEJHICs= -github.com/go-zoox/tag v1.2.3 h1:HDQpRu8rA1xSJt6c+v0O7TfzTjPq5aDtyzW/15aTh94= -github.com/go-zoox/tag v1.2.3/go.mod h1:z9z4iZb/XPE4HwTXJgPIdwgH90c2NysGxIMq9tW+GuU= -github.com/go-zoox/testify v1.0.2 h1:G5sQ3xm0uwCuytnMhgnqZ5BItCt2DN3n2wLBqlIJEWA= -github.com/go-zoox/uuid v0.0.1 h1:txqmDavRTq68gzzqWfJQLorFyUp9a7M2lmq2KcwPGPA= -github.com/go-zoox/uuid v0.0.1/go.mod h1:0/F4LdfLqFdyqOf7aXoiYXRkXHU324JQ5DZEytXYBPM= -github.com/go-zoox/zoox v1.2.19/go.mod h1:xk3S3L58ugJIDyuZMCYrj3qIGLSxddbkARwTRkpxPVE= -github.com/go-zoox/zoox v1.12.29 h1:eg4ug+sXvWt2w9KEaSyrV4Fzv0QE4dcCweKApcu2ZJY= -github.com/go-zoox/zoox v1.12.29/go.mod h1:Z8VmwMC7mahiXErAvy8GXv+tM8LHT0YPNOGLSycGTYw= -github.com/go-zoox/zoox v1.12.37 h1:8gQfx2ZR6UN6A9oSIQll/rHf1KBGV5YDD5iILhpZl0Q= -github.com/go-zoox/zoox v1.12.37/go.mod h1:kTJ7oHR9fui8FO06BWA1DC3fouAYCzpdQgwmopAPh10= -github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= -github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= -github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0= -github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= -github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= -github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs= -github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= -github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 h1:OXcKh35JaYsGMRzpvFkLv/MEyPuL49CThT1pZ8aSml4= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= diff --git a/logs.go b/logs.go deleted file mode 100644 index 3bd835c..0000000 --- a/logs.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import ( - "os" - - "github.com/go-zoox/core-utils/fmt" - "github.com/go-zoox/fs" - "github.com/go-zoox/logger" - "github.com/go-zoox/logger/components/transport" - "github.com/go-zoox/logger/transport/file" -) - -type Logs struct { - Dir string - Level string - - // - accessLogFile *os.File - errorLogFile *os.File - debugLogFile *os.File -} - -func (l *Logs) Setup() (err error) { - if ok := fs.IsExist(l.Dir); !ok { - if err := fs.Mkdirp(l.Dir); err != nil { - return fmt.Errorf("failed to create log directory for : %v", err) - } - } - - accessLog := fs.JoinPath(l.Dir, "access.log") - if l.accessLogFile, err = fs.Open(accessLog); err != nil { - return fmt.Errorf("failed to open access log(%s): %v", accessLog, err) - } - errorLog := fs.JoinPath(l.Dir, "error.log") - if l.errorLogFile, err = fs.Open(errorLog); err != nil { - return fmt.Errorf("failed to open error log(%s): %v", accessLog, err) - } - debugLog := fs.JoinPath(l.Dir, "debug.log") - if l.debugLogFile, err = fs.Open(debugLog); err != nil { - return fmt.Errorf("failed to open debug log(%s): %v", accessLog, err) - } - - logger.AppendTransports(map[string]transport.Transport{ - "access": file.New(&file.Config{ - Level: "info", - File: l.accessLogFile, - Exact: true, - }), - "error": file.New(&file.Config{ - Level: "error", - File: l.errorLogFile, - Exact: true, - }), - "debug": file.New(&file.Config{ - Level: "debug", - File: l.debugLogFile, - Exact: true, - }), - }) - - logger.SetLevel(l.Level) - - return nil -} diff --git a/main.go b/main.go deleted file mode 100644 index cbbb927..0000000 --- a/main.go +++ /dev/null @@ -1,202 +0,0 @@ -package main - -import ( - "github.com/go-zoox/chatgpt-for-chatbot-feishu/config" - "github.com/go-zoox/cli" -) - -func main() { - app := cli.NewSingleProgram(&cli.SingleProgramConfig{ - Name: "chatgpt-for-chatbot-feishu", - Usage: "chatgpt-for-chatbot-feishu is a portable chatgpt server", - Version: Version, - Flags: []cli.Flag{ - &cli.IntFlag{ - Name: "port", - Usage: "server port", - Aliases: []string{"p"}, - EnvVars: []string{"PORT"}, - Value: 8080, - }, - &cli.StringFlag{ - Name: "api-path", - Usage: "custom api path, default: /", - EnvVars: []string{"API_PATH"}, - Value: "/", - }, - &cli.StringFlag{ - Name: "openai-api-key", - Usage: "OpenAI API Key", - EnvVars: []string{"OPENAI_API_KEY"}, - // Required: true, - }, - &cli.Int64Flag{ - Name: "openai-api-timeout", - Usage: "OpenAI API Timeout, unit: second, default: 300", - EnvVars: []string{"OPENAI_API_TIMEOUT"}, - Value: 300, - }, - &cli.StringFlag{ - Name: "openai-api-server", - Usage: "OpenAI API Server", - EnvVars: []string{"OPENAI_API_SERVER"}, - }, - &cli.StringFlag{ - Name: "openai-api-type", - Usage: "OpenAI API Type", - EnvVars: []string{"OPENAI_API_TYPE"}, - }, - &cli.StringFlag{ - Name: "openai-azure-resource", - Usage: "Azure OpenAI Service Resource", - EnvVars: []string{"OPENAI_AZURE_RESOURCE"}, - }, - &cli.StringFlag{ - Name: "openai-azure-deployment", - Usage: "Azure OpenAI Service Deployment", - EnvVars: []string{"OPENAI_AZURE_DEPLOYMENT"}, - }, - &cli.StringFlag{ - Name: "openai-azure-api-version", - Usage: "Azure OpenAI Service API Version", - EnvVars: []string{"OPENAI_AZURE_API_VERSION"}, - }, - &cli.StringFlag{ - Name: "app-id", - Usage: "Feishu App ID", - EnvVars: []string{"APP_ID"}, - Required: true, - }, - &cli.StringFlag{ - Name: "app-secret", - Usage: "Feishu App SECRET", - EnvVars: []string{"APP_SECRET"}, - Required: true, - }, - &cli.StringFlag{ - Name: "encrypt-key", - Usage: "enable encryption if you need", - EnvVars: []string{"ENCRYPT_KEY"}, - }, - &cli.StringFlag{ - Name: "verification-token", - Usage: "enable token verification if you need", - EnvVars: []string{"VERIFICATION_TOKEN"}, - }, - &cli.StringFlag{ - Name: "report-url", - Usage: "Set error report url", - EnvVars: []string{"REPORT_URL"}, - }, - &cli.StringFlag{ - Name: "site-url", - Usage: "The Site URL", - EnvVars: []string{"SITE_URL"}, - }, - &cli.StringFlag{ - Name: "openai-model", - Usage: "Custom open ai model", - EnvVars: []string{"OPENAI_MODEL"}, - }, - &cli.Float64Flag{ - Name: "openai-temperature", - Usage: "Custom open ai temperature", - EnvVars: []string{"OPENAI_TEMPERATURE"}, - Value: 0.3, - }, - &cli.StringFlag{ - Name: "feishu-base-uri", - Usage: "Custom feishu base uri for selfhosted Feishu", - EnvVars: []string{"FEISHU_BASE_URI"}, - }, - &cli.StringFlag{ - Name: "conversation-context", - Usage: "Custom chatgpt conversation context", - EnvVars: []string{"CONVERSATION_CONTEXT"}, - }, - &cli.StringFlag{ - Name: "conversation-language", - Usage: "Custom chatgpt conversation lanuage", - EnvVars: []string{"CONVERSATION_LANGUAGE"}, - }, - &cli.StringFlag{ - Name: "logs-dir", - Usage: "The logs dir for save logs", - EnvVars: []string{"LOGS_DIR"}, - Value: "/tmp/chatgpt-for-chatbot-feishu", - }, - &cli.StringFlag{ - Name: "logs-level", - Usage: "The logs level", - EnvVars: []string{"LOGS_LEVEL", "LOG_LEVEL"}, - Value: "INFO", - }, - &cli.StringFlag{ - Name: "offline-message", - Usage: "The message to use for offline status", - EnvVars: []string{"OFFLINE_MESSAGE"}, - Value: "robot is offline", - }, - &cli.StringFlag{ - Name: "admin-email", - Usage: "Sets the admin with admin email, who can run commands", - EnvVars: []string{"ADMIN_EMAIL"}, - }, - &cli.StringFlag{ - Name: "bot-name", - Usage: "Sets the bot name, default: ChatGPT", - EnvVars: []string{"BOT_NAME"}, - }, - &cli.StringFlag{ - Name: "proxy", - Usage: "Sets the request proxy", - EnvVars: []string{"PROXY", "HTTPS_PROXY"}, - }, - &cli.StringFlag{ - Name: "custom-command", - Usage: "Custom command, such as: doc => trigger /doc", - EnvVars: []string{"CUSTOM_COMMAND"}, - }, - &cli.StringFlag{ - Name: "custom-command-service", - Usage: "Custom command service, such as: https://example.com/api/doc", - EnvVars: []string{"CUSTOM_COMMAND_SERVICE"}, - }, - }, - }) - - app.Command(func(ctx *cli.Context) (err error) { - return ServeFeishuBot(&config.Config{ - LogsDir: ctx.String("logs-dir"), - LogsLevel: ctx.String("logs-level"), - Port: ctx.Int64("port"), - APIPath: ctx.String("api-path"), - OpenAIAPIKey: ctx.String("openai-api-key"), - OpenAIAPITimeout: ctx.Int64("openai-api-timeout"), - AppID: ctx.String("app-id"), - AppSecret: ctx.String("app-secret"), - EncryptKey: ctx.String("encrypt-key"), - VerificationToken: ctx.String("verification-token"), - ReportURL: ctx.String("report-url"), - SiteURL: ctx.String("site-url"), - OpenAIModel: ctx.String("openai-model"), - OpenAITemperature: ctx.Float64("openai-temperature"), - FeishuBaseURI: ctx.String("feishu-base-uri"), - ConversationContext: ctx.String("conversation-context"), - ConversationLanguage: ctx.String("conversation-language"), - OfflineMessage: ctx.String("offline-message"), - AdminEmail: ctx.String("admin-email"), - BotName: ctx.String("bot-name"), - Proxy: ctx.String("proxy"), - OpenAIAPIServer: ctx.String("openai-api-server"), - OpenAIAPIType: ctx.String("openai-api-type"), - OpenAIAzureResource: ctx.String("openai-azure-resource"), - OpenAIAzureDeployment: ctx.String("openai-azure-deployment"), - OpenAIAzureAPIVersion: ctx.String("openai-azure-api-version"), - CustomCommand: ctx.String("custom-command"), - CustomCommandService: ctx.String("custom-command-service"), - }) - }) - - app.Run() -} diff --git a/server.go b/server.go deleted file mode 100644 index f03e683..0000000 --- a/server.go +++ /dev/null @@ -1,184 +0,0 @@ -package main - -import ( - "time" - - "github.com/go-zoox/chalk" - "github.com/go-zoox/chatbot-feishu" - "github.com/go-zoox/chatgpt-for-chatbot-feishu/commands" - "github.com/go-zoox/chatgpt-for-chatbot-feishu/config" - openaiclient "github.com/go-zoox/openai-client" - "github.com/go-zoox/zoox" - "github.com/go-zoox/zoox/defaults" - - "github.com/go-zoox/core-utils/fmt" - "github.com/go-zoox/feishu" - - chatgpt "github.com/go-zoox/chatgpt-client" - feishuEvent "github.com/go-zoox/feishu/event" - "github.com/go-zoox/logger" -) - -func ServeFeishuBot(cfg *config.Config) (err error) { - if cfg.OfflineMessage == "" { - cfg.OfflineMessage = "robot is offline" - } - - if cfg.OpenAIModel == "" { - cfg.OpenAIModel = openaiclient.ModelGPT_4 - } - - logger.Infof("###### Settings START #######") - logger.Infof("Serve Version: %s", Version) - logger.Infof("Serve at PORT: %d", cfg.Port) - logger.Infof("Serve at API_PATH: %s", cfg.APIPath) - logger.Infof("###### Settings END #######") - - logs := &Logs{ - Dir: cfg.LogsDir, - Level: cfg.LogsLevel, - } - if err := logs.Setup(); err != nil { - return fmt.Errorf("failed to setup logs: %v", err) - } - - chatgptClient, err := chatgpt.New(&chatgpt.Config{ - APIKey: cfg.OpenAIAPIKey, - APIServer: cfg.OpenAIAPIServer, - APIType: cfg.OpenAIAPIType, - AzureResource: cfg.OpenAIAzureResource, - AzureDeployment: cfg.OpenAIAzureDeployment, - AzureAPIVersion: cfg.OpenAIAzureAPIVersion, - ConversationContext: cfg.ConversationContext, - ConversationLanguage: cfg.ConversationLanguage, - ChatGPTName: cfg.BotName, - Proxy: cfg.Proxy, - Timeout: time.Duration(cfg.OpenAIAPITimeout) * time.Second, - }) - if err != nil { - return fmt.Errorf("failed to create chatgpt client: %v", err) - } - - feishuClient := feishu.New(&feishu.Config{ - AppID: cfg.AppID, - AppSecret: cfg.AppSecret, - BaseURI: cfg.FeishuBaseURI, - }) - - cfg.Version = Version - cfg.IsInService = true - - tryToGetBotInfo := func() { - for { - if cfg.BotInfo != nil { - break - } - - logger.Infof("Trying to get bot info ...") - cfg.BotInfo, err = feishuClient.Bot().GetBotInfo() - if err != nil { - logger.Errorf("failed to get bot info: %v", err) - return - } - - logger.Infof("Bot Name: %s", cfg.BotInfo.AppName) - logger.Infof("Feishu Bot Online ...") - time.Sleep(3 * time.Second) - } - } - - go func() { - tryToGetBotInfo() - }() - - fmt.PrintJSON(map[string]interface{}{ - "version": Version, - "cfg": cfg, - }) - - if cfg.SiteURL != "" { - logger.Infof("") - logger.Infof("###### Feishu Configuration START #######") - logger.Infof("# %s:%s", chalk.Red("飞书事件订阅请求地址"), chalk.Green(fmt.Sprintf("%s%s", cfg.SiteURL, cfg.APIPath))) - logger.Infof("###### Feishu Configuration END #######") - logger.Infof("") - } - - feishuchatbot, err := chatbot.New(&chatbot.Config{ - Port: cfg.Port, - Path: cfg.APIPath, - AppID: cfg.AppID, - AppSecret: cfg.AppSecret, - VerificationToken: cfg.VerificationToken, - EncryptKey: cfg.EncryptKey, - }) - if err != nil { - return fmt.Errorf("failed to create feishu chatbot: %v", err) - } - - feishuchatbot.OnCommand("ping", commands.CreatePingCommand(feishuClient, chatgptClient)) - - feishuchatbot.OnCommand("offline", commands.CreateOfflineCommand(feishuClient, chatgptClient, cfg)) - - feishuchatbot.OnCommand("online", commands.CreateOnlineCommand(feishuClient, chatgptClient, cfg)) - - feishuchatbot.OnCommand("model", commands.CreateModelCommand(feishuClient, chatgptClient, cfg)) - - feishuchatbot.OnCommand("reset", commands.CreateResetCommand(feishuClient, chatgptClient, cfg)) - - feishuchatbot.OnCommand("message", commands.CreateMessageCommand(feishuClient, chatgptClient, cfg)) - feishuchatbot.OnCommand("问答", commands.CreateMessageCommand(feishuClient, chatgptClient, cfg)) - - feishuchatbot.OnCommand("draw", commands.CreateDrawCommand(feishuClient, chatgptClient)) - feishuchatbot.OnCommand("画图", commands.CreateDrawCommand(feishuClient, chatgptClient)) - - if cfg.CustomCommand != "" && cfg.CustomCommandService != "" { - feishuchatbot.OnCommand(cfg.CustomCommand, commands.CreateCustomCommand(feishuClient, chatgptClient, cfg)) - } - - feishuchatbot.OnMessage(func(text string, request *feishuEvent.EventRequest, reply func(content string, msgType ...string) error) error { - return commands. - CreateMessageCommand(feishuClient, chatgptClient, cfg). - Handler([]string{text}, request, reply) - }) - - // return feishuchatbot.Run() - - return run( - feishuchatbot, - cfg.Port, - cfg.APIPath, - cfg.OpenAIAPIKey, - cfg.OpenAIAPIServer, - cfg.OpenAIAPIType, - cfg.OpenAIAzureResource, - cfg.OpenAIAzureDeployment, - cfg.OpenAIAzureAPIVersion, - ) -} - -func run( - chatbot chatbot.ChatBot, - port int64, - path, - OpenAIAPIKey, - OpenAIAPIServer, - OpenAIAPIType, - OpenAIAzureResource, - OpenAIAzureDeployment, - OpenAIAzureAPIVersion string, -) error { - if OpenAIAPIServer == "" { - OpenAIAPIServer = openaiclient.DefaultAPIServer - } - - app := defaults.Application() - - app.Post(path, chatbot.Handler()) - - app.Get(path, func(ctx *zoox.Context) { - ctx.String(200, "OK") - }) - - return app.Run(fmt.Sprintf(":%d", port)) -} diff --git a/version.go b/version.go deleted file mode 100644 index d6edad3..0000000 --- a/version.go +++ /dev/null @@ -1,4 +0,0 @@ -package main - -// Version is the version of lighthouse -var Version = "1.10.3"