Menerapkan penyedia umpan di Aplikasi Windows C#

Catatan

Beberapa informasi berkaitan dengan produk yang telah dirilis sebelumnya, yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Artikel ini memandu Anda membuat penyedia umpan sederhana yang mendaftarkan URI konten umpan dan mengimplementasikan antarmuka IFeedProvider . Metode antarmuka ini dipanggil oleh Papan Widget untuk meminta parameter string kueri kustom, biasanya untuk mendukung skenario autentikasi. Penyedia umpan dapat mendukung satu umpan atau beberapa umpan.

Untuk menerapkan penyedia umpan menggunakan C++/WinRT, lihat Menerapkan penyedia umpan di aplikasi win32 (C++/WinRT).

Prasyarat

  • Perangkat Anda harus mengaktifkan mode pengembang. Untuk informasi selengkapnya lihat Pengaturan untuk pengembang.
  • Visual Studio 2026 atau yang lebih baru dengan beban kerja pengembangan aplikasi WinUI .

Membuat aplikasi konsol C# baru

Di Visual Studio, buat proyek baru. Dalam dialog Buat proyek baru, atur filter bahasa ke "C#" dan filter platform ke Windows, lalu pilih templat proyek Aplikasi Konsol. Beri nama proyek baru "ExampleFeedProvider". Untuk panduan ini, pastikan bahwa opsi Tempatkan solusi dan proyek di direktori yang sama tidak dipilih. Saat diminta, atur versi .NET target ke 6.0.

Saat proyek dimuat, di Penjelajah Solusi klik kanan nama proyek dan pilih Properti. Pada halaman Umum , gulir ke bawah ke OS Target dan pilih "Windows". Di bawah Versi OS Target, pilih versi 10.022631.2787 atau yang lebih baru.

Perhatikan bahwa panduan ini menggunakan aplikasi konsol yang menampilkan jendela konsol saat umpan diaktifkan untuk memudahkan penelusuran kesalahan. Saat Anda siap untuk menerbitkan aplikasi penyedia umpan, Anda dapat mengonversi aplikasi konsol ke aplikasi Windows dengan mengikuti langkah-langkah di Mengonversi aplikasi konsol Anda ke aplikasi Windows.

Menambahkan referensi ke paket nuGet SDK Aplikasi Windows

Sampel ini menggunakan paket NuGet SDK Aplikasi Windows stabil terbaru. Di Penjelajah Solusi, klik kanan Dependensi dan pilih Kelola paket NuGet.... Di manajer paket NuGet, pilih tab Telusuri dan cari "Microsoft.WindowsAppSDK". Pilih versi stabil terbaru di menu drop-down Versi lalu klik Instal.

Menambahkan kelas FeedProvider untuk menangani operasi umpan

Di Visual Studio, klik ExampleFeedProvider kanan proyek di Penjelajah Solusi dan pilih Add-Class>. Dalam dialog Tambahkan kelas, beri nama kelas "FeedProvider" dan klik Tambahkan. Dalam file FeedProvider.cs yang dihasilkan, perbarui definisi kelas untuk menunjukkan bahwa file tersebut mengimplementasikan antarmuka IFeedProvider .

Buat CLSID yang akan digunakan untuk mengidentifikasi penyedia umpan Anda untuk aktivasi COM. Buat GUID di Visual Studio dengan membuka ALAT-Buat> GUID. Simpan GUID ini dalam file teks untuk digunakan nanti saat mengemas aplikasi penyedia umpan. Ganti GUID dalam anotasi untuk kelas FeedProvider yang ditunjukkan dalam contoh berikut.

// FeedProvider.cs
using Microsoft.Windows.Widgets.Feeds.Providers;
...
[ComVisible(true)]
[ComDefaultInterface(typeof(IFeedProvider))]
[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]
public sealed class FeedProvider : IFeedProvider

Menerapkan metode IFeedProvider

Di beberapa bagian berikutnya, kita akan menerapkan metode antarmuka IFeedProvider .

Catatan

