Rupert  Beatty

Rupert Beatty

1676638210

Stream-chat-swift: iOS Chat SDK in Swift

Stream-chat-swift

iOS Chat SDK in Swift - Build your own app chat experience for iOS using the official Stream Chat API

This is the official iOS SDK for Stream Chat, a service for building chat and messaging applications. This library includes both a low-level SDK and a set of reusable UI components.

Low Level Client (LLC)

The StreamChat SDK is a low level client for Stream chat service that doesn't contain any UI components. It is meant to be used when you want to build a fully custom UI. For the majority of use cases though, we recommend using our highly customizable UI SDK's.

UIKit SDK

The StreamChatUI SDK is our UI SDK for UIKit components. If your application needs to support iOS 13 and below, this is the right UI SDK for you.

SwiftUI SDK

The StreamChatSwiftUI SDK is our UI SDK for SwiftUI components. If your application only needs to support iOS 14 and above, this is the right UI SDK for you. This SDK is available in another repository stream-chat-swiftui.

iOS 16 and Xcode 14 support

Since the 4.20.0 release, our SDKs can be built using Xcode 14. Currently, there are no known issues on iOS 16. If you spot one, please create a ticket.


Main Features

  • Offline support: Browse channels and send messages while offline.
  • Familiar behavior: The UI elements are good platform citizens and behave like native elements; they respect tintColor, layoutMargins, light/dark mode, dynamic font sizes, etc.
  • Swift native API: Uses Swift's powerful language features to make the SDK usage easy and type-safe.
  • Uses UIKit patterns and paradigms: The API follows the design of native system SDKs. It makes integration with your existing code easy and familiar.
  • SwiftUI support: We have developed a brand new SDK to help you have smoother Stream Chat integration in your SwiftUI apps.
  • First-class support for Combine: The StreamChat SDK (Low Level Client) has Combine wrappers to make it really easy use in an app that uses Combine.
  • Fully open-source implementation: You have access to the complete source code of the SDK here on GitHub.
  • Supports iOS 11+: We proudly support older versions of iOS, so your app can stay available to almost everyone.

Quick Links

  • iOS/Swift Chat Tutorial: Learn how to use the SDK by following our simple tutorial with UIKit (or SwiftUI).
  • Register: Register to get an API key for Stream Chat.
  • Installation: Learn more about how to install the SDK using CocoaPods, SPM or Carthage.
  • Documentation: An extensive documentation is available to help with you integration.
  • SwiftUI: Check our SwiftUI SDK if you are developing with SwiftUI.
  • Demo app: This repo includes a fully functional demo app with example usage of the SDK.
  • Example apps: This section of the repo includes fully functional sample apps that you can use as reference.

Free for Makers

Stream is free for most side and hobby projects. You can use Stream Chat for free if you have less than five team members and no more than $10,000 in monthly revenue.

Main Principles

Progressive disclosure: The SDK can be used easily with very minimal knowledge of it. As you become more familiar with it, you can dig deeper and start customizing it on all levels.

Highly customizable: Every element is designed to be easily customizable. You can modify the brand color by setting tintColor, apply appearance changes using custom UI rules, or subclass existing elements and inject them everywhere in the system, no matter how deep is the logic hierarchy.

open by default: Everything is open unless there's a strong reason for it to not be. This means you can easily modify almost every behavior of the SDK such that it fits your needs.

Good platform citizen: The UI elements behave like good platform citizens. They use existing iOS patterns; their behavior is predictable and matches system UI components; they respect tintColor, layourMargins, dynamic font sizes, and other system-defined UI constants.

Dependencies

This SDK tries to keep the list of external dependencies to a minimum. Starting 4.6.0, and in order to improve the developer experience, dependencies are hidden inside our libraries. (Does not apply to StreamChatSwiftUI's dependencies yet).

Learn more about our dependencies here

Using Objective-C

You can still integrate our SDKs if your project is using Objective-C. In that case, any customizations would need to be done by subclassing our components in Swift, and then use those directly from the Objective-C code.


We are hiring

We've recently closed a $38 million Series B funding round and we keep actively growing. Our APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world. Check out our current openings and apply via Stream's website.


Quick Overview

Channel List

FeaturesPreview
A list of channels matching provided query
Channel name and image based on the channel members or custom data
Unread messages indicator
Preview of the last message
Online indicator for avatars
Create new channel and start right away
 

Message List

FeaturesPreview
A list of message in a channel
Photo preview
Message reactions
Message grouping based on the send time
Link preview
Inline replies
Message threads
GIPHY support
 

Message Composer

FeaturesPreview
Support for multiline text, expands and shrinks as needed
Image and file attachments
Replies to messages
Tagging of users
Chat commands like mute, ban, giphy
 

Chat Commands

FeaturesPreview
Easily search commands by writing / symbol or tap bolt icon
GIPHY support out of box
Supports mute, unmute, ban, unban commands
WIP support of custom commands
 

User Tagging Suggestion

FeaturesPreview
User mentions preview
Easily search for concrete user
Mention as many users as you want
 

Download Details:

Author: GetStream
Source Code: https://github.com/GetStream/stream-chat-swift 
License: View license

#swift #chat #ios #sdk #messaging 

Stream-chat-swift: iOS Chat SDK in Swift
Bongani  Ngema

Bongani Ngema

1676366220

Chat SDK iOS: Open Source Mobile Messenger

Chat SDK

Open Source Messaging framework for iOS

Chat SDK is a fully featured open source instant messaging framework for iOS. Chat SDK is fully featured, scalable and flexible and follows the following key principles:

  • Open Source. The Chat SDK is open source and free for commerical apps (see license)
  • Full data control. You have full and exclusive access to the user's chat data
  • Quick integration. Chat SDK is fully featured out of the box
  • Firebase Powered by Google Firebase

Features

Full breakdown is available on the features page.

Quick Start

Modules

About Us

Learn about the history of Chat SDK and our future plans in this post.

Scalability and Cost

People always ask about how much Chat SDK costs to run. And will it scale to millions of users? So I wrote an article talking about just that.

Looking for Freelance Developers

If you're a freelance developer looking for work, join our Discord server. We often have customers

Community

  • Discord: If you need support, join our Server
  • Support the project: Patreon or Github Sponsors 🙏 and get access to premium modules
  • Upvote: our advert on StackOverflow
  • Contribute by writing code: Email the Contributing Document to team@sdk.chat
  • Give us a star on Github ⭐
  • Upvoting us: Product Hunt
  • Tweet: about your Chat SDK project using @chat_sdk
  • Live Stream Join us every Saturday 18:00 CEST for a live stream where I answer questions about Chat SDK. For more details please join the Discord Server

You can also help us by:

  • Providing feedback and feature requests
  • Reporting bugs
  • Fixing bugs
  • Writing documentation

Email us at: team@sdk.chat

We also offer development services we are a team of full stack developers who are Firebase experts. For more information check out our consulting site.

Running the demo project

This repository contains a fully functional version of the Chat SDK which is configured using our Firebase account. This is great way to test the features of the Chat SDK before you start itegrating it with your app.

  1. Clone Chat SDK
  2. Run pod install in the Xcode directory
  3. Open the Chat SDK Firebase.xcworkspace file in Xcode
  4. Compile and run

Swift Version

We are currently updating the Chat SDK to use Swift, this will happen gradually. In the meantime, the Chat SDK API is fully compatible with Swift projects.

The Chat SDK is fully compatible with Swift projects and contains a Swift demo project.

  1. Clone Chat SDK
  2. Run pod install in the XcodeSwift directory
  3. Open the ChatSDKSwift.xcworkspace file in Xcode
  4. Compile and run

Adding the Chat SDK to your project

Quick start guide - it takes about 10 minutes!

Adding the Chat SDK to your project

  1. Add the Chat SDK development pods to your Podfile
use_frameworks!
pod "ChatSDK"
pod "ChatSDKFirebase/Adapter"
pod "ChatSDKFirebase/Upload"
pod "ChatSDKFirebase/Push"

Optional

pod "ChatSDK/ModAddContactWithQRCode"

Run pod update to get the latest version of the code.

Open the App Delegate add the following code to initialise the chat

Swift

AppDelegate.swift

import ChatSDK

Add the following code to the start of your didFinishLaunchingWithOptions function:

let config = BConfiguration.init();
config.rootPath = "test"
// Configure other options here...
config.allowUsersToCreatePublicChats = true

// Define the modules you want to use. 
var modules = [
    FirebaseNetworkAdapterModule.shared(),
    FirebasePushModule.shared(),
    FirebaseUploadModule.shared(),
    // Optional...
    AddContactWithQRCodeModule.init(),
]

BChatSDK.initialize(config, app: application, options: launchOptions, modules: modules)

    
self.window = UIWindow.init(frame: UIScreen.main.bounds)
self.window?.rootViewController = BChatSDK.ui().splashScreenNavigationController()
self.window?.makeKeyAndVisible();

Then add the following methods:

  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      BChatSDK.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
  }

  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
      BChatSDK.application(application, didReceiveRemoteNotification: userInfo)
  }

  func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
      return BChatSDK.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
  }

  func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
      return BChatSDK.application(app, open: url, options: options)
  }

Objective C

Check the demo project.

The Root Path

The root path variable allows you to run multiple Chat SDK instances on one Firebase account. Each different root path will represent a completely separate set of Firebase data. This can be useful for testing because you could have separate test and prod root paths.

  1. The Chat SDK is now added to your project

Firebase Setup

  1. Go to the Firebase website and sign up
  2. Go to the Firebase console and make a new project
  3. Click Add project
  4. Choose a name and a location
  5. Click Settings (the gear icon). On the General tab, click Add Firebase to your iOS app
  6. Enter your bundle ID
  7. Download the GoogleServices file and add it to the root of your Xcode project

Note:
It is worth opening your downloaded GoogleService-Info.plist and checking there is an API_KEY field included. Sometimes Firebase's automatic download doesn’t include this in the plist. To rectify, just re-download the plist from the project settings menu.

Copy the following rows from the demo ChatSDK Info.plist file to your project's Info.plist

App Transport Security Settings

URL types

Make sure that the URL types are all set correctly. The URL type for your app should be set to your bundle id

All the privacy rows. These will allow the app to access the camera, location and address book

In the Firebase dashboard click Authentication -> Sign-in method and enable all the appropriate methods

Add the security rules. The rules also enable optimized user search so this step is very important!

Enable file storage - Click Storage -> Get Started

Enable push notifications

Enable location messages. Get a Google Maps API key. Then add it during the Chat SDK configuration

Objective C

config.googleMapsApiKey = @"YOUR API KEY";

Swift

config.googleMapsApiKey = "YOUR API KEY"

Push Notifications

The Push Notification module allows you to send free push notifications using Firebase Cloud Messaging.

  1. Setup an APN key.
  2. Inside your project in the Firebase console, select the gear icon, select Project Settings, and then select the Cloud Messaging tab.
  3. In APNs authentication key under iOS app configuration, click the Upload button.
  4. Browse to the location where you saved your key, select it, and click Open. Add the key ID for the key (available in Certificates, Identifiers & Profiles in the Apple Developer Member Center) and click Upload.
  5. Enable the push notifications Capability in your Xcode project Project -> Capabilities -> Push Notifications
  6. In Xcode open the Capabilities tab. Enable Push Notifications and the following Background Modes: Location updates, Background fetch, Remote notifications.

