PHPackages                             fgendorf/zulip-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. fgendorf/zulip-php

ActiveLibrary[API Development](/categories/api)

fgendorf/zulip-php
==================

Zuilip PHP Client

v0.1(2y ago)010MITPHP

Since Jan 3Pushed 2y agoCompare

[ Source](https://github.com/fgendorf/zulip-php)[ Packagist](https://packagist.org/packages/fgendorf/zulip-php)[ RSS](/packages/fgendorf-zulip-php/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (1)Versions (2)Used By (0)

Zulip PHP
=========

[](#zulip-php)

We have been playing around with Zulip and noticed there was no a **good** PHP client... So we made another one!

THIS VERSION support higher version of puzzle

Installation
------------

[](#installation)

Using composer!

`composer require fgendorf/zulip-php`

Usage (italian only)
--------------------

[](#usage-italian-only)

La libreria è basica, e permette di fare tutte le chiamate (note) alle rEST API di Zulip.

Ci sono 3 possibili metodi d'implementazione:

- [WebHook (o simili, chiamateli come volete.)](#webhook)
- [Client sempre connesso](#client-sempre-connesso)
- [Batch](#batch)

La prima parte, è comune a tutte e 3 le versioni, ed è la **creazione del client**.

```
require 'vendor/autoload.php';

$client = new \ZulipPhp\Client('https://chat.mndrn.cloud/', 'bot-email', 'bot-api-key');
```

A questo punto abbiamo stabilito la connessione col server zulip, e possiamo lanciare tutti i metodi che vogliamo.

WebHook
-------

[](#webhook)

è la modalità più semplice, orientata alla scrittura "estemporanea", come traspare dal nome.. un evento esterno fà partire il messaggio.
in questo caso il .php di riferimento è piuttosto semplice, basta creare un client, formattare il messaggio e inviarlo.

### Messaggio Privato

[](#messaggio-privato)

```
$client->sendMessage([ 'to' => 'email-utente', 'type' => 'private', 'content' => "Messaggio!" ]);
```

### Messaggio ad uno Stream

[](#messaggio-ad-uno-stream)

```
$client->sendMessage([ 'to' => 'Canale', 'subject' => 'nome-dello-stream', 'type' => 'stream', 'content' => "Messaggio!" ]);
```

Client Sempre Connesso
----------------------

[](#client-sempre-connesso)

Per il client sempre connesso, và prima capita un po' di logica.

- Il primo step è capire la logica che fa muovere Zulip.
- Il secondo step, è immaginare che abbiamo bisogno di uno script sempre in esecuzione, che sia in ascolto continuo, per percepire la ricezione di un nuovo messaggio.

---

1. La logica di Zulip:

Zulip ci permette di leggere i messaggi in due modi: **registrando una queue** e **richiedendo i singoli/gruppi di messaggi**.

La **queue** è la modalità più indicata, perché permette di ricevere tutti gli eventi che sono accaduti a partire dalla sua registrazione; non scade e può quindi essere registrata una sola volta e l'informazione poi salvata in archivio. Una volta registrata una queue si può chiedere a Zulip se ci sono stati dei cambiamenti ed eventualmente decidere come trattarli.

La richiesta dei **messaggi** è meno indicata per lo scopo, quindi la tratterò nella versione `Batch`

---

2. Script sempre in esecuzione

per fare un client sempre attivo, abbiamo bisogno di inserire la logica in un `while(true)`. Easy Peasy; Lemon Squeezy! :)

scriviamo la porzione di codice per leggere tutti gli eventi di una queue

```
$client = new \ZulipPhp\…

$queue_id = false;
$last_id = -1; // Di default, -1 ti risponde con tutti gli eventi dalla creazione della queue.
// il last_id non è il vero identificativo dell'evento, è un indice parziale a partire dalla nascita della query (-1, 0, 1, 2, 3, …)

// Registriamo la queue:
$queue_id = $zulip->registerQueue()['queue_id'];

while(true) {

	try {

		$events = $client->getEvents([ 'queue_id' => $queue_id, 'last_event_id' => $last_id, 'dont_block' => 'false']);

		if(count($events) > 0) {
			$last_id += count($events);
			print_r($events);
		} else {
			echo "No new messages. Last event id: ".$msg.".\n";
		}

		sleep(2);

	} catch (Exception $e) {
		echo "Error in fetching Events. Try again in 1 sec.\n";
		sleep(1);
	}

}
```

e, una volta progettato, questo script dovrà essere eseguito da cli (`php script.php`) e vedremo che terrà traccia di tutti gli eventi che accadono.. i messaggi, le reazioni, le sottoscrizioni, heartbeat, ecc.

a questo punto, l'eventuale logica applicativa va inserita nel blocco `if(count($events)>0) {}` dove possiamo processare evento per evento, e guardarne il `$event['type']` per discriminarne le azioni.

in qualunque contesto, ricordiamo, possiamo richiamare i vari `$client->sendMessage()` e tutti gli altri metodi che possono ritornarci utili.

Batch
-----

[](#batch)

Questa modalità è da intendersi percorribile quando il nostro bot effettua un lavoro da "archivista" e non è richiesto che reagisca in tempo reale; in questo caso infatti chiederemo a Zulip di inviarci dei messaggi, a partire da un id (questa volta un vero id).

```
$client = new \ZulipPhp\…

$messages = $client->getMessages([ 'narrow' => json_encode([ [ 'stream', 'NomeStream' ] ]), 'had_error_retry' => 'false', 'anchor' => 0, 'num_before' => 1, 'num_after' => 5]);
// Fare riferimento alla loro documentazione, per l'endpoint GET /messages
```

Esempi di Eventi
----------------

[](#esempi-di-eventi)

### Messaggio Privato

[](#messaggio-privato-1)

```
{
  "type": "private",
  "reactions": [],
  "sender_realm_str": "",
  "timestamp": 1512934642,
  "id": 6516,
  "content": "$ time",
  "display_recipient": [
    {
      "id": 9,
      "full_name": "Federico Quagliotto",
      "email": "f.quagliotto@mandarinoadv.com",
      "is_mirror_dummy": false,
      "short_name": "f.quagliotto"
    },
    {
      "id": 19,
      "full_name": "Khaleesi",
      "email": "khaleesi-bot@chat.mndrn.cloud",
      "is_mirror_dummy": false,
      "short_name": "khaleesi-bot"
    }
  ],
  "sender_short_name": "f.quagliotto",
  "sender_id": 9,
  "sender_full_name": "Federico Quagliotto",
  "client": "website",
  "content_type": "text/x-markdown",
  "sender_email": "f.quagliotto@mandarinoadv.com",
  "avatar_url": "/user_avatars/2/ad4fa2008dc3b96e839ce1ec9d80ad743b5362c2.png?x=x&version=2",
  "recipient_id": 34,
  "is_me_message": false,
  "subject": "",
  "subject_links": []
}
```

### Messaggio publico

[](#messaggio-publico)

```
{
  "sender_short_name": "f.quagliotto",
  "sender_realm_str": "",
  "timestamp": 1512982424,
  "client": "website",
  "display_recipient": "Città dei Bot",
  "sender_full_name": "Federico Quagliotto",
  "sender_id": 9,
  "reactions": [],
  "content": "@**Alessandro Marino** eheh vuoi altri messaggi?",
  "id": 6574,
  "sender_email": "f.quagliotto@mandarinoadv.com",
  "stream_id": 17,
  "type": "stream",
  "recipient_id": 43,
  "is_me_message": false,
  "subject": "hello",
  "subject_links": [],
  "content_type": "text/x-markdown"
}
```

### Reazione

[](#reazione)

```
{
  "emoji_name": "dragon_face",
  "message_id": 6517,
  "id": 9,
  "op": "add",
  "user": {
    "user_id": 9,
    "full_name": "Federico Quagliotto",
    "email": "f.quagliotto@mandarinoadv.com"
  },
  "type": "reaction",
  "emoji_code": "1f432",
  "reaction_type": "unicode_emoji"
}
```

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity31

Early-stage or recently created project

 Bus Factor1

Top contributor holds 60% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

858d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/bc150fb5cfb66459aeec242ca66f74e5a13a60a7d9814ea408dffcd01efb2437?d=identicon)[fgendorf](/maintainers/fgendorf)

---

Top Contributors

[![federicoq](https://avatars.githubusercontent.com/u/1140773?v=4)](https://github.com/federicoq "federicoq (3 commits)")[![andrearufo](https://avatars.githubusercontent.com/u/2174510?v=4)](https://github.com/andrearufo "andrearufo (2 commits)")

---

Tags

phpbotchatzulip

### Embed Badge

![Health badge](/badges/fgendorf-zulip-php/health.svg)

```
[![Health](https://phpackages.com/badges/fgendorf-zulip-php/health.svg)](https://phpackages.com/packages/fgendorf-zulip-php)
```

###  Alternatives

[telegram-bot/api

PHP Wrapper for Telegram Bot API

1.2k2.4M29](/packages/telegram-bot-api)[telegram-bot-php/core

A PHP library that makes using Telegram Bot API much easier.

60293.1k](/packages/telegram-bot-php-core)[klev-o/telegram-bot-api

Simple and convenient object-oriented implementation Telegram bot API with php version ^7.4 support. You'll like it)

457.8k1](/packages/klev-o-telegram-bot-api)[klev-o/crypto-pay-api

Simple and convenient implementation of the Crypto Pay payment system (@CryptoBot)

205.1k](/packages/klev-o-crypto-pay-api)[kuvardin/telegram-bots-api

SDK for Telegram bots API

145.5k](/packages/kuvardin-telegram-bots-api)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
