Skip to content

Commit ddeb33e

Browse files
committed
[commands] add logs command
1 parent ad57409 commit ddeb33e

12 files changed

Lines changed: 277 additions & 7 deletions

File tree

‎README.md‎

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
<br />
1111

1212
<div align="center">
13-
<h3 align="center">SMS Gateway for Android™ CLI</h3>
13+
<h3 align="center">SMSGate CLI</h3>
1414

1515
<p align="center">
16-
A command-line interface for interacting with the SMS Gateway for Android API
16+
A command-line interface for interacting with the SMSGate API
1717
<br />
1818
<a href="https://docs.sms-gate.app/integration/cli/"><strong>Explore the docs »</strong></a>
1919
<br />
@@ -40,6 +40,9 @@
4040
- [Commands](#commands)
4141
- [Exit codes](#exit-codes)
4242
- [Examples](#examples)
43+
- [Sending messages](#sending-messages)
44+
- [Getting message status](#getting-message-status)
45+
- [Getting logs](#getting-logs)
4346
- [Output formats](#output-formats-1)
4447
- [👥 Contributing](#-contributing)
4548
- [©️ License](#️-license)
@@ -130,10 +133,11 @@ smsgate [global options] command [command options] [arguments...]
130133

131134
### Commands
132135

133-
The CLI offers two main groups of commands:
136+
The CLI offers three main groups of commands:
134137

135138
- **Messages**: Commands for sending messages and checking their status.
136139
- **Webhooks**: Commands for managing webhooks, including creating, updating, and deleting them.
140+
- **Logs**: Commands for retrieving logs for a specific time range.
137141

138142
For a complete list of available commands, you can:
139143
- Run `smsgate help` or `smsgate --help` in your terminal.
@@ -152,6 +156,14 @@ The CLI uses exit codes to indicate the outcome of operations:
152156

153157
For security reasons, it is recommended to pass credentials using environment variables or a `.env` file.
154158

159+
Credentials can also be passed via CLI options:
160+
161+
```bash
162+
smsgate -u <username> -p <password> send --phones '+12025550123' 'Hello, Dr. Turk!'
163+
```
164+
165+
#### Sending messages
166+
155167
```bash
156168
# Send a message
157169
smsgate send --phones '+12025550123' 'Hello, Dr. Turk!'
@@ -160,15 +172,28 @@ smsgate send --phones '+12025550123' 'Hello, Dr. Turk!'
160172
smsgate send --phones '+12025550123' --phones '+12025550124' 'Hello, doctors!'
161173
# or
162174
smsgate send --phones '+12025550123,+12025550124' 'Hello, doctors!'
175+
```
163176

177+
#### Getting message status
178+
179+
```bash
164180
# Get the status of a sent message
165181
smsgate status zXDYfTmTVf3iMd16zzdBj
166182
```
167183

168-
Credentials can also be passed via CLI options:
184+
#### Getting logs
185+
186+
The `logs` command retrieves logs for a specific time range. Dates should be in RFC3339 format (e.g., `2024-01-15T10:30:00Z`).
169187

170188
```bash
171-
smsgate -u <username> -p <password> send --phones '+12025550123' 'Hello, Dr. Turk!'
189+
# Get logs for the last 24 hours (default)
190+
smsgate logs
191+
192+
# Get logs for a specific time range
193+
smsgate logs --from '2024-01-15T00:00:00Z' --to '2024-01-15T23:59:59Z'
194+
195+
# Get logs with custom time range and output format
196+
smsgate --format json logs --from '2024-01-15T10:00:00+07:00' --to '2024-01-15T18:00:00+07:00'
172197
```
173198

174199
#### Output formats

‎cmd/smsgate/smsgate.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66

7+
"github.com/android-sms-gateway/cli/internal/commands/logs"
78
"github.com/android-sms-gateway/cli/internal/commands/messages"
89
"github.com/android-sms-gateway/cli/internal/commands/webhooks"
910
"github.com/android-sms-gateway/cli/internal/config"
@@ -25,9 +26,10 @@ func main() {
2526
os.Exit(codes.ParamsError)
2627
}
2728

28-
cmds := make([]*cli.Command, 0, len(messages.Commands())+len(webhooks.Commands()))
29+
cmds := make([]*cli.Command, 0, len(messages.Commands())+len(webhooks.Commands())+len(logs.Commands()))
2930
cmds = append(cmds, messages.Commands()...)
3031
cmds = append(cmds, webhooks.Commands()...)
32+
cmds = append(cmds, logs.Commands()...)
3133

3234
app := &cli.App{
3335
Name: "smsgate",

‎dev-docs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../dev-docs

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/android-sms-gateway/cli
33
go 1.23.2
44

55
require (
6-
github.com/android-sms-gateway/client-go v1.9.2
6+
github.com/android-sms-gateway/client-go v1.12.0
77
github.com/joho/godotenv v1.5.1
88
github.com/samber/lo v1.52.0
99
github.com/urfave/cli/v2 v2.27.5

‎go.sum‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
github.com/android-sms-gateway/client-go v1.9.2 h1:e9HFgvR+LRMV0dOJvFkxt998UxOMWNf8hfnXwMIc39I=
22
github.com/android-sms-gateway/client-go v1.9.2/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
3+
github.com/android-sms-gateway/client-go v1.11.1-0.20260315032244-641ce286d8b5 h1:04bQhao7QKaD5QwsHI8PDpd32ZAYO7Cw1/5bRMbfuNM=
4+
github.com/android-sms-gateway/client-go v1.11.1-0.20260315032244-641ce286d8b5/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
5+
github.com/android-sms-gateway/client-go v1.12.0 h1:4YWnzLi4AWEQIXvvUSLiTK+ZAgQD6SV+xfvlTCjZ8pI=
6+
github.com/android-sms-gateway/client-go v1.12.0/go.mod h1:DQsReciU1xcaVW3T5Z2bqslNdsAwCFCtghawmA6g6L4=
37
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
48
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
59
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=

‎internal/commands/logs/logs.go‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package logs
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/android-sms-gateway/cli/internal/core/codes"
8+
"github.com/android-sms-gateway/cli/internal/flags"
9+
"github.com/android-sms-gateway/cli/internal/utils/metadata"
10+
"github.com/urfave/cli/v2"
11+
)
12+
13+
func Commands() []*cli.Command {
14+
return []*cli.Command{logsCmd()}
15+
}
16+
17+
func logsCmd() *cli.Command {
18+
f := flags.Period()
19+
20+
return &cli.Command{
21+
Name: "logs",
22+
Aliases: []string{"log"},
23+
Usage: "Get logs for a specific time range",
24+
Category: "Logs",
25+
Flags: f,
26+
Before: logsBefore,
27+
Action: logsAction,
28+
}
29+
}
30+
31+
func logsBefore(c *cli.Context) error {
32+
period := flags.ParsePeriodFlags(c)
33+
34+
if period.From == nil || period.To == nil {
35+
return cli.Exit("From and To dates are required", codes.ParamsError)
36+
}
37+
38+
if period.From.After(*period.To) {
39+
return cli.Exit("From date must be less than or equal to To date", codes.ParamsError)
40+
}
41+
42+
return nil
43+
}
44+
45+
func logsAction(c *cli.Context) error {
46+
period := flags.ParsePeriodFlags(c)
47+
48+
from := period.From
49+
to := period.To
50+
51+
client := metadata.GetClient(c.App.Metadata)
52+
renderer := metadata.GetRenderer(c.App.Metadata)
53+
54+
res, err := client.GetLogs(c.Context, *from, *to)
55+
if err != nil {
56+
return cli.Exit(err.Error(), codes.ClientError)
57+
}
58+
59+
output, err := renderer.Logs(res)
60+
if err != nil {
61+
return cli.Exit(err.Error(), codes.OutputError)
62+
}
63+
fmt.Fprintln(os.Stdout, output)
64+
65+
return nil
66+
}

‎internal/core/client/client.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ func New(username, password, endpoint string) *smsgateway.Client {
88
BaseURL: endpoint,
99
User: username,
1010
Password: password,
11+
Token: "",
1112
})
1213
}

‎internal/core/output/json.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ func (o *JSONOutput) MessageState(src smsgateway.MessageState) (string, error) {
2727
return o.marshaler(src)
2828
}
2929

30+
func (o *JSONOutput) Logs(src []smsgateway.LogEntry) (string, error) {
31+
return o.marshaler(src)
32+
}
33+
3034
func (o *JSONOutput) Webhook(src smsgateway.Webhook) (string, error) {
3135
return o.marshaler(src)
3236
}

‎internal/core/output/output.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const (
1616

1717
type Renderer interface {
1818
MessageState(src smsgateway.MessageState) (string, error)
19+
Logs(src []smsgateway.LogEntry) (string, error)
1920
Webhook(src smsgateway.Webhook) (string, error)
2021
Webhooks(src []smsgateway.Webhook) (string, error)
2122
Success() (string, error)

‎internal/core/output/text.go‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package output
22

33
import (
4+
"fmt"
5+
"strconv"
46
"strings"
57
"time"
68

@@ -69,6 +71,42 @@ func (*TextOutput) MessageState(src smsgateway.MessageState) (string, error) {
6971
return builder.String(), nil
7072
}
7173

74+
func (*TextOutput) Logs(src []smsgateway.LogEntry) (string, error) {
75+
if len(src) == 0 {
76+
return "Empty result", nil
77+
}
78+
79+
builder := strings.Builder{}
80+
for i, entry := range src {
81+
builder.WriteString("ID: ")
82+
builder.WriteString(strconv.FormatUint(entry.ID, 10))
83+
builder.WriteString("\nPriority: ")
84+
builder.WriteString(string(entry.Priority))
85+
builder.WriteString("\nModule: ")
86+
builder.WriteString(entry.Module)
87+
builder.WriteString("\nMessage: ")
88+
builder.WriteString(entry.Message)
89+
builder.WriteString("\nCreated At: ")
90+
builder.WriteString(entry.CreatedAt.Local().Format(time.RFC3339))
91+
92+
if len(entry.Context) > 0 {
93+
builder.WriteString("\nContext:")
94+
for k, v := range entry.Context {
95+
builder.WriteString("\n\t")
96+
builder.WriteString(k)
97+
builder.WriteString(": ")
98+
fmt.Fprintf(&builder, "%v", v)
99+
}
100+
}
101+
102+
if i < len(src)-1 {
103+
builder.WriteString("\n---\n")
104+
}
105+
}
106+
107+
return builder.String(), nil
108+
}
109+
72110
// Webhook formats a single smsgateway.Webhook into a string representation.
73111
// The output includes the ID, Event, and URL of the webhook.
74112
func (*TextOutput) Webhook(src smsgateway.Webhook) (string, error) {

0 commit comments

Comments
 (0)