Setup Firebase Cloud Functions

Follow the instructions on our Chat SDK Firebase repository

Security Rules

Firebase secures your data by allowing you to write rules to govern who can access the database and what can be written. The rules are also needed to enable user search. To enable the rules see the guide Enabling Security Rules.

Conclusion

Congratulations! 🎉🎉 You've just turned your app into a fully featured instant messenger! Keep reading below to learn how to further customize the Chat SDK.

To go deeper, checkout the API Guide for help with:

  1. Interacting with the Firebase server
  2. Creating and updating entities
  3. Custom authentication
  4. Common code examples
  5. Customizing the user interface

View the API documentation here.

Next Steps

Documentation

Configuration

There are a number of configuration options available. Check out the BConfiguration class. Using this class you can do things like:

  • Changing the chat bubble colors
  • Changing the default user name
  • Enable or disable different types of login
  • Show or hide empty chats
  • etc...

Customize the UI

To customize the UI, you can register subclasses for different views. You can do that using the UI service BChatSDK.ui. For example, to register a new login view controller you would use:

BChatSDK.ui.loginViewController = [[YourViewController alloc] initWithNibName:Nil bundle: Nil];

To modify the chat view you would register a provider:

[BChatSDK.ui setChatViewController:^BChatViewController *(id<PThread> thread) {
        return [[YourChatViewController alloc] initWithThread:thread];
}];

Every view controller in the app can be customized this way.

Use Chat SDK views in your app

Any of the Chat SDK views can be added into your app. Checkout the PInterfaceFacade for options. You can add a any view using the following pattern. Here we are using the interface service to get the particular view.

Objective-C

UIViewController * privateThreadsViewController = [BChatSDK.ui privateThreadsViewController];

Swift

let privateThreadsViewController = BChatSDK.ui().a.privateThreadsViewController()

Integrate the Chat SDK with your existing app

To do that, you can take advantage of the BIntegrationHelper class. This makes provides some helper methods to make it easier to integrate the Chat SDK with your app.

At the most basic level, you need to do the following:

  • Authenticate the Chat SDK when your app authenticates. The best way to do this is to generate a custom token on your server following this guide. Then use this method to initialize the Chat SDK:

Objective-C

[BIntegrationHelper authenticateWithToken:@"your token"];

Swift

BIntegrationHelper.authenticate(withToken: "your token")
  • Update the Chat SDK user's name and image whenever your user's name or image changes. You can do this using the following method:

Objective-C

[BIntegrationHelper updateUserWithName:@"Name" image: image url: imageURL];

Swift

BIntegrationHelper.updateUser(withName: "Name", image: image, url: imageURL)
  • Logout of the Chat SDK whenever your app logs out. A good place to do this is whenever your login screen is displayed:

Objective-C

[BIntegrationHelper logout];

Swift

BIntegrationHelper.logout()
  • Now the Chat SDK is integrated with your app.

Module Setup

There are a number of free and premium extensions that can be added to the Chat SDK.

Firebase Modules

For the following modules:

The free modules are located in the chat-sdk-ios/ChatSDKFirebase folder. The premium modules can be purchased and downloaded from the links provided above.

To install a module you should use the following steps:

  1. Copy the module code into your Xcode source code folder and add the files to your project from inside Xcode. If you are using a symlink you can use the symlink script (mentioned above) and then just add a link to the ChatSDKFirebase folder to Xcode.
  2. Add any necessary dependencies to your Podfile
  3. Add the modules to the array of modules during configuration.

Firebase UI

The File UI module allows you to use the native Firebase user interface for authentication.

After adding the files to your Xcode project, add the following to the App Delegate to enable the module.

Objective C

AppDelegate.m -> application: didFinishLaunchingWithOptions:

 #import "BFirebaseUIModule.h"

[[[BFirebaseUIModule alloc] init] activateWithProviders: @[]];

Swift

[YourProject]-Bridging-Header.h

 #import "BFirebaseUIModule.h"

AppDelegate.swift

BFirebaseUIModule.init().activate(withProviders: []);

You should pass in array of the FUIAuthProvider objects you want to support.

Also add the following to your Podfile depending on which authentication methods you want to support:

pod 'FirebaseUI/Facebook', '~> 4.0'
pod 'FirebaseUI/Google', '~> 4.0'
pod 'FirebaseUI/Twitter', '~> 4.0'
pod 'FirebaseUI/Phone', '~> 4.0'

Then run pod install.

Note If you want to Firebase Auth UI make sure you comment out the following line:

BNetworkManager.shared().a.auth().setChallenge(BLoginViewController.init(nibName: nil, bundle: nil));

Other Modules

For the following modules:

These modules are distributed as development pods. After you've downloaded the module, unzip it and add it to the ChatSDKModules folder. Then:

  1. Open your Podfile
  2. Add the line:
pod "ChatSDKModules/[ModuleName]", :path => "[Path to ChatSDKModules folder]"
  1. Run pod install
  2. The module is now active

Using the Chat SDK API

The Chat SDK API is based around the network manager and a series of handlers. A good place to start is by looking at the handlers Pods/Development Pods/ChatSDK/Core/Core/Classes/Interfaces. Here you can review the handler interfaces which are well documented. To use a handler you would use the following code:

Objective C

[[BChatSDK.handler_name function: to: call:]

Swift

BNetworkManager.shared().a.handler_name() function: to: call:]

Searching for a user

For example, to search for a user you could use the search handler:

-(RXPromise *) usersForIndexes: (NSArray *) indexes withValue: (NSString *) value limit: (int) limit userAdded: (void(^)(id<PUser> user)) userAdded;

Here you pass in a series of indexes to be used in the search i.e. name, email etc... and a value. It will then return a series of user objects.

You can also see example implementations of these handlers by looking at the BFirebaseSearchHandler class. And also seeing how the method is used in the Chat SDK.

Starting a chat

To start a chat you can use the core handler.

-(RXPromise *) createThreadWithUsers: (NSArray *) users
                       threadCreated: (void(^)(NSError * error, id<PThread> thread)) thread;

When this method completes, the thread will have been created on Firebase and all the users will have been added. You could then open the thread using the interface adapter.

UIViewController * chatViewController = [BChatSDK.ui chatViewControllerWithThread:thread];

So a more complete example would look like this:

-(void) startChatWithUser {
    MBProgressHUD * hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.label.text = [NSBundle t:bCreatingThread];
    
    [[BChatSDK.core createThreadWithUsers:@[_user] threadCreated:^(NSError * error, id<PThread> thread) {
        if (!error) {
            [self pushChatViewControllerWithThread:thread];
        }
        else {
            [UIView alertWithTitle:[NSBundle t:bErrorTitle] withMessage:[NSBundle t:bThreadCreationError]];
        }
        [MBProgressHUD hideHUDForView:self.view animated:YES];
    }];
}

-(void) pushChatViewControllerWithThread: (id<PThread>) thread {
    if (thread) {
        UIViewController * chatViewController = [BChatSDK.ui chatViewControllerWithThread:thread];
        [self.navigationController pushViewController:chatViewController animated:YES];
    }
}

Troubleshooting Cocoapods

  1. Always open the .xcworkspace file rather than .xcodeproj
  2. Check CocoaPod warnings - make sure to fix any warnings before proceeding
  3. Make sure that your base configuration isn’t set: Project -> project name -> Info -> Configuration
  4. Make sure that the “Build Active Architecture Only” setting is the same for both the main project and the pods project.
  5. Check the build settings in the Xcode project and check which fields are in bold (this means that their value has been overridden and CocoaPods can't access them). If you press backspace while selecting those fields, their values will be set to the default value.

The license

We offer a choice of two license for this app. You can either use the Chat SDK license or the GPLv3 license.

Most Chat SDK users either want to add the Chat SDK to an app that will be released to the App Store or they want to use the Chat SDK in a project for their client. The Chat SDK license gives you complete flexibility to do this for free.

Chat SDK License Summary

  • License does not expire.
  • Can be used for creating unlimited applications
  • Can be distributed in binary or object form only
  • Commercial use allowed
  • Can modify source-code but cannot distribute modifications (derivative works)

If a user wants to distribute the Chat SDK source code, we feel that any additions or modifications they make to the code should be contributed back to the project. The GPLv3 license ensures that if source code is distributed, it must remain open source and available to the community.

GPLv3 License Summary

  • Can modify and distribute source code
  • Commerical use allowed
  • Cannot sublicense or hold liable
  • Must include original license
  • Must disclose source

What does this mean?

Please check out the Licensing FAQ for more information.

Download Details:

Author: Chat-sdk
Source Code: https://github.com/chat-sdk/chat-sdk-ios 
License: View license

#firebase #swift #ios #sdk #objective-c #messaging 

Chat SDK iOS: Open Source Mobile Messenger
Bongani  Ngema

Bongani Ngema

1676007960

Chat-sdk-android: Chat SDK Android - Open Source Mobile Messenger

Chat SDK for Android v5

Open Source Messaging framework for Android

Chat SDK is a fully featured open source instant messaging framework for Android. Chat SDK is fully featured, scalable and flexible and follows the following key principles:

  • Free. Chat SDK uses the Apache 2.0 license
  • Open Source. Chat SDK is open source
  • Full control of the data. You have full and exclusive access to the user's chat data
  • Quick integration. Chat SDK is fully featured out of the box
  • Scalable. Supports millons of daily users [1, 2]
  • Backend agnostic. Chat SDK can be customized to support any backend

Main Image

Technical details

Please bear in mind that this version is a major update. As a result we are making new releases every few days to fix bugs and crashes. If you see an issue, please report it on the Github bug tracker and we will fix it.

Features

  • Powered by Firebase Firestore, Realtime database or XMPP
  • Private and group messages ⇘GIF
  • Public chat rooms
  • Username / password, Facebook, Twitter, Anonymous and custom login
  • Phone number authentication
  • Push notifications (using FCM)
  • Text, Image ⇘GIF and Location ⇘GIF messages
  • Forward, Reply ⇘GIF, Copy and Delete ⇘GIF messages
  • Tabbar ⇘GIF or Drawer ⇘GIF layout
  • User Profiles ⇘GIF
  • User Search ⇘GIF
  • Contacts ⇘GIF
  • Add contact by QR code ⇘GIF
  • Firebase UI ⇘GIF
  • iOS Version
  • Web Version

Extras

Sponsor us on either Github sponsors or Paetron and get these features. For full details visit our Modules page.

When you support us on Patreon, you get: extra modules, code updates, support as well as special access to the Discord Server.

  • Typing indicator ⇘GIF
  • Read receipts
  • Last online indicator
  • Audio messages ⇘GIF
  • Video messages ⇘GIF
  • Sticker messages ⇘GIF
  • User blocking ⇘GIF
  • File Messages ⇘GIF
  • End-to-end encryption
  • Nearby Users
  • Contact book integration ⇘GIF
  • Location based chat ⇘GIF
  • XMPP Server Support
    • ejabberd
    • Prosody
    • OpenFire
    • Tigase
    • MongooseIM

Visit our Animated GIF Gallery to see all the features.

About Us

Learn about the history of Chat SDK and our future plans in this post.

Scalability and Cost

People always ask about how much Chat SDK costs to run. And will it scale to millions of users? So I wrote an article talking about just that.

Library Size

The Chat SDK library with ALL modules is around 20mb

Community

You can also help us by:

  • Providing feedback and feature requests
  • Reporting bugs
  • Fixing bugs
  • Writing documentation

Email us at: team@sdk.chat

We also offer development services we are a team of full stack developers who are Firebase experts. For more information check out our consulting site.

Firestream - A light-weight messaging library for Firebase

If you are looking for something that is more-light weight than Chat SDK, we also have a library which only provides instant messaging functionality.

  1. 1-to-1 Messaging
  2. Group chat, roles, moderation
  3. Android, iOS, Web and Node.js
  4. Fully customisable messages
  5. Typing Indicator
  6. Delivery receipts
  7. User blocking
  8. Presence
  9. Message history (optional)
  10. Firestore or Realtime database

You can check out the project: Firestream on Github.

Chat SDK Firebase Documentation

Quick Start

Video Tutorial

Bear in mind that the video is not updated frequently. Please cross reference with with the text based instructions for the latest gradle dependencies.

Integration

  1. Add the Chat SDK to your project
  2. Firebase Setup
  3. Chat SDK Initialization
  4. Set the Chat SDK Theme
  5. Enable Location Messages
  6. Display the login screen
  7. Add module dependencies
  8. Module Configuration
  9. Proguard
  10. Push Notifications, Security Rules and Storage

Customization

  1. Override Activity or Fragment
  2. Theme Chat SDK
  3. Customize the Icons
  4. Customize the Tabs
  5. Add a Chat Option
  6. Custom Message Types
  7. Handling Events
  8. Custom Push Handling
  9. Synchronize user profiles with your app
  10. Custom File Upload Handler
  11. Enable token authentication

Extras

Example Firebase Schema

Migrating from v4

Recommended background

Setup Service

We provide extensive documentation on Github but if you’re a non-technical user or want to save yourself some work you can take advantage of our setup and integration service.

Download Details:

Author: Chat-sdk
Source Code: https://github.com/chat-sdk/chat-sdk-android 
License: Apache-2.0 license

#firebase #sdk #messaging #android 

Chat-sdk-android: Chat SDK Android - Open Source Mobile Messenger
Bongani  Ngema

Bongani Ngema

1675995720

Firebase-php: Unofficial Firebase Admin SDK for PHP

Firebase-php

Unofficial Firebase Admin SDK for PHP. Firebase Admin PHP SDK

Overview

Firebase provides the tools and infrastructure you need to develop your app, grow your user base, and earn money. The Firebase Admin PHP SDK enables access to Firebase services from privileged environments (such as servers or cloud) in PHP.

Installation

The Firebase Admin PHP SDK is available on Packagist as kreait/firebase-php:

composer require kreait/firebase-php

Integrations for Laravel, Lumen and Symfony are available:

Documentation

Support

If you or your team rely on this project and me maintaining it, please consider becoming a Sponsor 🙏. Higher tiers enable access to extended support.

For more information, visit the Firebase Admin PHP SDK documentation.

Download Details:

Author: Kreait
Source Code: https://github.com/kreait/firebase-php 
License: MIT license

#firebase #php #cloud #messaging 

Firebase-php: Unofficial Firebase Admin SDK for PHP
Bongani  Ngema

Bongani Ngema

1675359960

Qksms: The most beautiful SMS messenger for Android

QKSMS

QKSMS is an open source replacement to the stock messaging app on Android. It is currently available on the Google Play Store and on F-Droid

QKSMS

Reporting bugs

A great bug report contains a description of the problem and steps to reproduce the problem. We need to know what we're looking for and where to look for it.

When reporting a bug, please make sure to provide the following information:

  • Steps to reproduce the issue
  • QKSMS version
  • Device / OS information

Translations

If you'd like to add translations to QKSMS, please join the project on Crowdin. Translations that are committed directly to source files will not be accepted.

Thank you

A special thank you to Jake (@klinker41) and Luke Klinker (@klinker24) for their work on android-smsmms, which has been an unspeakably large help in implementing MMS into QKSMS.

Contact

QKSMS is developed and maintained by Moez Bhatti. Feel free to reach out to moez@qklabs.com

Download Details:

Author: Moezbhatti
Source Code: https://github.com/moezbhatti/qksms 
License: GPL-3.0 license

#kotlin #android #material #design #messaging #sms 

Qksms: The most beautiful SMS messenger for Android
Rupert  Beatty

Rupert Beatty

1673341440

GrowingTextView: An UITextView in Swift

GrowingTextView

DEMO.gif

Requirements

iOS 8.0 or above

Installation

CocoaPods

GrowingTextView is available through CocoaPods. To install it, simply add the following line to your Podfile:

Swift 5.0
 

pod 'GrowingTextView', '0.7.2'

Swift 4.2
 

pod 'GrowingTextView', '0.6.1'

Swift 4.1
 

pod 'GrowingTextView', '~> 0.5'

Swift 3
 

pod 'GrowingTextView', '~> 0.4'

Swift 2.3 (Stopped update since Sep 2016)
 

pod 'GrowingTextView', :git => 'https://github.com/KennethTsang/GrowingTextView.git', :branch => 'swift2'

Carthage

GrowingTextView is also available through Carthage. To install it, add the following line to your Cartfile:

Swift 5.0
 

github "KennethTsang/GrowingTextView" ~> 0.7

Swift 4.2
 

github "KennethTsang/GrowingTextView" ~> 0.6

Swift 4.1
 

github "KennethTsang/GrowingTextView" ~> 0.5

Swift 3
 

github "KennethTsang/GrowingTextView" ~> 0.4

Swift 2.3 (Stopped update since Sep 2016)
 

github "KennethTsang/GrowingTextView" "swift2"

Manually

Copy GrowingTextView.swift into your project.

Usage

Example
 

GrowingTextview is just a textview, download the example to see how to use it as a input toolbar like other instant messaging apps.

Using GrowingTextview programmatically
 

let textView = GrowingTextView()
textView.delegate = self
addSubview(textView)

Using GrowingTextview in Storyboard
 

  1. Drag a TextView into Storyboard.
  2. Set class to "GrowingTextView".
  3. Set delegate to it's view controller.

automaticallyAdjustsScrollViewInsets
 

Sometime the view controller may incorrectly adjust the inset of textview automatically. To avoid this, set automaticallyAdjustsScrollViewInsets to false

override func viewDidLoad() {
    super.viewDidLoad()
    automaticallyAdjustsScrollViewInsets = false
}

Customization

ParameterTypeDescriptionDefault
maxLengthIntMaximum text length. Exceeded text will be trimmed. 0 means no limit.0
trimWhiteSpaceWhenEndEditingBoolTrim white space and new line characters when textview did end editing.true
placeholderString?Placeholder text.nil
placeholderColorUIColorPlaceholder text color.UIColor(white: 0.8, alpha: 1.0)
attributedPlaceholderNSAttributedString?Attributed Placeholder text.nil
minHeightCGFloatMinimum height of textview.0.0
maxHeightCGFloatMaximum height of textview.0.0

Examples

textView.maxLength = 140
textView.trimWhiteSpaceWhenEndEditing = false
textView.placeholder = "Say something..."
textView.placeholderColor = UIColor(white: 0.8, alpha: 1.0)
textView.minHeight = 25.0
textView.maxHeight = 70.0
textView.backgroundColor = UIColor.whiteColor()
textView.layer.cornerRadius = 4.0

Animation

  1. Adopt GrowingTextViewDelegate instead of UITextViewDelegate.
  2. Implement textViewDidChangeHeight.
  3. Call layoutIfNeeded() on superview inside the animation.
class ViewController: UIViewController, GrowingTextViewDelegate {
    func textViewDidChangeHeight(_ textView: GrowingTextView, height: CGFloat) {
       UIView.animate(withDuration: 0.2) {
           self.view.layoutIfNeeded()
       }
    }
}

Delegate

GrowingTextViewDelegate is inherited from UITextViewDelegate. You may use it's delegate function as a normal UITextView.

class ViewController: UIViewController, GrowingTextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        ...
    }
    func textViewDidEndEditing(_ textView: UITextView) {
        ...
    }
}

Check out UITextViewDelegate here: https://developer.apple.com/reference/uikit/uitextviewdelegate

Download Details:

Author: KennethTsang
Source Code: https://github.com/KennethTsang/GrowingTextView 
License: MIT license

#swift #chat #messaging #growing 

GrowingTextView: An UITextView in Swift

PHP Service Bus (publish-subscribe Pattern) Implementation

Introduction

A concurrency (based on Amp) framework, that lets you implement an asynchronous messaging, a transparent workflow and control of long-lived business transactions by means of the Saga pattern. It implements the message based architecture and it includes the following patterns: Saga, Publish\Subscribe, Message Bus.

Main Features

  • Сooperative multitasking
  • Asynchronous messaging (Publish\Subscribe pattern implementation)
  • Event-driven architecture
  • Distribution (messages can be handled by different applications)
    • Subscribers can be implemented on any programming language
  • High performance
  • Orchestration of long-lived business transactions (for example, a checkout) with the help of Saga Pattern
  • Full history of aggregate changes (EventSourcing)

See it in action

Jump into our Quick Start and build your first distributed solution in just 15 minutes.

Documentation

Documentation can be found in the .documentation directory

Requirements

  • PHP >=8.1
  • RabbitMQ/Redis/Nsq
  • PostgreSQL

Contributions are welcome! Please read CONTRIBUTING for details.

Communication Channels

You can find help and discussion in the following places:

Contributing

Contributions are welcome! Please read CONTRIBUTING for details.

Download Details:

Author: php-service-bus
Source Code: https://github.com/php-service-bus/service-bus 
License: MIT license

#php #service #async #messaging 

PHP Service Bus (publish-subscribe Pattern) Implementation
Rupert  Beatty

Rupert Beatty

1666101060

A Community-driven Replacement for JSQMessagesViewController

MessageKit

A community-driven replacement for JSQMessagesViewController

Goals

  • Provide a 🚨safe🚨 environment for others to learn and grow through Open Source.
  • Make adding Chat💬 to a project easy.
  • Enable beautiful and customizable Chat UI's.
  • Provide an awesome Open Source project for the iOS open source community.
  • Help others learn.

Installation

Swift Package Manager - Recommended

Swift 5.3 in Xcode 12 added support for assets in Swift Packages. You can just add MessageKit package to your project by entering it's repository URL

https://github.com/MessageKit/MessageKit

Older versions of Swift and Xcode don't support MessageKit via SPM.

Manual

Requirements

  • iOS 13 or later
  • Swift 5.5 or later

For iOS 12 or CocoaPods please use version 3.8.0

For iOS 11 please use version 3.3.0

For iOS 9 and iOS 10 please use version 3.1.1

Getting Started

Please have a look at the Quick Start guide and the FAQs.

We recommend you start by looking at the Example project or write a question with the "messagekit" tag on Stack Overflow. You can also look at previous issues here on GitHub with the "Question" tag.

For more on how to use the MessageInputBar, see the dependency it is based on InputBarAccessoryView. You can also see this short guide

Check out the full documentation here.

Cell Structure

Each default cell is a subclass of MessageContentCell which has 7 parts. From top down we have a: cellTopLabel, messageTopLabel, messageContainerView, messageBottomLabel, cellBottomLabel with the avatarView and accessoryView on either side respectively. Above we see the basic TextMessageCell which uses a MessageLabel as its main content.

This structure will allow you to create a layout that suits your needs as you can customize the size, appearance and padding of each. If you need something more advanced you can implement a custom cell, which we show how to do in the Example project.