Objek yang diteruskan ke metode panggilan balik antarmuka IFeedProvider hanya dijamin valid dalam panggilan balik. Anda tidak boleh menyimpan referensi ke objek ini karena perilakunya di luar konteks panggilan balik tidak terdefinisi.

ProsesPengaktifanPenyediaUmpan

Metode OnFeedProviderEnabled dipanggil ketika umpan yang terkait dengan penyedia dibuat oleh host Widgets Board. Dalam implementasi metode ini, buat string kueri dengan parameter yang akan diteruskan ke URL yang menyediakan konten umpan, termasuk token autentikasi yang diperlukan. Buat instans CustomQueryParametersUpdateOptions, dengan melewatkan FeedProviderDefinitionId dari argumen acara yang mengidentifikasi umpan yang diaktifkan serta string kueri. Dapatkan FeedManager default dan panggil SetCustomQueryParameters untuk mendaftarkan parameter string kueri ke Papan Widget.

// FeedProvider.cs

public void OnFeedProviderEnabled(FeedProviderEnabledArgs args)
{
    Console.WriteLine($"{args.FeedProviderDefinitionId} feed provider was enabled.");
    var updateOptions = new CustomQueryParametersUpdateOptions(args.FeedProviderDefinitionId, "param1&param2");
    FeedManager.GetDefault().SetCustomQueryParameters(updateOptions);
}

OnFeedProviderDinonaktifkan

OnFeedProviderDisabled dipanggil ketika semua umpan untuk penyedia ini telah dinonaktifkan di Papan Widget. Penyedia umpan tidak diperlukan untuk melakukan tindakan apa pun sebagai respons terhadap panggilan metode ini. Pemanggilan metode dapat digunakan untuk tujuan telemetri atau untuk memperbarui parameter string kueri atau mencabut token autentikasi, jika diperlukan. Jika aplikasi hanya mendukung penyedia umpan tunggal atau jika semua penyedia umpan yang didukung oleh aplikasi telah dinonaktifkan, aplikasi dapat keluar sebagai respons terhadap panggilan balik ini.

// FeedProvider.cs
public void OnFeedProviderDisabled(FeedProviderDisabledArgs args)
{
    Console.WriteLine($"{args.FeedProviderDefinitionId} feed provider was disabled.");
}

Saat Umpan Diaktifkan, Saat Umpan Dinonaktifkan

OnFeedEnabled dan OnFeedDisabled dipanggil oleh Papan Widget saat umpan diaktifkan atau dinonaktifkan. Penyedia umpan tidak diperlukan untuk melakukan tindakan apa pun sebagai respons terhadap panggilan metode ini. Pemanggilan metode dapat digunakan untuk tujuan telemetri atau untuk memperbarui parameter string kueri atau mencabut token autentikasi, jika diperlukan.

// FeedProvider.cs
public void OnFeedEnabled(FeedEnabledArgs args)
{
    Console.WriteLine($"{args.FeedDefinitionId} feed was enabled.");
}

// FeedProvider.cs
public void OnFeedDisabled(FeedDisabledArgs args)
{
    Console.WriteLine($"{args.FeedDefinitionId} feed was disabled.");
}

OnCustomQueryParametersRequested

OnCustomQueryParametersRequested dinaikkan ketika Papan Widget menentukan bahwa parameter kueri kustom yang terkait dengan penyedia umpan perlu di-refresh. Misalnya, metode ini dapat dinaikkan jika operasi untuk mengambil konten umpan dari layanan web jarak jauh gagal. Properti FeedProviderDefinitionId dari CustomQueryParametersRequestedArgs yang diteruskan ke metode ini menentukan umpan tempat param string kueri diminta. Penyedia harus meregenerasi string kueri dan meneruskannya kembali ke Widgets Board dengan memanggil SetCustomQueryParameters.

// FeedProvider.cs

public void OnCustomQueryParametersRequested(CustomQueryParametersRequestedArgs args)
{
    Console.WriteLine($"CustomQueryParamaters were requested for {args.FeedProviderDefinitionId}.");
    var updateOptions = new CustomQueryParametersUpdateOptions(args.FeedProviderDefinitionId, "param1&param2");
    FeedManager.GetDefault().SetCustomQueryParameters(updateOptions);
}

