-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This reverts commit e7509a3.
- Loading branch information
Showing
10 changed files
with
801 additions
and
423 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,89 @@ | ||
# Weavy Chat GO Lang SDK | ||
# Go FastOTP | ||
|
||
This library provides a Go client for interacting with the Weavy Chat API. It allows you to create applications, manage users, issue access tokens, and perform various operations within the Weavy Chat ecosystem. | ||
FastOTP is a Go library for interacting with the FastOTP API to generate one-time passwords (OTPs) easily. | ||
|
||
## Installation | ||
|
||
To install the library, use `go get`: | ||
|
||
```bash | ||
go get github.com/CeoFred/weavychat | ||
go get -u github.com/CeoFred/[email protected] | ||
``` | ||
|
||
## Usage | ||
|
||
```go | ||
import "github.com/CeoFred/weavychat" | ||
``` | ||
|
||
## Documentation | ||
This library currently supports the following Weavy Chat API methods: | ||
|
||
`NewWeavyServer`: Creates a new WeavyServer instance. | ||
`NewApp`: Creates a new app. | ||
`GetApp`: Retrieves an existing app. | ||
`NewUser`: Creates a new user. | ||
`AddUserToApp`: Adds users to an app. | ||
`RemoveUserFromApp`: Removes users from an app. | ||
`AppInit`: Initializes an app. | ||
`GetAccessToken`: Issues an access token for a user. | ||
|
||
## Authentication | ||
|
||
You need to provide the server URL and API key to authenticate with the Weavy Chat API. | ||
### Basic Example | ||
|
||
```go | ||
weavyServer := weavychat.NewWeavyServer("your-weavy-server-url", "your-api-key") | ||
``` | ||
|
||
## Creating Applications | ||
|
||
You can create applications using the `NewApp` method: | ||
|
||
```go | ||
appRequest := &weavychat.AppRequest{ | ||
ID: 1, | ||
Type: weavychat.AppType("your-app-type"), | ||
UID: "your-uid", | ||
DisplayName: "Your App", | ||
Metadata: weavychat.Metadata{}, | ||
Tags: []string{"tag1", "tag2"}, | ||
} | ||
|
||
app, err := weavyServer.NewApp(context.Background(), appRequest) | ||
if err != nil { | ||
// Handle error | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/CeoFred/fast-otp" | ||
) | ||
|
||
func main() { | ||
// Replace "your_api_key" with your actual FastOTP API key | ||
apiKey := "your_api_key" | ||
|
||
// Create an instance of FastOtp | ||
client := fastotp.NewFastOTP(apiKey) | ||
|
||
// Create context for library functions | ||
ctx := context.Background() | ||
|
||
// Define OTP generation payload | ||
payload := fastotp.GenerateOTPPayload{ | ||
Delivery: OtpDelivery{ | ||
"email": "[email protected]", | ||
}, | ||
Identifier: "user123", | ||
TokenLength: 6, | ||
Type: "numeric", | ||
Validity: 120, | ||
} | ||
|
||
// Generate OTP | ||
otp, err := client.GenerateOTP(ctx, payload) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Printf("Generated OTP: %s\n", otp) | ||
|
||
// Validate OTP | ||
otp, err = client.ValidateOTP( | ||
ctx, | ||
ValidateOTPPayload{ | ||
Identifier: "user123", | ||
Token: "123456", | ||
} | ||
) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
fmt.Printf("Otp validation status: %s\n", otp.Status) | ||
} | ||
``` | ||
|
||
## Managing Users | ||
## API Documentation | ||
|
||
You can create new users using the `NewUser` method: | ||
For detailed information about the FastOTP API and available endpoints, refer to the [official API documentation](https://api.fastotp.co/docs). | ||
|
||
```go | ||
user := &weavychat.User{ | ||
UID: "user-uid", | ||
Email: "[email protected]", | ||
GivenName: "John", | ||
MiddleName: "Doe", | ||
Name: "John Doe", | ||
FamilyName: "Doe", | ||
Nickname: "JD", | ||
PhoneNumber: "+1234567890", | ||
Comment: "A new user", | ||
Picture: "user-avatar-url", | ||
Directory: "directory-id", | ||
Metadata: weavychat.Metadata{}, | ||
Tags: []string{"tag1", "tag2"}, | ||
IsSuspended: false, | ||
} | ||
|
||
newUser, err := weavyServer.NewUser(context.Background(), user) | ||
if err != nil { | ||
// Handle error | ||
} | ||
``` | ||
|
||
## Access Tokens | ||
## Configuration | ||
|
||
You can issue access tokens for users: | ||
|
||
```go | ||
accessToken, err := weavyServer.GetAccessToken(context.Background(), "user-uid", 3600) | ||
if err != nil { | ||
// Handle error | ||
} | ||
``` | ||
- `APIKey`: Your FastOTP API key. | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! If you find any issues or have suggestions for improvement, please create an issue or a pull request on GitHub. | ||
If you'd like to contribute to this project, please follow the guidelines in [CONTRIBUTING.md](CONTRIBUTING.md). | ||
|
||
## License | ||
|
||
This library is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. | ||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. | ||
|
||
## Acknowledgments | ||
|
||
- Thanks to the FastOTP team for providing the awesome OTP generation service. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package fastotp | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"time" | ||
|
||
httpclient "github.com/CeoFred/fast-otp/lib" | ||
) | ||
|
||
const ( | ||
baseURL = "https://api.fastotp.co" | ||
) | ||
|
||
// FastOTP is the main struct for the FastOtp package. | ||
type FastOTP struct { | ||
apiKey string | ||
baseURL string | ||
client HttpClient | ||
} | ||
|
||
// ErrorResponse is the error struct for the FastOtp package. | ||
type ErrorResponse struct { | ||
Errors map[string][]string `json:"errors"` | ||
Message string `json:"message"` | ||
} | ||
|
||
// OTP is the struct for the OTP object. | ||
type OTP struct { | ||
CreatedAt time.Time `json:"created_at"` | ||
ExpiresAt time.Time `json:"expires_at"` | ||
UpdatedAt time.Time `json:"updated_at"` | ||
DeliveryDetails DeliveryDetails `json:"delivery_details"` | ||
ID string `json:"id"` | ||
Identifier string `json:"identifier"` | ||
Status OTPStatus `json:"status"` | ||
Type OTPType `json:"type"` | ||
DeliveryMethods []string `json:"delivery_methods"` | ||
} | ||
|
||
// OTPResponse is the struct for the OTP response object. | ||
type OTPResponse struct { | ||
OTP OTP `json:"otp"` | ||
} | ||
|
||
// DeliveryDetails is the struct for the DeliveryDetails object. | ||
type DeliveryDetails struct { | ||
Email string `json:"email"` | ||
} | ||
|
||
// OTPDelivery is the struct for the OtpDelivery object. | ||
type OTPDelivery map[string]string | ||
|
||
// GenerateOTPPayload is the struct for the GenerateOTPPayload object. | ||
type GenerateOTPPayload struct { | ||
Delivery OTPDelivery `json:"delivery"` | ||
Identifier string `json:"identifier"` | ||
Type OTPType `json:"type"` | ||
TokenLength int `json:"token_length"` | ||
Validity int `json:"validity"` | ||
} | ||
|
||
// ValidateOTPPayload is the struct for the ValidateOTPPayload object. | ||
type ValidateOTPPayload struct { | ||
Identifier string `json:"identifier"` | ||
Token string `json:"token"` | ||
} | ||
|
||
// NewFastOTP creates a new FastOtp instance. | ||
func NewFastOTP(apiKey string) *FastOTP { | ||
return &FastOTP{ | ||
apiKey: apiKey, | ||
baseURL: baseURL, | ||
client: httpclient.NewAPIClient(baseURL, apiKey), | ||
} | ||
} | ||
|
||
func (f *FastOTP) GenerateOTP(ctx context.Context, payload GenerateOTPPayload) (*OTP, error) { | ||
resp, err := f.client.Post(ctx, "/generate", payload) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
var errorResponse ErrorResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&errorResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(errorResponse.Errors) > 0 { | ||
return nil, formatValidationError(errorResponse.Errors) | ||
} | ||
|
||
return nil, fmt.Errorf("API error: %s", errorResponse.Message) | ||
} | ||
|
||
var otpResponse OTPResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&otpResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &otpResponse.OTP, nil | ||
} | ||
|
||
func (f *FastOTP) ValidateOTP(ctx context.Context, payload ValidateOTPPayload) (*OTP, error) { | ||
resp, err := f.client.Post(ctx, "/validate", payload) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
var errorResponse ErrorResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&errorResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(errorResponse.Errors) > 0 { | ||
return nil, formatValidationError(errorResponse.Errors) | ||
} | ||
|
||
return nil, fmt.Errorf("API error: %s", errorResponse.Message) | ||
} | ||
|
||
var otpResponse OTPResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&otpResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &otpResponse.OTP, nil | ||
} | ||
|
||
// GetOtp gets a new otp | ||
func (f *FastOTP) GetOtp(ctx context.Context, id string) (*OTP, error) { | ||
resp, err := f.client.Get(ctx, id) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
var errorResponse ErrorResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&errorResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(errorResponse.Errors) > 0 { | ||
return nil, formatValidationError(errorResponse.Errors) | ||
} | ||
|
||
return nil, fmt.Errorf("API error: %s", errorResponse.Message) | ||
} | ||
|
||
var otpResponse OTPResponse | ||
if err := json.NewDecoder(resp.Body).Decode(&otpResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &otpResponse.OTP, nil | ||
} | ||
|
||
func formatValidationError(errors map[string][]string) error { | ||
var errorMessage string | ||
for field, fieldErrors := range errors { | ||
for _, err := range fieldErrors { | ||
errorMessage += fmt.Sprintf("%s: %s\n", field, err) | ||
} | ||
} | ||
return fmt.Errorf("validation errors:\n%s", errorMessage) | ||
} |
Oops, something went wrong.