InputBarAccessoryView Structure

The InputBarAccessoryView, 3rd party dependency from InputBarAccessoryView is a flexible and robust way of creating any kind of input layout you wish. Check the repo and examples there for more info.

Default Cells

The type of cell rendered for a given message is based on the MessageKind

public enum MessageKind {
    case text(String) // TextMessageCell
    case attributedText(NSAttributedString) // TextMessageCell
    case photo(MediaItem) // MediaMessageCell
    case video(MediaItem) // MediaMessageCell
    case location(LocationItem) // LocationMessageCell
    case emoji(String) // TextMessageCell
    case audio(AudioItem) // AudioMessageCell
    case contact(ContactItem) // ContactMessageCell
    case linkPreview(LinkItem) // LinkPreviewMessageCell

    /// A custom message.
    /// - Note: Using this case requires that you implement the following methods and handle this case:
    ///   - MessagesDataSource: customCell(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UICollectionViewCell
    ///   - MessagesLayoutDelegate: customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator
    case custom(Any?)
}

If you choose to use the .custom kind you are responsible for all of the cells layout. Any UICollectionViewCell can be returned for custom cells which means any of the styling you provide from the MessageDisplayDelegate will not effect your custom cell. Even if you subclass your cell from MessageContentCell. Read more about custom cells

Read more about the cases on the Quick Start guide.

Contributing

Tests Build framework Build example app Danger

Great! Look over these things first.

  • Please read our Code of Conduct
  • Check the Contributing Guide Lines.
  • Come join us on Slack and 🗣 don't be a stranger.
  • Check out the current issues and see if you can tackle any of those.
  • Download the project and check out the current code base. Suggest any improvements by opening a new issue.
  • Check out the What's Next section :point_down: to see where we are headed.
  • Check StackOverflow
  • Install SwiftLint to keep yourself in :neckbeard: style.
  • Be kind and helpful.

What's Next?

Check out the Releases to see what we are working on next.

Contact

Have a question or an issue about MessageKit? Create an issue!

Interested in contributing to MessageKit? Click here to join our Slack.

Apps using this library

Add your app to the list of apps using this library and make a pull request.

Please provide attribution, it is greatly appreciated.

Core Team

Thanks

Many thanks to the contributors of this project.

Inspiration

Inspired by JSQMessagesViewController 👈 💯

Download Details:

Author: MessageKit
Source Code: https://github.com/MessageKit/MessageKit 
License: MIT license

#swift #chat #ios #messaging 

A Community-driven Replacement for JSQMessagesViewController

10 Popular Golang Libraries That Implement Messaging Systems

In today's post we will learn about 10 Popular Golang Libraries that implement messaging Systems.

What is Messaging Systems?

A messaging system is responsible for transferring data from one application to another so the applications can focus on data without getting bogged down on data transmission and sharing. Distributed messaging is based on the concept of reliable message queuing. Messages are queued asynchronously between client applications and messaging system. There are two types of messaging patterns. The first one is a point-to-point and the other one is “publish–subscribe” (pub-sub) messaging system. Most of the messaging systems follow the pub-sub pattern.

Table of contents:

  • Ami - Go client to reliable queues based on Redis Cluster Streams.
  • Amqp - Go RabbitMQ Client Library.
  • APNs2 - HTTP/2 Apple Push Notification provider for Go — Send push notifications to iOS, tvOS, Safari and OSX apps.
  • Asynq - A simple, reliable, and efficient distributed task queue for Go built on top of Redis.
  • Beaver - A real time messaging server to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.
  • Benthos - A message streaming bridge between a range of protocols.
  • Bus - Minimalist message bus implementation for internal communication.
  • Centrifugo - Real-time messaging (Websockets or SockJS) server in Go.
  • Chanify - A push notification server send message to your iOS devices.
  • DBus - Native Go bindings for D-Bus.

1 - Ami: Go client to reliable queues based on Redis Cluster Streams.

Go client to reliable queues based on Redis Cluster Streams.

Consume/produce performance

Performance is dependent from:

  • Redis Cluster nodes count;
  • ping RTT from client to Redis Cluster master nodes;
  • network speed between nodes;
  • message sizes;
  • Ami configuration.

As example, 10-nodes Redis Cluster with half of nodes in other datacenter (50 msec ping), 1 master/1 slave, with message "{}" got:

$ go run examples/performance/main.go
Produced 1000000 in 3.423883 sec, rps 292066.022156
Consumed 151000 in 1.049238 sec, rps 143913.931722
Acked 151000 in 0.973587 sec, rps 155096.612263

Producer example

	type errorLogger struct{}

	func (l *errorLogger) AmiError(err error) {
		println("Got error from Ami:", err.Error())
	}

	pr, err := ami.NewProducer(
		ami.ProducerOptions{
			ErrorNotifier:     &errorLogger{},
			Name:              "ruthie",
			PendingBufferSize: 10000000,
			PipeBufferSize:    50000,
			PipePeriod:        time.Microsecond * 1000,
			ShardsCount:       10,
		},
		&redis.ClusterOptions{
			Addrs:        []string{"172.17.0.1:7001", "172.17.0.1:7002"},
			ReadTimeout:  time.Second * 60,
			WriteTimeout: time.Second * 60,
		},
	)
	if err != nil {
		panic(err)
	}

	for i := 0; i < 10000; i++ {
		pr.Send("{}")
	}

	pr.Close()

View on Github

2 - Amqp: Go RabbitMQ Client Library.

Differences from streadway/amqp

Some things are different compared to the original client, others haven't changed.

Package Name

This library uses a different package name. If moving from streadway/amqp, using an alias may reduce the number of changes needed:

amqp "github.com/rabbitmq/amqp091-go"

Goals

Provide a functional interface that closely represents the AMQP 0.9.1 model targeted to RabbitMQ as a server. This includes the minimum necessary to interact the semantics of the protocol.

Non-goals

Things not intended to be supported.

  • Auto reconnect and re-synchronization of client and server topologies.
    • Reconnection would require understanding the error paths when the topology cannot be declared on reconnect. This would require a new set of types and code paths that are best suited at the call-site of this package. AMQP has a dynamic topology that needs all peers to agree. If this doesn't happen, the behavior is undefined. Instead of producing a possible interface with undefined behavior, this package is designed to be simple for the caller to implement the necessary connection-time topology declaration so that reconnection is trivial and encapsulated in the caller's application code.
  • AMQP Protocol negotiation for forward or backward compatibility.
    • 0.9.1 is stable and widely deployed. AMQP 1.0 is a divergent specification (a different protocol) and belongs to a different library.
  • Anything other than PLAIN and EXTERNAL authentication mechanisms.
    • Keeping the mechanisms interface modular makes it possible to extend outside of this package. If other mechanisms prove to be popular, then we would accept patches to include them in this package.
  • Support for basic.return and basic.ack frame ordering. This client uses Go channels for certain protocol events and ordering between events sent to two different channels generally cannot be guaranteed.

Usage

See the _examples subdirectory for simple producers and consumers executables. If you have a use-case in mind which isn't well-represented by the examples, please file an issue.

View on Github

3 - APNs2: HTTP/2 Apple Push Notification provider for Go — Send push notifications to iOS, tvOS, Safari and OSX apps.

APNS/2 is a go package designed for simple, flexible and fast Apple Push Notifications on iOS, OSX and Safari using the new HTTP/2 Push provider API.

Features

  • Uses new Apple APNs HTTP/2 connection
  • Fast - See notes on speed
  • Works with go 1.7 and later
  • Supports new Apple Token Based Authentication (JWT)
  • Supports new iOS 10 features such as Collapse IDs, Subtitles and Mutable Notifications
  • Supports new iOS 15 features interruptionLevel and relevanceScore
  • Supports persistent connections to APNs
  • Supports VoIP/PushKit notifications (iOS 8 and later)
  • Modular & easy to use
  • Tested and working in APNs production environment

Install

  • Make sure you have Go installed and have set your GOPATH.
  • Install apns2:
go get -u github.com/sideshow/apns2

If you are running the test suite you will also need to install testify:

go get -u github.com/stretchr/testify

Example

package main

import (
  "log"
  "fmt"

  "github.com/sideshow/apns2"
  "github.com/sideshow/apns2/certificate"
)

func main() {

  cert, err := certificate.FromP12File("../cert.p12", "")
  if err != nil {
    log.Fatal("Cert Error:", err)
  }

  notification := &apns2.Notification{}
  notification.DeviceToken = "11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"
  notification.Topic = "com.sideshow.Apns2"
  notification.Payload = []byte(`{"aps":{"alert":"Hello!"}}`) // See Payload section below

  // If you want to test push notifications for builds running directly from XCode (Development), use
  // client := apns2.NewClient(cert).Development()
  // For apps published to the app store or installed as an ad-hoc distribution use Production()

  client := apns2.NewClient(cert).Production()
  res, err := client.Push(notification)

  if err != nil {
    log.Fatal("Error:", err)
  }

  fmt.Printf("%v %v %v\n", res.StatusCode, res.ApnsID, res.Reason)
}

View on Github

4 - Asynq: A simple, reliable, and efficient distributed task queue for Go built on top of Redis.

Asynq is a Go library for queueing tasks and processing them asynchronously with workers. It's backed by Redis and is designed to be scalable yet easy to get started.

Highlevel overview of how Asynq works:

  • Client puts tasks on a queue
  • Server pulls tasks off queues and starts a worker goroutine for each task
  • Tasks are processed concurrently by multiple workers

Task queues are used as a mechanism to distribute work across multiple machines. A system can consist of multiple worker servers and brokers, giving way to high availability and horizontal scaling.

Quickstart

Make sure you have Go installed (download). Version 1.14 or higher is required.

Initialize your project by creating a folder and then running go mod init github.com/your/repo (learn more) inside the folder. Then install Asynq library with the go get command:

go get -u github.com/hibiken/asynq

Make sure you're running a Redis server locally or from a Docker container. Version 4.0 or higher is required.

Next, write a package that encapsulates task creation and task handling.

package tasks

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"
    "github.com/hibiken/asynq"
)

// A list of task types.
const (
    TypeEmailDelivery   = "email:deliver"
    TypeImageResize     = "image:resize"
)

type EmailDeliveryPayload struct {
    UserID     int
    TemplateID string
}

type ImageResizePayload struct {
    SourceURL string
}

//----------------------------------------------
// Write a function NewXXXTask to create a task.
// A task consists of a type and a payload.
//----------------------------------------------

func NewEmailDeliveryTask(userID int, tmplID string) (*asynq.Task, error) {
    payload, err := json.Marshal(EmailDeliveryPayload{UserID: userID, TemplateID: tmplID})
    if err != nil {
        return nil, err
    }
    return asynq.NewTask(TypeEmailDelivery, payload), nil
}

func NewImageResizeTask(src string) (*asynq.Task, error) {
    payload, err := json.Marshal(ImageResizePayload{SourceURL: src})
    if err != nil {
        return nil, err
    }
    // task options can be passed to NewTask, which can be overridden at enqueue time.
    return asynq.NewTask(TypeImageResize, payload, asynq.MaxRetry(5), asynq.Timeout(20 * time.Minute)), nil
}

//---------------------------------------------------------------
// Write a function HandleXXXTask to handle the input task.
// Note that it satisfies the asynq.HandlerFunc interface.
//
// Handler doesn't need to be a function. You can define a type
// that satisfies asynq.Handler interface. See examples below.
//---------------------------------------------------------------

