Browse Source

Merge branch 'openapi-yaml' into whatsmeow-version

pull/103/head
Jose F. Franco 3 years ago
committed by GitHub
parent
commit
c88a8e4e98
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 71
      air.toml
  2. 15
      docker-compose.yml
  3. 20
      docker/golang.Dockerfile
  4. 64
      docs/openapi.yaml
  5. 70
      src/.air.toml
  6. 48
      src/cmd/root.go
  7. 4
      src/go.mod
  8. 58
      src/views/doc.html

71
air.toml

@ -0,0 +1,71 @@
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format
# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"
[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o /app/whatsapp"
# Binary file yields from `cmd`.
bin = "/app/whatsapp"
# Customize binary, can setup environment variables when run your app.
#full_bin = "APP_ENV=dev APP_USER=air /app/whatsapp"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl"]
# Ignore these filename extensions or directories.
exclude_dir = ["statics", "storages", "docker"]
# Watch these directories if you specified.
include_dir = []
# Watch these files.
include_file = []
# Exclude files.
exclude_file = []
# Exclude specific regular expressions.
exclude_regex = ["_test\\.go"]
# Exclude unchanged files.
exclude_unchanged = true
# Follow symlink for directories
follow_symlink = true
# This log file places in your tmp_dir.
log = "air.log"
# Poll files for changes instead of using fsnotify.
poll = false
# Poll interval (defaults to the minimum interval of 500ms).
poll_interval = 500 # ms
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 0 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms
# Rerun binary or not
rerun = false
# Delay after each executions
rerun_delay = 500
# Add additional arguments when running binary (bin/full_bin). Will run '/app/whatsapp hello world'.
args_bin = ["--os=Linux", "--debug", "true", "--basic-auth=admin:password"]
[log]
# Show log time
time = false
# Only show main log (silences watcher, build, runner)
main_only = false
[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"
[misc]
# Delete tmp directory on exit
clean_on_exit = true
[screen]
clear_on_rebuild = true
keep_scroll = true

15
docker-compose.yml

@ -6,10 +6,21 @@ services:
options:
max-size: "200k"
max-file: "10"
image: "aldinokemal2104/go-whatsapp-web-multidevice:latest"
image: jffrancob/wa-multidevice:latest
command: --os=Linux --debug true --basic-auth=admin:password
environment:
- SERVER_URL=http://${API_HOST-localhost}:${API_PORT-3000}
working_dir: /whatsapp
build:
context: .
dockerfile: ./docker/golang.Dockerfile
target: runtime
restart: 'always'
ports:
- "3000:3000"
- "3000:3000"
volumes:
#- ./src:/whatsapp/
#- ./air.toml:/whatsapp/.air.toml
- ./storages:/whatsapp/storages
- ./statics:/whatsapp/statics
#- ./docs/:/docs/

20
docker/golang.Dockerfile

@ -1,23 +1,35 @@
############################
# STEP 1 build executable binary
############################
FROM golang:alpine AS builder
FROM golang:1.20.5-alpine3.17 AS builder
RUN apk update && apk add --no-cache vips-dev gcc musl-dev gcompat ffmpeg
WORKDIR /whatsapp
COPY ./src .
# Fetch dependencies.
RUN go mod download
#RUN go mod tidy -e
# Install pkger
RUN go install github.com/markbates/pkger/cmd/pkger@latest
# Build the binary.
RUN pkger && go build -o /app/whatsapp
RUN pkger
RUN go build -o /app/whatsapp
#FROM builder AS dev
#RUN go install github.com/cosmtrek/air@latest
#RUN go mod tidy
#RUN go mod download
#CMD ["air", "-c", ".air.toml"]
#############################
## STEP 2 build a smaller image
#############################
FROM alpine:latest
RUN apk update && apk add --no-cache vips-dev ffmpeg
FROM alpine:3.17 as runtime
RUN apk update && apk add --no-cache vips ffmpeg
COPY ./docs /docs
WORKDIR /app
# Copy compiled from builder.
COPY --from=builder /app/whatsapp /app/whatsapp

64
docs/openapi.yaml

@ -103,8 +103,9 @@ paths:
- name: phone
in: query
schema:
type: integer
example: '6289685028129@s.whatsapp.net'
type: string
example: '573148901850'
description: Contact phone number (with country code)
responses:
'200':
description: OK
@ -134,8 +135,9 @@ paths:
- name: phone
in: query
schema:
type: integer
example: '6289685028129@s.whatsapp.net'
type: string
example: '573148901850'
description: Contact phone number (with country code)
- name: is_preview
in: query
schema:
@ -206,11 +208,11 @@ paths:
properties:
phone:
type: string
example: '6289685028129@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
message:
type: string
example: selamat malam
example: This is a *test* _message_ 😊
description: Message to send
responses:
'200':
@ -245,11 +247,11 @@ paths:
properties:
phone:
type: string
example: '6289685028129@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
caption:
type: string
example: selamat malam
example: Image caption
description: Caption to send
view_once:
type: boolean
@ -296,11 +298,11 @@ paths:
properties:
phone:
type: string
example: '6289685028129@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
caption:
type: string
example: selamat malam
example: File caption
description: Caption to send
file:
type: string
@ -339,11 +341,11 @@ paths:
properties:
phone:
type: string
example: '6289685028129@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
caption:
type: string
example: ini contoh caption video
example: Video caption
description: Caption to send
view_once:
type: boolean
@ -390,15 +392,15 @@ paths:
properties:
phone:
type: string
example: '6289685024051@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
contact_name:
type: string
example: Aldino Kemal
example: This is a test contact
description: Contact name
contact_phone:
type: string
example: '6289685024992'
example: '573208963960'
description: Contact phone number
responses:
'200':
@ -433,15 +435,15 @@ paths:
properties:
phone:
type: string
example: '6289685024051@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
link:
type: string
example: "https://google.com"
description: Link to send
caption:
type: string
example: 'Halo ini contoh caption'
example: Link caption
description: Caption to send
responses:
'200':
@ -476,15 +478,15 @@ paths:
properties:
phone:
type: string
example: '6289685024051@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
latitude:
type: string
example: "-7.797068"
example: "4.8087158"
description: Latitude coordinate
longitude:
type: string
example: '110.370529'
example: '-75.6787543'
description: Longitude coordinate
responses:
'200':
@ -526,8 +528,8 @@ paths:
properties:
phone:
type: string
example: '6289685024051@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
responses:
'200':
description: OK
@ -568,8 +570,8 @@ paths:
properties:
phone:
type: string
example: '6289685024051@s.whatsapp.net'
description: Phone number with country code
example: '573148901850'
description: Destination phone number (with country code)
emoji:
type: string
example: "🙏"

70
src/.air.toml

@ -1,5 +1,71 @@
root = '.'
# Config file for [Air](https://github.com/cosmtrek/air) in TOML format
# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"
[build]
exclude_dir = ["statics", "views"]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o /app/whatsapp"
# Binary file yields from `cmd`.
bin = "/app/whatsapp"
# Customize binary, can setup environment variables when run your app.
full_bin = "APP_ENV=dev APP_USER=air /app/whatsapp"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl"]
# Ignore these filename extensions or directories.
exclude_dir = ["statics", "storages", "docker"]
# Watch these directories if you specified.
include_dir = []
# Watch these files.
include_file = []
# Exclude files.
exclude_file = []
# Exclude specific regular expressions.
exclude_regex = ["_test\\.go"]
# Exclude unchanged files.
exclude_unchanged = true
# Follow symlink for directories
follow_symlink = true
# This log file places in your tmp_dir.
log = "air.log"
# Poll files for changes instead of using fsnotify.
poll = false
# Poll interval (defaults to the minimum interval of 500ms).
poll_interval = 500 # ms
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 0 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms
# Rerun binary or not
rerun = false
# Delay after each executions
rerun_delay = 500
# Add additional arguments when running binary (bin/full_bin). Will run '/app/whatsapp hello world'.
args_bin = ["--os=Linux", "--debug", "true", "--basic-auth=admin:password"]
[log]
# Show log time
time = false
# Only show main log (silences watcher, build, runner)
main_only = false
[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"
[misc]
# Delete tmp directory on exit
clean_on_exit = true
[screen]
clear_on_rebuild = true
keep_scroll = true

48
src/cmd/root.go

@ -20,6 +20,9 @@ import (
_ "github.com/mattn/go-sqlite3"
"github.com/spf13/cobra"
"log"
"io/ioutil"
"github.com/json-iterator/go"
"gopkg.in/yaml.v2"
"os"
"strings"
)
@ -109,13 +112,35 @@ func runRest(_ *cobra.Command, _ []string) {
rest.InitRestGroup(app, groupService)
app.Get("/", func(c *fiber.Ctx) error {
return c.Render("index", fiber.Map{
"AppHost": fmt.Sprintf("%s://%s", c.Protocol(), c.Hostname()),
"AppVersion": config.AppVersion,
"BasicAuthToken": c.UserContext().Value("token"),
"MaxFileSize": humanize.Bytes(uint64(config.WhatsappSettingMaxFileSize)),
"MaxVideoSize": humanize.Bytes(uint64(config.WhatsappSettingMaxVideoSize)),
})
serverURL := os.Getenv("SERVER_URL")
if len(serverURL) != 0 {
apiDoc, err := ioutil.ReadFile("/docs/openapi.yaml")
if err != nil {
log.Fatal(err)
}
var spec map[string]any
err = yaml.Unmarshal([]byte(apiDoc), &spec)
if err != nil {
log.Fatal(err)
}
delete(spec, "servers")
spec["servers"] = []map[string]interface{}{
{"url": string(serverURL)},
}
return c.Render("doc", fiber.Map{
"AppHost": fmt.Sprintf("%s://%s", c.Protocol(), c.Hostname()),
"Spec": toJSON(spec),
"BasicAuthToken": c.UserContext().Value("token"),
})
} else {
return c.Render("index", fiber.Map{
"AppHost": fmt.Sprintf("%s://%s", c.Protocol(), c.Hostname()),
"AppVersion": config.AppVersion,
"BasicAuthToken": c.UserContext().Value("token"),
"MaxFileSize": humanize.Bytes(uint64(config.WhatsappSettingMaxFileSize)),
"MaxVideoSize": humanize.Bytes(uint64(config.WhatsappSettingMaxVideoSize)),
})
}
})
websocket.RegisterRoutes(app, appService)
@ -128,6 +153,15 @@ func runRest(_ *cobra.Command, _ []string) {
}
}
func toJSON(data interface{}) string {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
data_json, err := json.MarshalToString(data)
if err != nil {
log.Fatal(err)
}
return data_json
}
// Execute adds all child commands to the root command and sets flags appropriately.
func Execute() {
if err := rootCmd.Execute(); err != nil {

4
src/go.mod

@ -19,8 +19,10 @@ require (
github.com/stretchr/testify v1.8.4
github.com/valyala/fasthttp v1.48.0
go.mau.fi/libsignal v0.1.0
go.mau.fi/whatsmeow v0.0.0-20230718190209-efef6f1cec8e
go.mau.fi/whatsmeow v0.0.0-20230831081037-69534bf768bc
google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v2 v2.4.0
github.com/json-iterator/go v1.1.12
)
require (

58
src/views/doc.html

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui.css" >
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui-bundle.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui-standalone-preset.js"> </script>
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>
<script>
const http = axios.create({
baseURL: {{ .AppHost }}
});
{{ if isEnableBasicAuth .BasicAuthToken }}
http.defaults.headers.common['Authorization'] = {{ .BasicAuthToken }};
{{ end }}
window.onload = function() {
var spec = {{ .Spec }};
// Build a system
const ui = SwaggerUIBundle({
spec: JSON.parse(spec),
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
]
})
window.ui = ui
}
</script>
</body>
</html>
Loading…
Cancel
Save