Menerapkan faktori kelas yang akan menginstansiasi FeedProvider sesuai permintaan

Agar host umpan dapat berkomunikasi dengan penyedia umpan kami, kita harus memanggil CoRegisterClassObject. Fungsi ini mengharuskan kita untuk membuat implementasi IClassFactory yang akan membuat objek kelas untuk kelas FeedProvider kita. Kami akan menerapkan class factory kami di kelas bantu mandiri.

Di Visual Studio, klik ExampleFeedProvider kanan proyek di Penjelajah Solusi dan pilih Add-Class>. Dalam dialog Tambahkan kelas, beri nama kelas "FactoryHelper" dan klik Tambahkan.

Ganti konten file FactoryHelper.cs dengan kode berikut. Kode ini mendefinisikan antarmuka IClassFactory dan mengimplementasikan dua metodenya, CreateInstance dan LockServer. Kode ini adalah boilerplate umum untuk menerapkan pabrik kelas dan tidak terkait langsung dengan fungsionalitas penyedia umpan, kecuali bahwa kami menunjukkan bahwa objek kelas yang dibuat mengimplementasikan antarmuka IFeedProvider.

// FactoryHelper.cs
using Microsoft.Windows.Widgets.Feeds.Providers;
using System.Runtime.InteropServices;
using WinRT;

namespace ExampleFeedProvider
{
    namespace Com
    {
        static class Guids
        {
            public const string IClassFactory = "00000001-0000-0000-C000-000000000046";
            public const string IUnknown = "00000000-0000-0000-C000-000000000046";
        }

        [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(Guids.IClassFactory)]
        internal interface IClassFactory
        {
            [PreserveSig]
            int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
            [PreserveSig]
            int LockServer(bool fLock);
        }

        static class ClassObject
        {
            public static void Register(Guid clsid, object pUnk, out uint cookie)
            {
                [DllImport("ole32.dll")]
                static extern int CoRegisterClassObject(
                    [MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
                    [MarshalAs(UnmanagedType.IUnknown)] object pUnk,
                    uint dwClsContext,
                    uint flags,
                    out uint lpdwRegister);

                int result = CoRegisterClassObject(clsid, pUnk, 0x4, 0x1, out cookie);
                if (result != 0)
                {
                    Marshal.ThrowExceptionForHR(result);
                }
            }

            public static int Revoke(uint cookie)
            {
                [DllImport("ole32.dll")]
                static extern int CoRevokeClassObject(uint dwRegister);

                return CoRevokeClassObject(cookie);
            }
        }
    }

    internal class FeedProviderFactory<T> : Com.IClassFactory
            where T : IFeedProvider, new()
    {
        public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
        {
            ppvObject = IntPtr.Zero;

            if (pUnkOuter != IntPtr.Zero)
            {
                Marshal.ThrowExceptionForHR(CLASS_E_NOAGGREGATION);
            }

            if (riid == typeof(T).GUID || riid == Guid.Parse(Com.Guids.IUnknown))
            {
                // Create the instance of the .NET object
                ppvObject = MarshalInspectable<IFeedProvider>.FromManaged(new T());
            }
            else
            {
                // The object that ppvObject points to does not support the
                // interface identified by riid.
                Marshal.ThrowExceptionForHR(E_NOINTERFACE);
            }

            return 0;
        }

        int Com.IClassFactory.LockServer(bool fLock)
        {
            return 0;
        }

        private const int CLASS_E_NOAGGREGATION = -2147221232;
        private const int E_NOINTERFACE = -2147467262;
    }
}

Mendaftarkan objek kelas penyedia umpan dengan OLE

Dalam file Program.cs untuk executable kami, kami akan memanggil CoRegisterClassObject untuk mendaftarkan penyedia umpan kami dengan OLE, sehingga Widgets Board dapat berinteraksi dengannya. Ganti konten Program.cs dengan kode berikut. Ini menggunakan antarmuka FeedProviderFactory yang kami tentukan di langkah sebelumnya untuk mendaftarkan kelas pembantu FeedProvider . Untuk tujuan penelusuran kesalahan, contoh ini memanggil GetEnabledFeedProviders pada instance FeedManager default untuk mendapatkan daftar objek FeedProviderInfo yang mewakili penyedia umpan yang diaktifkan. Ini melintasi penyedia umpan yang diaktifkan, menggunakan properti EnabledFeedDefinitionIds untuk mencantumkan semua ID umpan yang diaktifkan.

// Program.cs

using Microsoft.Windows.Widgets.Feeds.Providers;
using Microsoft.Windows.Widgets.Providers;
using System; 
using System.Runtime.InteropServices;

namespace ExampleFeedProvider
{