func HandleEmailDeliveryTask(ctx context.Context, t *asynq.Task) error {
    var p EmailDeliveryPayload
    if err := json.Unmarshal(t.Payload(), &p); err != nil {
        return fmt.Errorf("json.Unmarshal failed: %v: %w", err, asynq.SkipRetry)
    }
    log.Printf("Sending Email to User: user_id=%d, template_id=%s", p.UserID, p.TemplateID)
    // Email delivery code ...
    return nil
}

// ImageProcessor implements asynq.Handler interface.
type ImageProcessor struct {
    // ... fields for struct
}

func (processor *ImageProcessor) ProcessTask(ctx context.Context, t *asynq.Task) error {
    var p ImageResizePayload
    if err := json.Unmarshal(t.Payload(), &p); err != nil {
        return fmt.Errorf("json.Unmarshal failed: %v: %w", err, asynq.SkipRetry)
    }
    log.Printf("Resizing image: src=%s", p.SourceURL)
    // Image resizing code ...
    return nil
}

func NewImageProcessor() *ImageProcessor {
	return &ImageProcessor{}
}

View on Github

5 - Beaver: A real time messaging server to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.

Beaver is a real-time messaging server. With beaver you can easily build scalable in-app notifications, realtime graphs, multiplayer games, chat applications, geotracking and more in web applications and mobile apps.

Documentation

Run Beaver on Ubuntu

Download the latest beaver binary. Make it executable from everywhere.

$ export BEAVER_LATEST_VERSION=$(curl --silent "https://api.github.com/repos/Clivern/Beaver/releases/latest" | jq '.tag_name' | sed -E 's/.*"([^"]+)".*/\1/' | tr -d v)

$ curl -sL https://github.com/Clivern/Beaver/releases/download/v{$BEAVER_LATEST_VERSION}/beaver_{$BEAVER_LATEST_VERSION}_Linux_x86_64.tar.gz | tar xz

Then install redis cluster or a single node. Update the following config file with redis configs.

Create the configs file config.yml from config.dist.yml. Something like the following:

# App configs
app:
    # Env mode (dev or prod)
    mode: ${BEAVER_APP_MODE:-prod}
    # HTTP port
    port: ${BEAVER_API_PORT:-8080}
    # Hostname
    hostname: ${BEAVER_API_HOSTNAME:-127.0.0.1}
    # TLS configs
    tls:
        status: ${BEAVER_API_TLS_STATUS:-off}
        pemPath: ${BEAVER_API_TLS_PEMPATH:-cert/server.pem}
        keyPath: ${BEAVER_API_TLS_KEYPATH:-cert/server.key}

    # API Configs
    api:
        key: ${BEAVER_API_KEY:-6c68b836-6f8e-465e-b59f-89c1db53afca}

    # Beaver Secret
    secret: ${BEAVER_SECRET:-sWUhHRcs4Aqa0MEnYwbuQln3EW8CZ0oD}

    # Runtime, Requests/Response and Beaver Metrics
    metrics:
        prometheus:
            # Route for the metrics endpoint
            endpoint: ${BEAVER_METRICS_PROM_ENDPOINT:-/metrics}

    # Application Database
    database:
        # Database driver
        driver: ${BEAVER_DB_DRIVER:-redis}

        # Redis Configs
        redis:
            # Redis address
            address: ${BEAVER_DB_REDIS_ADDR:-localhost:6379}
            # Redis password
            password: ${BEAVER_DB_REDIS_PASSWORD:- }
            # Redis database
            db: ${BEAVER_DB_REDIS_DB:-0}

    # Log configs
    log:
        # Log level, it can be debug, info, warn, error, panic, fatal
        level: ${BEAVER_LOG_LEVEL:-info}
        # Output can be stdout or abs path to log file /var/logs/beaver.log
        output: ${BEAVER_LOG_OUTPUT:-stdout}
        # Format can be json
        format: ${BEAVER_LOG_FORMAT:-json}

The run the beaver with systemd

$ beaver api -c /path/to/config.yml

View on Github

6 - Benthos: A message streaming bridge between a range of protocols.

Benthos is a high performance and resilient stream processor, able to connect various sources and sinks in a range of brokering patterns and perform hydration, enrichments, transformations and filters on payloads.

It comes with a powerful mapping language, is easy to deploy and monitor, and ready to drop into your pipeline either as a static binary, docker image, or serverless function, making it cloud native as heck.

Benthos is declarative, with stream pipelines defined in as few as a single config file, allowing you to specify connectors and a list of processing stages:

input:
  gcp_pubsub:
    project: foo
    subscription: bar

pipeline:
  processors:
    - bloblang: |
        root.message = this
        root.meta.link_count = this.links.length()
        root.user.age = this.user.age.number()

output:
  redis_streams:
    url: tcp://TODO:6379
    stream: baz
    max_in_flight: 20

Delivery Guarantees

Delivery guarantees can be a dodgy subject. Benthos processes and acknowledges messages using an in-process transaction model with no need for any disk persisted state, so when connecting to at-least-once sources and sinks it's able to guarantee at-least-once delivery even in the event of crashes, disk corruption, or other unexpected server faults.

This behaviour is the default and free of caveats, which also makes deploying and scaling Benthos much simpler.

Install

Grab a binary for your OS from here. Or use this script:

curl -Lsf https://sh.benthos.dev | bash

Or pull the docker image:

docker pull jeffail/benthos

Benthos can also be installed via Homebrew:

brew install benthos

For more information check out the getting started guide.

Run

benthos -c ./config.yaml

Or, with docker:

# Using a config file
docker run --rm -v /path/to/your/config.yaml:/benthos.yaml jeffail/benthos

# Using a series of -s flags
docker run --rm -p 4195:4195 jeffail/benthos \
  -s "input.type=http_server" \
  -s "output.type=kafka" \
  -s "output.kafka.addresses=kafka-server:9092" \
  -s "output.kafka.topic=benthos_topic"

View on Github

7 - Bus: Minimalist message bus implementation for internal communication.

Bus is a minimalist event/message bus implementation for internal communication. It is heavily inspired from my event_bus package for Elixir language.

API

The method names and arities/args are stable now. No change should be expected on the package for the version 3.x.x except any bug fixes.

Installation

Via go packages: go get github.com/mustafaturan/bus/v3

Usage

Configure

The package requires a unique id generator to assign ids to events. You can write your own function to generate unique ids or use a package that provides unique id generation functionality.

The bus package respect to software design choice of the packages/projects. It supports both singleton and dependency injection to init a bus instance.

Hint: Check the demo project for the singleton configuration.

Here is a sample initilization using monoton id generator:

import (
    "github.com/mustafaturan/bus/v3"
    "github.com/mustafaturan/monoton/v2"
    "github.com/mustafaturan/monoton/v2/sequencer"
)

func NewBus() *bus.Bus {
    // configure id generator (it doesn't have to be monoton)
    node        := uint64(1)
    initialTime := uint64(1577865600000) // set 2020-01-01 PST as initial time
    m, err := monoton.New(sequencer.NewMillisecond(), node, initialTime)
    if err != nil {
        panic(err)
    }

    // init an id generator
    var idGenerator bus.Next = m.Next

    // create a new bus instance
    b, err := bus.NewBus(idGenerator)
    if err != nil {
        panic(err)
    }

    // maybe register topics in here
    b.RegisterTopics("order.received", "order.fulfilled")

    return b
}

View on Github

8 - Centrifugo: Real-time messaging (Websockets or SockJS) server in Go.

Centrifugo is an open-source scalable real-time messaging server. Centrifugo can instantly deliver messages to application online users connected over supported transports (WebSocket, HTTP-streaming, SSE/EventSource, GRPC, SockJS, WebTransport). Centrifugo has the concept of a channel – so it's a user-facing PUB/SUB server.

Centrifugo is language-agnostic and can be used to build chat apps, live comments, multiplayer games, real-time data visualizations, collaborative tools, etc. in combination with any backend. It is well suited for modern architectures and allows decoupling the business logic from the real-time transport layer.

Several official client SDKs for browser and mobile development wrap the bidirectional protocol. In addition, Centrifugo supports a unidirectional approach for simple use cases with no SDK dependency.

How to install

See installation instructions in Centrifugo documentation.

Highlights

  • Centrifugo is fast and capable to scale to millions of simultaneous connections
  • Simple integration with any application – Centrifugo works as a separate service, provides HTTP and GRPC API
  • Client real-time SDKs for popular frontend environments – for both web and mobile development
  • Strict client protocol based on Protobuf schema, with JSON and binary data transfer support
  • Bidirectional transport support (WebSocket and SockJS) for full-featured communication
  • Unidirectional transport support for simple use cases with zero SDK dependency - use native APIs (SSE, Fetch, WebSocket, GRPC)
  • User authentication with JWT or over connection request proxy to the configured HTTP/GRPC endpoint
  • Proper connection management and expiration control
  • Various types of channel subscriptions: client-side or server-side
  • Transform RPC calls sent over real-time transport to the configured HTTP or GRPC endpoint calls
  • Presence information for channels (show all active clients in a channel)
  • History information for channels (last messages published into a channel)
  • Join/leave events for channels (client subscribed/unsubscribed)
  • Automatic recovery of missed messages between reconnects over configured retention period
  • Built-in administrative web panel
  • Cross-platform – works on Linux, macOS and Windows
  • Ready to deploy (Docker, RPM/DEB packages, automatic TLS certificates, Prometheus instrumentation, Grafana dashboard)
  • Open-source license

View on Github

9 - Chanify: A push notification server send message to your iOS devices.

Chanify is a safe and simple notification tools. For developers, system administrators, and everyone can push notifications with API.

Features

Chanify is include these features:

  • Customize channel for notifications.
  • Deploy your own node server.
  • Distributed architecture design.
  • Design for privacy protection.
  • Support text/image/audio/file message format.

Getting Started

  1. Install iOS App(1.0.0 version and above) or macOS App(1.3.0 version and above).
  2. Get send token, more detail.
  3. Send message.

Installation

Precompiled binary

Download precompiled binary from here.

Docker

$ docker pull wizjin/chanify:latest

From source

$ git clone https://github.com/chanify/chanify.git
$ cd chanify
$ make install

Usage

As Sender Client

Use chanify to send message.

# Text message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --text=<message>

# URL message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --link=<web url>

# Image message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --image=<image file path>

# Audio message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --audio=<audio file path>

# File message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --file=<file path> --text=<file description>

# Action  message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --text=<message> --title=<title> --action="<action name>|<action url>"

# Timeline message
$ chanify send --endpoint=http://<address>:<port> --token=<token> --timeline.code=<code> <item1>=<value1> <item2>=<value2> ...

endpoint default value is https://api.chanify.net, and notification will send by default server. If you have own node server, please set endpoint to your node server url.

View on Github

10 - DBus: Native Go bindings for D-Bus.

dbus is a simple library that implements native Go client bindings for the D-Bus message bus system.

Features

  • Complete native implementation of the D-Bus message protocol
  • Go-like API (channels for signals / asynchronous method calls, Goroutine-safe connections)
  • Subpackages that help with the introspection / property interfaces

Installation

This packages requires Go 1.12 or later. It can be installed by running the command below:

go get github.com/godbus/dbus/v5

Usage

