# سير عمل Discourse

**URL:** https://meta.discourse.org/t/discourse-workflows/407100
**Category:** Plugin
**Tags:** official, included-in-core, workflows
**Created:** [13 يوليو 2026، 1:54ص UTC](https://meta.discourse.org/t/discourse-workflows/407100 "2026-07-13T01:54:16Z")
**Posts on this page:** 18
**Page:** 3

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [28 أغسطس 2026، 8:16م UTC](https://meta.discourse.org/t/discourse-workflows/407100/42 "2026-08-28T20:16:45Z")

</div>

شكرًا، لقد حُلّت المشكلة!

---

<div class="post-metadata">

### Author: ![Ethsim2](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ethsim2/32/522255_2.png) [@Ethsim2](https://meta.discourse.org/u/Ethsim2)
#### Post date: [29 أغسطس 2026، 1:59م UTC](https://meta.discourse.org/t/discourse-workflows/407100/43 "2026-08-29T13:59:44Z")

</div>

@gilles لقد نفّذت الآن المتابعة التي أشرتُ إليها أعلاه:

> <https://github.com/discourse/discourse/pull/43028>
>
> Depends on #42932.
> 
> This is a stacked follow-up to #42932 adding \`Set attendance…\` to the Event workflow action.
> 
> Until #42932 merges, GitHub's diff also contains the prerequisite Event action changes. Once #42932 is merged, this branch will be rebased onto the updated \`main\` so this PR contains only the attendance changes.

يضيف هذا تغييرًا عامًّا لعملية **حدث → تعيين الحضور** ، ويشمل:

- المشارك (attendee)
- حالة الحضور: سيحضر / مهتم / لن يحضر / إزالة الحضور
- معرّف الموضوع (topic ID)
- الفاعل (actor) اختياري

لذلك يمكن بناء حالتك الأصلية على النحو التالي:

**تم إنشاء منشور → إذا كان أول منشور → حدث / تعيين الحضور**

باستخدام كاتب الحدث كمشارك وتعيين حالته إلى **سيحضر**.

قمت باختبار هذا النمط تحديدًا محليًا في واجهة Workflows الرسومية، مع الاستناد إلى #42932، وتأكدت من أن المستخدم يُسجَّل تلقائيًا بحالة “سيحضر” في الحدث.

الحالي PR مسودة فقط لأنه يعتمد على #42932. بمجرد دمج #42932، سأعيد تجميعه (rebase) على فرع `main`، مما سيترك فرقًا خاصًّا بالحضور فقط.

---

<div class="post-metadata">

### Author: ![gilles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gilles/32/549022_2.png) [@gilles](https://meta.discourse.org/u/gilles)
#### Post date: [29 أغسطس 2026، 2:11م UTC](https://meta.discourse.org/t/discourse-workflows/407100/44 "2026-08-29T14:11:47Z")

</div>

@Ethsim2 شكراً لك، أنت رائع 👍 👏

---

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [31 أغسطس 2026، 5:44م UTC](https://meta.discourse.org/t/discourse-workflows/407100/45 "2026-08-31T17:44:36Z")

</div>

هل يوجد طريقة لإعادة محاولة تنفيذ سير عمل (نفس الحدث)، على غرار إعادة إرسال الحمولة في حالة استخدام Webhook؟

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [31 أغسطس 2026، 7:51م UTC](https://meta.discourse.org/t/discourse-workflows/407100/46 "2026-08-31T19:51:57Z")

</div>

لا، نعتذر، نحن لا ندعم هذا حاليًا.

---

<div class="post-metadata">

### Author: ![joo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joo/32/334852_2.png) [@joo](https://meta.discourse.org/u/joo)
#### Post date: [1 سبتمبر 2026، 6:04ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/47 "2026-09-01T06:04:51Z")

</div>

هل يوجد مُشغِّل/حدث يُطلق عند إنشاء وسم جديد؟

عندما يُنشئ مستخدم وسمًا جديدًا، هل هناك طريقة لإضافته تلقائيًا إلى مجموعة وسوم محددة؟ وإذا لم يكن الأمر كذلك، فما هو النهج الموصى به؟

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [1 سبتمبر 2026، 12:23م UTC](https://meta.discourse.org/t/discourse-workflows/407100/48 "2026-09-01T12:23:57Z")

</div>

لا، لا نملك أيًا من هذه الأشياء. هل يمكنك توضيح حالتك الاستخدامية بشكل أكبر من فضلك؟

---

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [1 سبتمبر 2026، 2:45م UTC](https://meta.discourse.org/t/discourse-workflows/407100/49 "2026-09-01T14:45:41Z")

</div>

هل يمكنك القيام بما يلي:

1. الاطلاع على جميع المواضيع الجديدة
2. التحقق من وسمها مقابل الوسوم الموجودة
3. إذا كان الوسم جديدًا، `<insert action>`

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [1 سبتمبر 2026، 3:06م UTC](https://meta.discourse.org/t/discourse-workflows/407100/50 "2026-09-01T15:06:10Z")

</div>

> [@joo](#):
>
> هل يوجد مُشغِّل/حدث يُطلق عند إنشاء وسم جديد؟

يوجد حدث “تغيير وسم الموضوع”. يمكنك بعد ذلك استدعاء واجهة برمجة تطبيقات Discourse للتحقق من عدد المرات التي يُستخدم فيها الوسم. إذا كان مرة واحدة / إذا كان على ذلك الموضوع المحدد، فستعرف أن الوسم جديد.

بديلًا لذلك، وربما يكون أسهل: يمكنك إعداد خطاف ويب (webhook) لحدث “إنشاء وسم” وتوجيهه إلى مُشغِّل خطاف ويب في سير العمل.

---

<div class="post-metadata">

### Author: ![joo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joo/32/334852_2.png) [@joo](https://meta.discourse.org/u/joo)
#### Post date: [2 سبتمبر 2026، 2:57ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/51 "2026-09-02T02:57:48Z")

</div>

حالة الاستخدام: لدي مجموعة وسوم باسم “فنان”. يظهر فنانون جدد باستمرار، لذا تظهر وسوم فنانين جدد باستمرار عندما ينشئها المستخدمون. أريد أن تُضاف هذه الوسوم الجديدة تلقائيًا إلى مجموعة الوسوم “فنان”، بدلاً من أن أضيفها يدويًا. هل هناك طريقة جيدة لتحقيق هذا النتيجة باستخدام سير عمل (Workflows)؟

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [2 سبتمبر 2026، 6:47ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/52 "2026-09-02T06:47:44Z")

</div>

كيف تعرف أنه وسم فنان وليس مجرد وسم عشوائي آخر؟

---

<div class="post-metadata">

### Author: ![joo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/joo/32/334852_2.png) [@joo](https://meta.discourse.org/u/joo)
#### Post date: [2 سبتمبر 2026، 7:35ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/53 "2026-09-02T07:35:38Z")

</div>

هذا بالضبط ما تعالجه خطوة الذكاء الاصطناعي. يقوم وكيل الذكاء الاصطناعي أولاً بتحديد ما إذا كان الوسم الجديد ينتمي إلى أيٍّ من المجموعات المحددة (الموسيقي / العضو / المنطقة / نوع الحدث / نوع الإصدار)؛ وإذا لم ينطبق على أيٍّ منها، يتم تجاهله ولا يُصنَّف ضمن أي مجموعة. وبالتالي، يتم تصفية الوسوم العشوائية، ولا يُضاف تلقائيًا إلى مجموعة الوسوم سوى الوسوم المصنّفة بشكل صحيح.

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [2 سبتمبر 2026، 8:58ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/54 "2026-09-02T08:58:30Z")

</div>

حسنًا، سأضيف بعض المحفّزات (triggers) عند إنشاء وسم (tag)، بالإضافة إلى عقدة (node) لإضافة الوسم إلى مجموعة الوسوم (tag group).

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [2 سبتمبر 2026، 2:41م UTC](https://meta.discourse.org/t/discourse-workflows/407100/55 "2026-09-02T14:41:36Z")

</div>

لقد أضفنا ما يلي إلى سير العمل:

> <https://github.com/discourse/discourse/commit/dd4cc4f4cc5aa73d8eb8efc3c154f4e139ff6052>
>
> Add the \`action:tag\_group\` workflow node for adding and removing tags.

> <https://github.com/discourse/discourse/commit/bd8b99b84bb3079862b3b18ec0249212f57b100d>
>
> Add a \`tag\_created\` workflow trigger with serialized tag payloads.

> <https://github.com/discourse/discourse/commit/0e80e895c354f1b524a1e8a8eda80d1ddf998c7c>
>
> Previously, the events plugin had no way to drive a workflow from an
> RSVP or fro…m an event finishing, and a trigger node contributed by any
> plugin was added to the registry but never subscribed to its
> \`DiscourseEvent\` — so it saved fine, showed up in the palette, and
> silently never fired.
> 
> This change wires the subscription into node registration, which drops
> the hand-rolled \`on(...)\` workarounds in assign, topic voting and chat,
> and adds \`trigger:event\_participation\_changed\` and
> \`trigger:event\_ended\`, both scopable to a single topic.
> 
> \---
> 
> Split into two commits, since the first touches shared infrastructure:
> 
> \- \*\*\`FIX: Subscribe trigger events for workflow nodes added by
> plugins\`\*\* — claiming a node now registers \*and\* subscribes it, and
> contributing plugins are flushed before the host claims its own, so
> ownership lands on them. Because the subscription goes through
> \`Plugin::Instance#on\`, a node stops listening while \*its own\* plugin is
> disabled rather than following the host's setting. This also drops a
> duplicate registration that let \`trigger:chat\_message\_created\` show in
> the palette while chat was disabled.
> \- \*\*\`FEATURE: Workflow triggers for event participation and event end\`\*\*
> — the two triggers. No \`on(...)\` wiring needed in the events plugin
> thanks to the commit above.
> 
> Three behaviour changes in the events plugin, each deliberate:
> 
> \- Withdrawing an RSVP destroyed the record without publishing anything,
> so attendance state built from these triggers could never recover from
> someone leaving. Removal now publishes, and reads as \`status: null\` with
> \`removed: true\`. The livestream chat sync skips removals, so its
> follow/unfollow behaviour is unchanged.
> \- The ended occurrence travels with \`:discourse\_post\_event\_event\_ended\`.
> \`set\_next\_date\` moves the event on immediately afterwards, and
> \`Event#starts\_at\` returns \`nil\` once a bounded series is past
> \`recurrence\_until\`, so the event alone cannot say which occurrence
> ended.
> \- Re-submitting an unchanged RSVP still publishes, so the trigger
> ignores it rather than running a workflow twice for one decision.
> 
> Payload is \`{event, post, topic, stats}\`, plus \`{user, participation}\`
> on the participation trigger — modelled on
> \`WebHook.build\_calendar\_event\_payload\` rather than \`EventSerializer\`,
> which goes admin-truthy under a system guardian. No JS, no core changes,
> no new site settings.
> 
> \### Known gaps, documented rather than fixed
> 
> Bulk invite, \`Event#create\_invitees\` (\`insert\_all!\`),
> \`reset\_invitee\_notifications\` (\`update\_all\`),
> \`enforce\_private\_invitees!\` (\`delete\_all\`) and event/user destroy stay
> silent. \`create\_attendance!\` swallows \`RecordNotUnique\`, so a concurrent
> first RSVP fires nothing. \`event\_ended\` can re-fire if an edit resets
> \`finished\_at\`, and is missed when an event is closed early:
> \`EventDate.pending\` merges \`Event.open\`, so the in-flight occurrence
> leaves the job's scope.
> 
> \`EventListener\` does not rescue \`new\`/\`valid?\`/\`matches?\` and
> \`DiscourseEvent.trigger\` re-raises, so a raising subscriber aborts
> \`MonitorEventDates\` mid-\`find\_each\`. Adding \`continue\_on\_error:\` there
> breaks existing \`track\_events\` assertions, so it is left for its own
> commit.
> 
> \### Testing
> 
> Full \`discourse-workflows\` and \`discourse-events\` backend suites pass
> (4005 examples), plus the workflow specs in chat, assign and topic
> voting. Verified at runtime that all 22 trigger nodes have exactly one
> subscription and there are no duplicate registrations, and that both new
> nodes disappear from the palette and stop dispatching when
> \`discourse\_events\_enabled\` is off.
> 
> Meta:
> https://meta.discourse.org/t/discourse-calendar-events-webhook-triggers-automations-plugin/409623
> 
> \---------
> 
> Co-authored-by: Joffrey JAFFEUX \<j.jaffeux@gmail.com\>

---

<div class="post-metadata">

### Author: ![Lou](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lou/32/544605_2.png) [@Lou](https://meta.discourse.org/u/Lou)
#### Post date: [12 سبتمبر 2026، 7:48ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/56 "2026-09-12T07:48:58Z")

</div>

أريد وسم موضوع إذا تم إنشاؤه بنص معين. هل يوجد طريقة لاستخدام الأحرف الصغيرة (lower case) لـ `{{ $JSON.topic.title }}` بحيث تكون النتيجة صحيحة (true) لكل من “pub run” و"Pub Run" و"pUb rUn"؟

(مقتطف)

```plaintext
{
      "id": "db9e2fa2-0008-4110-9c77-f1060124d7e7",
      "type": "condition:if",
      "typeVersion": "1.0",
      "name": "If",
      "parameters": {
        "combinator": "and",
        "conditions": [
          {
            "id": "29d3ed6c-e984-4d9b-83bf-861bd11b4b0a",
            "operator": {
              "type": "string",
              "operation": "contains",
              "singleValue": false
            },
            "leftValue": "={{ $json.topic.title }}",
            "rightValue": "pub run"
          }
        ]
      },

```

---

<div class="post-metadata">

### Author: ![zogstrip](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zogstrip/32/512781_2.png) [@zogstrip](https://meta.discourse.org/u/zogstrip)
#### Post date: [12 سبتمبر 2026، 8:00ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/57 "2026-09-12T08:00:49Z")

</div>

هل جرّبت `{{ $JSON.topic.title.toLowerCase() }}`؟

---

<div class="post-metadata">

### Author: ![Lou](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lou/32/544605_2.png) [@Lou](https://meta.discourse.org/u/Lou)
#### Post date: [12 سبتمبر 2026، 8:08ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/58 "2026-09-12T08:08:11Z")

</div>

> [@zogstrip](#):
>
> .toLowerCase()

شكراً – لقد نجح!

ما هي لغة القوالب المستخدمة؟

---

<div class="post-metadata">

### Author: ![Ethsim2](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ethsim2/32/522255_2.png) [@Ethsim2](https://meta.discourse.org/u/Ethsim2)
#### Post date: [12 سبتمبر 2026، 8:39ص UTC](https://meta.discourse.org/t/discourse-workflows/407100/59 "2026-09-12T08:39:00Z")

</div>

> [@Lou](#):
>
> ما هي لغة القوالب المستخدمة؟

يبدو أنها **نظام تعبيرات جافاسكربت الخاص بـ Discourse Workflows** ، والذي يتم تقييمه على جانب الخادم داخل بيئة معزولة (sandbox) بدلاً من كونه لغة قوالب منفصلة مثل Liquid أو Handlebars.

لذا، على سبيل المثال:

```plaintext
={{ $json.topic.title.toLowerCase() }}

```

يعمل لأن محتوى `{{ ... }}` يتم تقييمه كجافاسكربت، و`toLowerCase()` هي طريقة السلاسل النصية القياسية في جافاسكربت.

التنفيذ موجود في `plugins/discourse-workflows/lib/discourse_workflows/expression_resolver.rb`؛ حيث يعرّف متغيرات عامة خاصة بالعملية (workflows) مثل `$json`، و`$input`، و`$itemIndex`، و`$trigger`، و`$execution`، و`$()`.

النحو والمفاهيم تشبه إلى حد كبير n8n. يوجد في الواقع مرجح صريح إلى n8n في مكان آخر من مصدر Workflows:

الالتزام (commit) المذكور أدناه أضاف سلوك دمج عقدة المزج (merge-node) ويتضمن اختبارًا موصوفًا بأنه:

> `defaults clash handling to add_suffix (matches n8n position combine)`

> <https://github.com/discourse/discourse/commit/bc639cad0f743ae39f86775a8882fdff1e5af55a>
>
> In discourse workflows you can now choose the combine operation on the
> merge nod…e. This operation will allow you to transform multiple items
> into one, useful for gathering multiple reports for example.

لذا، هناك أدلة على أن أجزاء من Workflows تطابق سلوك n8n عمدًا، على الرغم من أنني لم أجد شيئًا يقول صراحةً أن **لغة التعبيرات نفسها** منسوخة من n8n أو مبنية عليه. لذلك، سأصفها بأنها **تعبيرات جافاسكربت معزولة (sandboxed) يوفرها Discourse Workflows**، مع بعض الاتفاقيات المشابهة لـ n8n.

[Previous page](https://meta.discourse.org/t/discourse-workflows/407100.md?page=2)