    public static class Program
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [MTAThread]
        static void Main(string[] args)
        {
            Console.WriteLine("FeedProvider Starting...");
            if (args.Length > 0 && args[0] == "-RegisterProcessAsComServer")
            {
                WinRT.ComWrappersSupport.InitializeComWrappers();

                uint registrationHandle;
                var factory = new FeedProviderFactory<FeedProvider>();
                Com.ClassObject.Register(typeof(FeedProvider).GUID, factory, out registrationHandle);

                Console.WriteLine("Feed Provider registered.");

                var existingFeedProviders = FeedManager.GetDefault().GetEnabledFeedProviders();
                if (existingFeedProviders != null)
                {
                    Console.WriteLine($"There are {existingFeedProviders.Length} FeedProviders currently outstanding:");
                    foreach (var feedProvider in existingFeedProviders)
                    {
                        Console.WriteLine($"  ProviderId: {feedProvider.FeedProviderDefinitionId}, DefinitionIds: ");
                        var m = WidgetManager.GetDefault().GetWidgetIds();
                        if (feedProvider.EnabledFeedDefinitionIds != null)
                        {
                            foreach (var enabledFeedId in feedProvider.EnabledFeedDefinitionIds)
                            {
                                Console.WriteLine($" {enabledFeedId} ");
                            }
                        }
                    }
                }
                if (GetConsoleWindow() != IntPtr.Zero)
                {
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                }
                else
                {
                    while (true)
                    {
                        // You should fire an event when all the outstanding
                        // FeedProviders have been disabled and exit the app.
                    }
                }
            }
            else
            {
                Console.WriteLine("Not being launched to service Feed Provider... exiting.");
            }
        }
    }
}

Perhatikan bahwa contoh kode ini mengimpor fungsi GetConsoleWindow untuk menentukan apakah aplikasi berjalan sebagai aplikasi konsol, perilaku default untuk panduan ini. Jika fungsi mengembalikan pointer yang valid, kami menulis informasi debug ke konsol. Jika tidak, aplikasi berjalan sebagai aplikasi Windows. Dalam hal ini, kami menunggu peristiwa yang kami tetapkan dalam metode OnFeedProviderDisabled ketika daftar penyedia umpan yang diaktifkan kosong, dan kami keluar dari aplikasi. Untuk informasi tentang mengonversi contoh aplikasi konsol ke aplikasi Windows, lihat Mengonversi aplikasi konsol Anda ke aplikasi Windows.

Mengemas aplikasi penyedia umpan Anda

Dalam rilis saat ini, hanya aplikasi paket yang dapat didaftarkan sebagai penyedia umpan. Langkah-langkah berikut akan membawa Anda melalui proses pengemasan aplikasi Anda dan memperbarui manifes aplikasi untuk mendaftarkan aplikasi Anda dengan OS sebagai penyedia umpan.

Membuat proyek pengemasan MSIX

Di Penjelajah Solusi, klik kanan solusi Anda dan pilih Tambahkan> Proyek Baru.... Dalam dialog Tambahkan proyek baru, pilih templat "Proyek Pengemasan Aplikasi Windows" dan klik Berikutnya. Atur nama proyek ke "ExampleFeedProviderPackage" dan klik Buat. Saat diminta, atur versi target untuk membangun 22621 atau yang lebih baru dan klik OK. Selanjutnya, klik kanan proyek ExampleFeedProviderPackage dan pilih Tambah-> Referensi Proyek. Pilih proyek ExampleFeedProvider dan klik OK.