The complete package documentation and some simple examples are available at godoc.org. Also, the _examples directory gives a short overview over the basic usage.

Projects using godbus

  • fyne a cross platform GUI in Go inspired by Material Design.
  • fynedesk a full desktop environment for Linux/Unix using Fyne.
  • go-bluetooth provides a bluetooth client over bluez dbus API.
  • iwd go bindings for the internet wireless daemon "iwd".
  • notify provides desktop notifications over dbus into a library.
  • playerbm a bookmark utility for media players.
  • rpic lightweight web app and RESTful API for managing a Raspberry Pi

Please note that the API is considered unstable for now and may change without further notice.

View on Github

Thank you for following this article.

Related videos:

Gopher in an Event-Driven playground

#go #golang #messaging #system 

10 Popular Golang Libraries That Implement Messaging Systems
Elian  Harber

Elian Harber

1659838500

Sandglass: A Distributed, Horizontally Scalable, Persistent

Sandglass is a distributed, horizontally scalable, persistent, time ordered message queue. It was developed to support asynchronous tasks and message scheduling which makes it suitable for usage as a task queue.  

Features

  • Horizontal scalability
  • Highly available
  • Persistent storage
  • Time ordered
  • Multiple consumers per group for a partition
  • Produce message to be consumed in the future
  • Acknowledge/NotAcknowledge each message individualy
  • Automatic redelivery and commit offset tracking
  • Language agnostic

EXPERIMENTAL: This is a prototype of a side project. This should not be used in production in its current form as things may change quickly without notice.

Installation

On MacOS using Homebrew:

brew install celrenheit/taps/sandglass

For other platforms, you can grab binaries here.

Getting started

NOTE: All data will be stored in /tmp/node1. If you wish to change this, copy demo/node1.yaml and modify it accordingly.

First, let's launch sandglass server:

sandglass --config https://raw.githubusercontent.com/celrenheit/sandglass/master/demo/node1.yaml --offset_replication_factor 1

In a second terminal window, create a emails topic:

sandctl topics create emails --num_partitions 3 --replication_factor 1

...produce 10,000 messages:

sandctl produce emails '{"dest" : "hi@example.com"}' -n 10000

...and consume from the emails topic:

sandctl consume emails

(or if you wish to watch you can use sandctl consume -f emails to see messages coming live)

We are using a single node cluster, this is not recommended for production.

Add a second node to the cluster:

sandglass --config https://raw.githubusercontent.com/celrenheit/sandglass/master/demo/node2.yaml

and repeat the same steps described above for another topic and increasing the replication factor to 2.

Motivation

As previously asked (#4), the purpose of this project might not seem clear. In short, there is two goals.

The first is to be able to track each message individually (i.e. not using a single commit offset) to make suitable for asynchronous tasks.

The second is the ability to schedule messages to be consumed in the future. This make it suitable for retries.

Documentation

Documentation is a work in progress and still lacking.

  • API docs
  • Overview - TODO
  • Clients development guides - TODO
  • Documentation the different ways of starting a cluster

Clients

Go

Installation

go get -u github.com/celrenheit/sandglass-client/go/sg

Documentation

The documentation is available on godoc.

Usage

Producer

// Let's first create a client by providing adresses of nodes in the sandglass cluster
client, err := sg.NewClient(
    sg.WithAddresses(":7170"),
)
if err != nil {
    panic(err)
}
defer client.Close()

// Now we produce a new message
// Notice the empty string "" in the 3th argument, meaning let sandglass choose a random partition
err := client.Produce(context.Background(), "emails", "", &sgproto.Message{
    Value: []byte("Hello, Sandglass!"),
})
if err != nil {
    panic(err)
}

In order to produce message in the future, you need to specify a custom offset:

inOneHour := time.Now().Add(1 * time.Hour)
gen := sandflake.NewFixedTimeGenerator(inOneHour)

msg := &sgproto.Message{
    Offset: gen.Next(),
    Value:  []byte("Hello"),
}

err := client.ProduceMessage(context.Background(), "emails", "", msg)
if err != nil {
    return err
}

This will produce a message that will be available for consumption in 1h.

Consumer

  1. High-level
// Let's first create a client by providing adresses of nodes in the sandglass cluster
client, err := sg.NewClient(
    sg.WithAddresses(":7170"),
)
if err != nil {
    panic(err)
}
defer client.Close()

mux := sg.NewMux()
mux.SubscribeFunc("emails", func(msg *sgproto.Message) error {
    // handle message
    log.Printf("received: %s\n", string(msg.Value))
    return nil
})

m := &sg.MuxManager{
    Client:               c,
    Mux:                  mux,
    ReFetchSleepDuration: dur,
}

err = m.Start()
if err != nil {
    log.Fatal(err)
}
  1. Low level
// Let's first create a client by providing adresses of nodes in the sandglass cluster
client, err := sg.NewClient(
    sg.WithAddresses(":7170"),
)
if err != nil {
    panic(err)
}
defer client.Close()


// Listing partitions in order to choose one to consume from
partitions, err := client.ListPartitions(context.Background(), topic)
if err != nil {
    panic(err)
}

// we are choosing only one partition for demo purposes
partition := partitions[0]

// Create a new consumer using consumer group emails-sender and consumer name consumer1
consumer := client.NewConsumer(topic, partition, "emails-sender", "consumer1")

// and consume messages
msgCh, err := consumer.Consume(context.Background())
if err != nil {
    panic(err)
}

for msg := range msgCh {
    // do an amazing amount of work
    log.Printf("received: %s\n", string(msg.Value))

    // when we are done, we Acknowledge the message
    // but we can also NotAcknowledge to trigger a redelivery of the message
    if err := consumer.Acknowledge(context.Background(), msg); err!=nil {
        panic(err)
    }
}

Java, Python, Node.js, Ruby

Interested in having client for one the following languages ?

Support is planned but there is no specific schedule. So, if you are interested to quickly have a client in your language, help is welcome!

Check the raw generated code available on https://github.com/celrenheit/sandglass-grpc and feel free to submit your through a pull request to https://github.com/celrenheit/sandglass-client.

Architecture

General

                                                                  +-----------------+
                                                                  |                 |
                          +--------------------------+     +------>  Consumer       |
                          |                          |     |      |                 |
                          |    Sandglass Cluster     |     |      +-----------------+
                          |                          |     |
                          |                          +-----+  Round robin consumption
+-----------------+       |   +------------------+   |     |
|                 |       |   |                  |   |     |      +-----------------+
|  Producer       +------->   |                  |   |     |      |                 |
|                 |       |   |    Broker 1      |   |     +------>  Consumer       |
+-----------------+       |   |                  |   |            |                 |
                          |   |                  |   |            +-----------------+
                          |   +------------------+   |
+-----------------+       |                          |
|                 |       |   +------------------+   |
|  Producer       +------->   |                  |   |            +-----------------+
|                 |       |   |                  |   |            |                 |
+-----------------+       |   |    Broker 2      |   +-----+------>  Consumer       |
                          |   |                  |   |     |      |                 |
                          |   |                  |   |     |      +-----------------+
+-----------------+       |   +------------------+   |     |
|                 |       |                          |     |  Failover consumption
|  Producer       +------->   +------------------+   |     |     (NOT DONE YET)
|                 |       |   |                  |   |     |
+-----------------+       |   |                  |   |     |      +-----------------+
                          |   |    Broker 3      |   |     |      |                 |
                          |   |                  |   |     +------+  Consumer       |
                          |   |                  |   |            |                 |
                          |   +------------------+   |            +-----------------+
                          |                          |
                          |                          |
                          +--------------------------+

Topic

There is two kinds of topics:

Timer:

  • Fixed number of partitions (set up-front, could change)
  • Time ordered using sandflake IDs
  • Can produce messages in the future

KV:

  • Fixed number of partitions (set up-front, cannot change)
  • Behaves like a distributed key value store

A topic has a number of partitions. Data is written into a single partition. Either the destination partition is specified by the producer. Otherwise, we fallback to choosing the destination partition using a consistent hashing algorithm.

Each produced message to a partition writes a message to a Write Ahead Log (WAL) and to the View Log (VL). The WAL is used for the replication logic, it is sorted in the order each message was produced. The View Log is used for message consumption, it is mainly sorted by time (please refer to sandflake ids for the exact composition) for a Timer topics and by keys for KV topics.

A message is composed of the following fields:

    index                       <- position in the WAL

    offset                      <- position in the view log for timer topics
    key and clusteringKey       <- position in the view log for key for kv topics (key is used for partitioning)

    value                       <- your payload

Offset Tracking

Sandglass is responsible for maintaining two offsets for each consumer group:

  • Commited: the offset below which all messages have been ACKed
  • Consumed: the last consumed message

When consuming sandglass starts from the last commited until the last consumed message to check the redelivery of messages. And from the last consumed offset until the last produced message to deliver the new messages. These two actions are done in parallel.

Technologies used

Contributing

Want to contribute to Sandglass ? Awesome! Feel free to submit an issue or a pull request.

Here are some ways you can help:

  • Report bugs
  • Your language is not supported ? Feel free to build a client. Trust me, it should not take you long :)
  • Improve code/documentation
  • Propose new features
  • and more...

Author: Sandglass
Source Code: https://github.com/sandglass/sandglass 
License: Apache-2.0 license

#go #golang #messaging 

Sandglass: A Distributed, Horizontally Scalable, Persistent
Rupert  Beatty

Rupert Beatty

1658350680

Laravel-Talk: A Real-time Users Messaging and Chatting System Laravel

Laravel-Talk

Talk is a Laravel based user conversation (chatting) system with realtime messaging. You can easily integrate this package with any Laravel based project. It helps you to develop a messaging system in just few minutes. Here is a project screenshot that was developed by Talk.

Talk v2.1.0 supports realtime messaging. Learn more about Talk Live Messaging

Feedback

If you already used Talk, please share your experience with us. It will make the project better.

Give us your feedback

Built with Talk

If you are using Talk in your project please share your project URL or project name with us. It will inspire other people to use Talk.

See which project was Built with Talk.

Caution

Do not migrate 1.1.7 from its higher version directly. Please try our sample project first and then apply it on your project.

Talk-Example Screenshot

You may try Talk-Example project.

Or you can try live Demo by using this credentials:

username: admin   
password: admin

So let's start your tour :)

Features

  • Head to head messaging
  • Realtime messaging
  • Creating new conversation
  • Message threads with latest one
  • View conversations by user id or conversation id
  • Support pagination in threads and messages
  • Delete (soft delete) message from both end. Sender and receiver can delete their message from their end
  • Permanent delete message
  • Mark message as seen
  • Only participant can view or access there message or message threads
  • Inline url render using oembed specifications

Installation

Talk is a Laravel package so you can install it via Composer. Run this command in your terminal from your project directory:

composer require nahid/talk

Wait for a while, Composer will automatically install Talk in your project.

Configuration

When the download is complete, you have to call this package service in config/app.php config file. To do that, add this line in app.php in providers section:

Nahid\Talk\TalkServiceProvider::class,

To use facade you have to add this line in app.php in aliases array:

'Talk'      => Nahid\Talk\Facades\Talk::class,

Now run this command in your terminal to publish this package resources:

php artisan vendor:publish --provider="Nahid\Talk\TalkServiceProvider"

After running this command, all necessary file will be included in your project. This package has two default migrations. So you have to run migrate command like this. (But make sure your database configuration is configured correctly.)

php artisan migrate

Okay, now you need to configure your user model for Talk. Go to config/talk.php and config it:

return [
    'user' => [
        'model' => 'App\User',
        'foreignKey' => null,
        'ownerKey' => null,
    ],

    'broadcast' => [
        'enable' => true,
        'app_name' => 'talk-example',
        'driver' => env('TALK_BROADCAST_DRIVER', 'pusher'), // pusher or laravel-websockets
        'pusher' => [
            'app_id' => env('PUSHER_APP_ID', ''),
            'app_key' => env('PUSHER_APP_KEY', ''),
            'app_secret' => env('PUSHER_APP_SECRET', ''),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER', 'ap2'),
                'encrypted' => env('PUSHER_APP_ENCRYPTION', false),
                'host' => '127.0.0.1',
                'port' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
                'scheme' => 'http',
                'wsHost' => '127.0.0.1',
                'wsPort' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
                'forceTLS' => false,
                'disableStats' => true
            ]
        ],
    ],


    'oembed' => [
        'enabled' => false,
        'url' => '',
        'key' => ''
    ]
];

Usage

Its very easy to use. If you want to set authenticate user id globally then you have to set a middleware first. Go to app/Http/Kernel.php and set it in $routeMiddleware array:

'talk'  =>  \Nahid\Talk\Middleware\TalkMiddleware::class,

And now you can use it from anywhere with middleware. Suppose you have a Controller and you want to set authenticate user id globally then write this in controller constructor:

$this->middleware('talk');

But instead of set id globally you can use these procedure from any method in controller:

Talk::setAuthUserId(auth()->user()->id);

Now you may use any method what you need. But if want pass authentic id instantly, this method may help you:

Talk::user(auth()->user()->id)->anyMethodHere();

Please see the API Doc.

API List

setAuthUserId

setAuthUserId method sets the currently loggedin user id, which you pass through parameter. If you pass null or empty value then it returns false.

Syntax

void setAuthUserId($userid)

Example

Constructor of a Controller is the best place to write this method.

function __construct()
{
    Talk::setAuthUserId(auth()->user()->id);
}

When you pass logged in user ID, Talk will know who is currently authenticated for this system. So Talk retrieve all information based on this user.

user

You may use this method instead of setAuthUserId() method. When you have to instantly access users conversations then you may use it. Syntax

object user($id)

Example When you haven't set authenticated user id globally, then you just use this method directly with others method.

$inboxes = Talk::user(auth()->user()->id)->threads();
return view('messages.threads', compact('inboxes'));

isConversationExists

This method checks currently logged in user and if given user is already in conversation

Syntax

int|false isConversationExists($userid)

Example

if ($conversationId = Talk::isConversationExists($userId)) {
    Talk::sendMessage($conversationId, $message);
} 

isAuthenticUser

isAuthenticUser checks if the given user exists in given conversation.

Syntax

boolean isAuthenticUser($conversationId, $userId)

Example

if (Talk::isAuthenticUser($conversationId, $userId)) {
    Talk::sendMessage($conversationId, $message);
} 

sendMessage

You can send messages via conversation id by using this method. If the message is successfully sent, it will return objects of Message model otherwise, it will return false

Syntax

object|false sendMessage($conversationId, $message)

Example

    $message = Talk::sendMessage($conversationId, $message);
    if ($message) {
        return response()->json(['status'=>'success', 'data'=>$message], 200);
   }

sendMessageByUserId

You can send message via receiver id by using this method. If the message is successfully sent, it will return objects of Message model otherwise, it will return false

Syntax

object|false sendMessageByUserId($userId, $message)

getInbox

If you want to get all the inboxes except soft deleted message , this method may help you. This method gets all the inboxes via previously assigned authenticated user id. It returns collections of message thread with latest message.

Syntax

array getInbox([$order = 'desc'[,$offset = 0[, $take = 20]]])

Example

// controller method
$inboxes = Talk::getInbox();
return view('message.threads', compact('inboxes'));
<!-- messages/threads.blade.php -->
<ul>
    @foreach($inboxes as $inbox)
        <li>
            <h2>{{$inbox->withUser->name}}</h2>
            <p>{{$inbox->thread->message}}</p>
            <span>{{$inbox->thread->humans_time}}</span>
        </li>
    @endforeach
</ul>

getInboxAll

Its similar as getInbox() method. If you want to get all the inboxes with soft deleted messages, this method may help you. This method gets all the inboxes via given user id.

Syntax

object getInboxAll([$order = 'desc'[,$offset = 0[, $take = 20]]])

threads

This method is an alias of getInbox() method.

Syntax

array threads([$order = 'desc'[,$offset = 0[, $take = 20]]])

threadsAll

This method is an alias of getInboxAll() method.

Syntax

array threadsAll([$order = 'desc'[,$offset = 0[, $take = 20]]])

getConversationsById

When you want to get all the conversations using your desire conversation id, you can try this method. This method returns all the conversations (except soft deleted) with sender and withUser objects

Syntax

array getConversationsById($conversationId[, $offset = 0[, $take = 20]])

Example

// controller method
$conversations = Talk::getConversationsById($conversationId);
$messages = $conversations->messages;
$withUser = $conversations->withUser;

return view('messages.conversations', compact('messages', 'withUser'));

This method returns two objects messages and withUser. messages object contains messages collection and withUser object contains participant User collections.

Let's see how to use it with your views

<!-- messages/conversations.blade.php -->
<div class="message-container">
    <h2>Chat with {{$withUser->name}}</h2>
    @foreach ($messages as $msg)
     <div class="message">
        <h4>{{$msg->sender->name}}</h4>
        <span>{{$msg->humans_time}}</span>
        <p>
            {{$msg->message}}
       </p> 
    </div>
    @endforeach
</div>

getConversationsAllById

This method is similar as getConversationsById(). The only difference between this method is its return all messages with soft deleted items.

Syntax

array getConversationsAllById($conversationId[, $offset = 0[, $take = 20]])

getConversationsByUserId

When you want to get all the conversations using your desire receiver id, you can try this method. This method returns all the conversations (except soft deleted message) with user's objects

Syntax

object getConversationsByUserId($receiverId [, $offset = 0[, $take = 20]])

getConversationsAllByUserId

This method is similar as getConversationsByUserId(). The only difference between this method is it returns all messages with soft deleted items.

Syntax

array getConversationsAllByUserId($receiverId[, $offset = 0[, $take = 20]])

getMessages

This is a alias of getConversationsById() method.

Syntax

array messages($conversationId[, $offset = 0[, $take = 20]])

getMessagesAll

This is a alias of getConversationsAllById() method.

Syntax

array messagesAll($conversationId[, $offset = 0[, $take = 20]])

getMessagesByUserId

This is a alias of getConversationsByUserId() method.

Syntax

array messagesByUserId($receiverId[, $offset = 0[, $take = 20]])

getMessagesAllByUserId

This is a alias of getConversationsAllByUserId() method.

Syntax

array messagesAllByUserId($receiverId[, $offset = 0[, $take = 20]])

readMessage

If you want to read a single message then you may use it. This message is return a single message object by message id.

Syntax

array readMessage($messageId)

getReceiverInfo

This method returns all the information about message receiver.

This method is deprecated from version 2.0.0 and it will be removed from version 2.0.2

Syntax

object getReceiverInfo($conversationId)

makeSeen

If you want to set a message as seen you can use this method.

Syntax

boolean makeSeen($messageId)

deleteMessage

When you want to delete a specific message from a conversation, you have to use this method. This method soft delete message for both user-end individually.

Syntax

boolean deleteMessage($messageId)

deleteForever

If you want to hard delete or permanently delete a specific message then you have to use this method.

Syntax

boolean deleteForever($messageId)

deleteConversations

This method is used to permanently delete all conversations.

Syntax

boolean deleteConversations($conversationId)

Realtime Messaging

Talk also support realtime messaging thats called Talk-Live. Talk support pusher and laravel-websocket for realtime messaging. So first you have to configure pusher or laravel-websocket. Go to app/talk.php again and configure.

return [
    'user' => [
        'model' => 'App\User',
        'foreignKey' => null,
        'ownerKey' => null,
    ],

    'broadcast' => [
        'enable' => true,
        'app_name' => 'talk-example',
        'driver' => env('TALK_BROADCAST_DRIVER', 'pusher'), // pusher or laravel-websockets
        'pusher' => [
            'app_id' => env('PUSHER_APP_ID', ''),
            'app_key' => env('PUSHER_APP_KEY', ''),
            'app_secret' => env('PUSHER_APP_SECRET', ''),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER', 'ap2'),
                'encrypted' => env('PUSHER_APP_ENCRYPTION', false),
                'host' => '127.0.0.1',
                'port' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
                'scheme' => 'http',
                'wsHost' => '127.0.0.1',
                'wsPort' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
                'forceTLS' => false,
                'disableStats' => true
            ]
        ],
    ],


    'oembed' => [
        'enabled' => false,
        'url' => '',
        'key' => ''
    ]
];

in this new version broadcast section was added with talk config. Here broadcast is disabled by default. If you want to enable live (realtime) messaging then you have to enable it first. Then add pusher credentials to your .env file and you must add a new line called PUSHER_APP_NAME in the .env file to specify your application pusher name. Thats it. Everytime when you send message then talk will automatically fire two event, one for specific user and second for specific conversation. So you may listen or subscribe one or both as per your wish. Finally you have to subscribe these events by using talk_live() helper function. Go to where you want to subscribe to work with message data follow this code.

<script>
    var msgshow = function(data) {
        // write what you want with this data
        
        console.log(data);
    }
</script>

{!! talk_live(['user'=>["id"=>auth()->user()->id, 'callback'=>['msgshow']]]) !!}

talk_live() supports one parameters as array. The first parameter is for channel name which you want to subscribe. You have not know which channel was broadcast. Talk broadcast two channel by default. One for user and second for conversation. If you want to subscribe channel for currently loggedin user then you have to pass

logedin user id in 'user' key. ['user'=>['id'=>auth()->user()->id, 'callback'=>[]] or you want to subscribe for conversation id you have pass conversation id as 'conversation' key. ['conversation'=>['id'=>$conversationID, 'callback'=>[]]. You may pass both if you want.

You can pass a callback for working with pusher recieved data. For both user and conversation section support callbacks as array. So you can pass multiple callback as array value that was shown in previous example.

You can watch Talk-Live-Demo

Oembed support

Talk also supports embed urls simply use $message->toHtlmString() in you views to render an embed link

Eg. This is a youtube embed link: https://www.youtube.com/watch?v=jNQXAC9IVRw

<div class="message-container">
    <h2>Chat with {{$withUser->name}}</h2>
    @foreach ($messages as $msg)
     <div class="message">
        <h4>{{$msg->sender->name}}</h4>
        <span>{{$msg->humans_time}}</span>
        <p>
            {{$msg->toHtmlString()}}
       </p> 
    </div>
    @endforeach
</div>

Custom embed link

If you want to setup your own implementation of oembed you can configure it in the talk config file. You endpoint should follow the Oembed specifications

    'user' => [
        ...
    ],
    ...
    ],
    'oembed' => [
        'enabled' => true,
        'url' => 'http://your.domain/api/oembed',
        'key' => 'yout-auth-api-key'
    ]

Testing

Talk is backwards compatible with php 5.5. Use docker to run unit tests.

docker-compose run php55 composer install
docker-compose run php55 phpunit
docker-compose run php56 composer install
docker-compose run php56 phpunit
docker-compose run php7 composer install
docker-compose run php7 phpunit
docker-compose run hhvm composer install
docker-compose run hhvm phpunit

Try Demo Project

Talk-Example

Special Thanks To

Shipu Ahamed

Thanks :)