Menambahkan referensi paket SDK Aplikasi Windows ke proyek pengemasan

Anda perlu menambahkan referensi ke paket NuGet Windows App SDK ke proyek kemasan MSIX. Di Penjelajah Solusi, klik dua kali proyek ExampleFeedProviderPackage untuk membuka file ExampleFeedProviderPackage.wapproj. Tambahkan xml berikut di dalam elemen Project .

<!--ExampleWidgetProviderPackage.wapproj-->
<ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231116003-experimentalpr">
        <IncludeAssets>build</IncludeAssets>
    </PackageReference>  
</ItemGroup>

Catatan

Pastikan Versi yang ditentukan dalam elemen PackageReference cocok dengan versi stabil terbaru yang Anda referensikan di langkah sebelumnya.

Jika versi SDK Aplikasi Windows yang benar sudah diinstal di komputer dan Anda tidak ingin membundel runtime SDK dalam paket Anda, Anda dapat menentukan dependensi paket dalam file Package.appxmanifest untuk proyek ExampleFeedProviderPackage.

<!--Package.appxmanifest-->
...
<Dependencies>
...
    <PackageDependency Name="Microsoft.WindowsAppRuntime.1.5.233430000-experimental1" MinVersion="2000.638.7.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
...
</Dependencies>
...

Memperbarui manifes paket

Di Penjelajah Solusi klik Package.appxmanifest kanan file dan pilih Tampilkan Kode untuk membuka file xml manifes. Selanjutnya, Anda perlu menambahkan beberapa deklarasi namespace untuk ekstensi paket aplikasi yang akan kita gunakan. Tambahkan definisi namespace berikut ke elemen Paket tingkat atas.

<!-- Package.appmanifest -->
<Package
  ...
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"

Di dalam elemen Aplikasi, buat elemen kosong baru bernama Extensions. Pastikan ini muncul setelah tag penutup untuk uap:VisualElements.

<!-- Package.appxmanifest -->
<Application>
...
    <Extensions>

    </Extensions>
</Application>

Ekstensi pertama yang perlu kita tambahkan adalah ekstensi ComServer . Ini mendaftarkan titik masuk dari executable ke dalam OS. Ekstensi ini adalah aplikasi paket yang setara dengan mendaftarkan server COM dengan mengatur kunci registri, dan tidak khusus untuk penyedia widget. Tambahkan elemen com:Extension berikut sebagai turunan dari elemen Extensions. Ubah GUID di atribut Id elemen com:Class ke GUID yang Anda buat di langkah sebelumnya saat menentukan kelas FeedProvider.

<!-- Package.appxmanifest -->
<Extensions>
    <com:Extension Category="windows.comServer">
        <com:ComServer>
            <com:ExeServer Executable="ExampleFeedProvider\ExampleFeedProvider.exe" Arguments="-RegisterProcessAsComServer" DisplayName="C# Feed Provider App">
                <com:Class Id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" DisplayName="FeedProvider" />
            </com:ExeServer>
        </com:ComServer>
    </com:Extension>
</Extensions>


Selanjutnya, tambahkan ekstensi yang mendaftarkan aplikasi sebagai penyedia umpan. Tempelkan elemen uap3:Extension dalam cuplikan kode berikut, sebagai turunan dari elemen Extensions. Pastikan untuk mengganti atribut ClassId elemen COM dengan GUID yang Anda gunakan di langkah sebelumnya.

<!-- Package.appxmanifest -->
<Extensions>
    ...
    <uap3:Extension Category="windows.appExtension">
        <uap3:AppExtension Name="com.microsoft.windows.widgets.feeds" DisplayName="ContosoFeed" Id="com.examplewidgets.examplefeed" PublicFolder="Public">
            <uap3:Properties>
                <FeedProvider Icon="ms-appx:Assets\StoreLogo.png" Description="FeedDescription">
                    <Activation>
                        <!-- Apps exports COM interface which implements IFeedProvider -->
                        <CreateInstance ClassId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />
                    </Activation>
                    <Definitions>
                        <Definition Id="Contoso_Feed"
                            DisplayName="Contoso_Feed Feed"
                            Description="Feed representing Contoso"
                            ContentUri="https://www.contoso.com/"
                            Icon="ms-appx:Images\StoreLogo.png">
                        </Definition>
                        <Definition Id="Fabrikam_Feed"
                            DisplayName="Fabrikam Feed"
                            Description="Feed representing Example"
                            ContentUri="https://www.fabrikam.com/"
                            Icon="ms-appx:Images\StoreLogo.png">
                        </Definition>
                    </Definitions>
                </FeedProvider>
            </uap3:Properties>
        </uap3:AppExtension>
    </uap3:Extension>
</Extensions>

Untuk deskripsi terperinci dan informasi format untuk semua elemen ini, lihat Format XML manifes paket penyedia umpan.

Menguji penyedia umpan Anda

Pastikan Anda telah memilih arsitektur yang cocok dengan komputer pengembangan Anda dari drop-down Platform Solusi, misalnya "x64". Di Penjelajah Solusi, klik kanan solusi Anda dan pilih Bangun Solusi. Setelah ini selesai, klik kanan ExampleWidgetProviderPackage Anda dan pilih Sebarkan. Aplikasi konsol harus diluncurkan saat penerapan dan Anda akan melihat umpan diaktifkan dalam output konsol. Buka Papan Widget dan Anda akan melihat umpan baru di tab di sepanjang bagian atas umpan.

Men-debug penyedia umpan Anda

Setelah Anda menyematkan umpan, Platform Widget akan memulai aplikasi penyedia umpan Anda untuk menerima dan mengirim informasi yang relevan tentang umpan. Untuk men-debug umpan yang sedang berjalan, Anda dapat melampirkan debugger ke aplikasi penyedia umpan yang sedang berjalan atau Anda dapat menyiapkan Visual Studio untuk secara otomatis mulai men-debug proses penyedia umpan setelah dimulai.

Untuk melampirkan ke proses yang sedang berjalan:

  1. Di Visual Studio klik Debug -> Lampirkan ke proses.
  2. Filter proses dan temukan aplikasi penyedia umpan yang Anda inginkan.
  3. Sambungkan debugger.

Untuk melampirkan debugger secara otomatis ke proses ketika prosesnya pertama kali dimulai:

  1. Di Visual Studio klik Debug -> Target Debug Lainnya -> Debug Paket Aplikasi Terinstal.
  2. Filter paket dan temukan paket penyedia umpan yang Anda inginkan.
  3. Pilih dan centang kotak yang bertuliskan Jangan diluncurkan, tetapi debug kode saya saat mulai.
  4. Klik Lampirkan.

Mengonversi aplikasi konsol Anda ke aplikasi Windows

Untuk mengonversi aplikasi konsol yang dibuat dalam panduan ini ke aplikasi Windows, klik kanan proyek ExampleFeedProvider di Penjelajah Solusi dan pilih Properti. Di bawah Aplikasi-Umum> ubah jenis Output dari "Aplikasi Konsol" menjadi "Aplikasi Windows".

Cuplikan layar memperlihatkan properti proyek penyedia umpan C# dengan jenis output yang diatur ke Aplikasi Windows

Menerbitkan aplikasi penyedia umpan Anda

Setelah mengembangkan dan menguji penyedia umpan, Anda dapat menerbitkan aplikasi di Microsoft Store agar pengguna dapat menginstal umpan di perangkat mereka. Untuk panduan langkah demi langkah untuk menerbitkan aplikasi, lihat Menerbitkan aplikasi Anda di Microsoft Store.

Kumpulan Penyimpanan Umpan

Setelah aplikasi diterbitkan di Microsoft Store, Anda dapat meminta aplikasi Anda disertakan dalam Kumpulan Penyimpanan umpan yang membantu pengguna menemukan aplikasi yang menampilkan umpan Windows. Untuk mengirimkan permintaan Anda, lihat Mengirimkan Umpan/Papan Anda agar ditambahkan ke Koleksi Toko.