Author: Nahid
Source Code: https://github.com/nahid/talk 
License: MIT license

#laravel #messaging 

Laravel-Talk: A Real-time Users Messaging and Chatting System Laravel

Gcm: Google Cloud Messaging for Application Servers Implemented

gcm

The Android SDK provides a nice convenience library (com.google.android.gcm.server) that greatly simplifies the interaction between Java-based application servers and Google's GCM servers. However, Google has not provided much support for application servers implemented in languages other than Java, specifically those written in the Go programming language. The gcm package helps to fill in this gap, providing a simple interface for sending GCM messages and automatically retrying requests in case of service unavailability.

Getting Started

To install gcm, use go get:

go get github.com/Aorioli/gcm

Import gcm with the following:

import "github.com/Aorioli/gcm"

Sample Usage

Here is a quick sample illustrating how to send a message to the GCM server:

package main

import (
    "fmt"
    "net/http"
    "time"

    "github.com/Aorioli/gcm"
)

func main() {
    // Create the message to be sent.
    data := map[string]interface{}{"score": "5x1", "time": "15:10"}
    regIDs := []string{"4", "8", "15", "16", "23", "42"}
    m := new(gcm.Message)
    m.RegistrationIDs = regIDs
    m.Data = data

    // Create a Sender to send the message.
    sender := gcm.NewSender("sample_api_key", 2, time.Minute)

    // Send the message and receive the response after at most two retries.
    response, err := sender.Send(m)
    if err != nil {
        fmt.Println("Failed to send message:", err)
        return
    }

    /* ... */
}

Contributing

Open up an issue describing the bug, enhancement or whatever so it's open for discussion.

Fork the repo, make your changes on a separate branch from master and create a pull request.

Documentation: http://godoc.org/github.com/Aorioli/gcm

Author: TheOrioli
Source Code: https://github.com/TheOrioli/gcm 
License: MIT license

#go #golang #cloud #messaging 

Gcm: Google Cloud Messaging for Application Servers Implemented
Nigel  Uys

Nigel Uys

1651949880

Jackal: An XMPP Server Written in Go

jackal

An XMPP server written in Go. 

About

jackal is a free, open-source, high performance XMPP server which aims to be known for its stability, simple configuration and low resource consumption.

Features

jackal supports the following features:

  • Customizable
  • Enforced SSL/TLS
  • Stream compression (zlib)
  • Database connectivity for storing offline messages and user settings (PostgreSQL 9.5+, BoltDB)
  • Caching (Redis 6.2+)
  • Clustering capabilities (etcd 3.4+)
  • Expose prometheus metrics
  • Cross-platform (OS X, Linux)

Installing

Getting Started

To start using jackal, install Go 1.18+ and run the following commands:

$ git clone git@github.com:ortuman/jackal.git
$ cd jackal
$ make install installctl

This will fetch the code and install jackal and jackalctl binaries into your $GOPATH/bin path.

By default the application will try to locate service configuration at config.yaml, but alternatively you can specify a custom configuration path either through command line.

$ jackal --config=/your-custom-path/your-config.yaml

or environment variable:

$ env JACKAL_CONFIG_FILE=/your-custom-path/your-config.yaml jackal

PostgreSQL database creation

Create a user and a database for that user:

CREATE ROLE jackal WITH LOGIN PASSWORD 'password';
CREATE DATABASE jackal;
GRANT ALL PRIVILEGES ON DATABASE jackal TO jackal;

Download lastest version of the PostgreSQL schema from jackal Github repository.

wget https://raw.githubusercontent.com/ortuman/jackal/master/sql/postgres.up.psql

Run the postgres script file to create database schema:

psql --user jackal --password -f sql/postgres.up.psql

Configure jackal to use PostgreSQL by editing the configuration file:

storage:
  type: pgsql
  pgsql:
    host: 127.0.0.1:5432
    user: jackal
    password: password
    database: jackal

That's it!

Your database is now ready to connect with jackal.

Creating jackal user

After completing database setup and starting jackal service you'll have to register a new user to be able to login. To do so, you can use jackal command-line tool to create a new user proving name and password.

make installctl && jackalctl user add <user>:<password>

Clustering

The purpose of clustering is to be able to use several servers for fault-tolerance and scalability.

Since jackal is a distributed system, it needs a distributed data store like etcd to share its state across the entire cluster.

To properly run jackal in clustering mode make sure to add a cluster section configuration in each of your service nodes.

Here's an example of how this section should look like:

cluster:
  type: kv
  kv:
    type: etcd
    etcd:
      endpoints:
        - http://<etcd-host1>:<etcd-port1>
        - http://<etcd-host2>:<etcd-port2>
        ...
  port: your-cluster-node-port # default is 14369

Note the defined port value will be used to perform cluster node communication, so make sure is reachable within your internal network.

Server extensibility

The purpose of the extensibility framework is to provide an interface between jackal server and third-party external modules, thus offering the possibility of extending the functionality of the service for particular use cases. Extensibility gRPC API proto files can be found at jackal proto definitions repository.

Run jackal in Docker

The Docker deployment framework supports easy installation and configuration of jackal server.

You need to have Docker installed on your system before you can use a jackal Docker image. See Install Docker for instructions.

Download the jackal Docker image from the official Docker Hub library with this command:

docker pull ortuman/jackal:latest

Start a new jackal Docker container with custom configuration.

docker run --name=jackal \
   --mount type=bind,src=/path-on-host-machine/my-custom-config.yaml,dst=/jackal/config.yaml \
   -d ortuman/jackal:latest

Docker compose

Alternatively, and with the purpose of facilitating service mounting, you can make use of docker-compose as follows:

docker-compose -f dockerfiles/docker-compose.yml up

This command will spin up a jackal server along with its dependencies on a docker network and start listening for incoming connections on port 5222.

Once up and running, don't forget to register one or more users using jackalctl.

Supported Specifications

Join and Contribute

The jackal developer community is vital to improving jackal future releases.

Contributions of all kinds are welcome: reporting issues, updating documentation, fixing bugs, improving unit tests, sharing ideas, and any other tips that may help the jackal community.

Code of Conduct

Help us keep jackal open and inclusive. Please read and follow our Code of Conduct.

Contact

If you have any suggestion or question:

Miguel Ángel Ortuño, JID: ortuman@jackal.im, email: ortuman@pm.me

Author: ortuman
Source Code: https://github.com/ortuman/jackal 
License: Apache-2.0 license

#go #golang #chat #messaging 

Jackal: An XMPP Server Written in Go
Elian  Harber

Elian Harber

1649796720

Bus: Minimalist Message Bus Implementation for internal Communication

Bus is a minimalist event/message bus implementation for internal communication. It is heavily inspired from my event_bus package for Elixir language.

API

The method names and arities/args are stable now. No change should be expected on the package for the version 3.x.x except any bug fixes.

Installation

Via go packages: go get github.com/mustafaturan/bus/v3

Usage

Configure

The package requires a unique id generator to assign ids to events. You can write your own function to generate unique ids or use a package that provides unique id generation functionality.

The bus package respect to software design choice of the packages/projects. It supports both singleton and dependency injection to init a bus instance.

Hint: Check the demo project for the singleton configuration.

Here is a sample initilization using monoton id generator:

import (
    "github.com/mustafaturan/bus/v3"
    "github.com/mustafaturan/monoton/v2"
    "github.com/mustafaturan/monoton/v2/sequencer"
)

func NewBus() *bus.Bus {
    // configure id generator (it doesn't have to be monoton)
    node        := uint64(1)
    initialTime := uint64(1577865600000) // set 2020-01-01 PST as initial time
    m, err := monoton.New(sequencer.NewMillisecond(), node, initialTime)
    if err != nil {
        panic(err)
    }

    // init an id generator
    var idGenerator bus.Next = m.Next

    // create a new bus instance
    b, err := bus.NewBus(idGenerator)
    if err != nil {
        panic(err)
    }

    // maybe register topics in here
    b.RegisterTopics("order.received", "order.fulfilled")

    return b
}

Register Event Topics

To emit events to the topics, topic names need to be registered first:

// register topics
b.RegisterTopics("order.received", "order.fulfilled")

Register Event Handlers

To receive topic events you need to register handlers; A handler basically requires two vals which are a Handle function and topic Matcher regex pattern.

handler := bus.Handler{
    Handle: func(ctx context.Context, e bus.Event) {
        // do something
        // NOTE: Highly recommended to process the event in an async way
    },
    Matcher: ".*", // matches all topics
}
b.RegisterHandler("a unique key for the handler", handler)

Emit Events

// if txID val is blank, bus package generates one using the id generator
ctx := context.Background()
ctx = context.WithValue(ctx, bus.CtxKeyTxID, "some-transaction-id-if-exists")
// with optional source
ctx = context.WithValue(ctx, bus.CtxKeySource, "source-of-the-event")

// event topic name (must be registered before)
topic := "order.received"

// interface{} data for event
order := make(map[string]string)
order["orderID"]     = "123456"
order["orderAmount"] = "112.20"
order["currency"]    = "USD"

// emit the event
err := b.Emit(ctx, topic, order)

if err != nil {
    // report the err
    fmt.Println(err)
}

// emit the event with options
err := b.EmitWithOpts(ctx, topic, order, bus.WithTxID("some-tx-id"))

if err != nil {
    // report the err
    fmt.Println(err)
}

Processing Events

When an event is emitted, the topic handlers receive the event synchronously. It is highly recommended to process events asynchronous. Package leave the decision to the packages/projects to use concurrency abstractions depending on use-cases. Each handlers receive the same event as ref of bus.Event struct:

// Event data structure
type Event struct {
    ID         string      // identifier
    TxID       string      // transaction identifier
    Topic      string      // topic name
    Source     string      // source of the event
    OccurredAt time.Time   // creation time in nanoseconds
    Data       interface{} // actual event data
}

Sample Project

A demo project with three consumers which increments a counter for each event topic, printer consumer which prints all events and lastly calculator consumer which sums amounts.

Benchmarks

Command:

go test -benchtime 10000000x -benchmem -run=^$ -bench=. github.com/mustafaturan/bus/v3

Results:

goos: darwin
goarch: amd64
pkg: github.com/mustafaturan/bus/v3
cpu: Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz
BenchmarkEmit-4                          10000000           180.5 ns/op           8 B/op           0 allocs/op
BenchmarkEmitWithoutTxID-4               10000000           244.6 ns/op          72 B/op           2 allocs/op
BenchmarkEmitWithOpts-4                  10000000           280.8 ns/op         112 B/op           4 allocs/op
BenchmarkEmitWithOptsUnspecified-4       10000000           169.4 ns/op           8 B/op           0 allocs/op
PASS
ok      github.com/mustafaturan/bus/v3    8.884s

Contributing

All contributors should follow Contributing Guidelines before creating pull requests.

Credits

Mustafa Turan

Author: Mustafaturan
Source Code: https://github.com/mustafaturan/bus 
License: Apache-2.0 License

#go #golang #messaging

Bus: Minimalist Message Bus Implementation for internal Communication